Forráskód Böngészése

Merge pull request #1353 from alemoreau/fix-undo_quote_doesnt_work

fix: remove attribute if it already exists on the node
Lucas.Xu 2 éve
szülő
commit
6fb677d346

+ 14 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart

@@ -91,6 +91,10 @@ void formatBulletedList(EditorState editorState) {
   });
 }
 
+/// Format the current selection with the given attributes.
+///
+/// If the selected nodes are not text nodes, this method will do nothing.
+/// If the selected text nodes already contain the style in attributes, this method will remove the existing style.
 bool formatTextNodes(EditorState editorState, Attributes attributes) {
   final nodes = editorState.service.selectionService.currentSelectedNodes;
   final textNodes = nodes.whereType<TextNode>().toList();
@@ -108,7 +112,16 @@ bool formatTextNodes(EditorState editorState, Attributes attributes) {
         newAttributes[globalStyleKey] = null;
       }
     }
-    newAttributes.addAll(attributes);
+
+    // if an attribute already exists in the node, it should be removed instead
+    for (final entry in attributes.entries) {
+      if (textNode.attributes.containsKey(entry.key) &&
+          textNode.attributes[entry.key] == entry.value) {
+        // attribute is not added to the node new attributes
+      } else {
+        newAttributes.addEntries([entry]);
+      }
+    }
     transaction
       ..updateNode(
         textNode,

+ 36 - 0
frontend/app_flowy/packages/appflowy_editor/test/service/default_text_operations/format_rich_text_style_test.dart

@@ -0,0 +1,36 @@
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:appflowy_editor/src/render/rich_text/quoted_text.dart';
+import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
+import 'package:flutter_test/flutter_test.dart';
+import '../../infra/test_editor.dart';
+
+void main() async {
+  setUpAll(() {
+    TestWidgetsFlutterBinding.ensureInitialized();
+  });
+
+  group('format_rich_text_style.dart', () {
+    testWidgets('formatTextNodes', (tester) async {
+      const text = 'Welcome to Appflowy 😁';
+      final editor = tester.editor..insertTextNode(text);
+      await editor.startTesting();
+      await editor.updateSelection(
+        Selection.single(path: [0], startOffset: 0, endOffset: text.length),
+      );
+
+      // format the text to Quote
+      formatTextNodes(editor.editorState, {
+        BuiltInAttributeKey.subtype: BuiltInAttributeKey.quote,
+      });
+      await tester.pumpAndSettle(const Duration(seconds: 1));
+      expect(find.byType(QuotedTextNodeWidget), findsOneWidget);
+
+      // format the text to Quote again. The style should be removed.
+      formatTextNodes(editor.editorState, {
+        BuiltInAttributeKey.subtype: BuiltInAttributeKey.quote,
+      });
+      await tester.pumpAndSettle();
+      expect(find.byType(QuotedTextNodeWidget), findsNothing);
+    });
+  });
+}