Przeglądaj źródła

Merge pull request #828 from LucasXu0/main

fix: #827
Nathan.fooo 2 lat temu
rodzic
commit
cc39e03f4c

+ 2 - 0
frontend/app_flowy/packages/flowy_editor/lib/src/document/selection.dart

@@ -46,6 +46,8 @@ class Selection {
       (start.path <= end.path && !pathEquals(start.path, end.path)) ||
       (start.path <= end.path && !pathEquals(start.path, end.path)) ||
       (isSingle && start.offset < end.offset);
       (isSingle && start.offset < end.offset);
 
 
+  Selection get reversed => copyWith(start: end, end: start);
+
   Selection collapse({bool atStart = false}) {
   Selection collapse({bool atStart = false}) {
     if (atStart) {
     if (atStart) {
       return Selection(start: start, end: start);
       return Selection(start: start, end: start);

+ 6 - 3
frontend/app_flowy/packages/flowy_editor/lib/src/extensions/text_node_extensions.dart

@@ -20,14 +20,17 @@ extension TextNodeExtension on TextNode {
 
 
   bool allSatisfyInSelection(String styleKey, Selection selection) {
   bool allSatisfyInSelection(String styleKey, Selection selection) {
     final ops = delta.whereType<TextInsert>();
     final ops = delta.whereType<TextInsert>();
+    final startOffset =
+        selection.isBackward ? selection.start.offset : selection.end.offset;
+    final endOffset =
+        selection.isBackward ? selection.end.offset : selection.start.offset;
     var start = 0;
     var start = 0;
     for (final op in ops) {
     for (final op in ops) {
-      if (start >= selection.end.offset) {
+      if (start >= endOffset) {
         break;
         break;
       }
       }
       final length = op.length;
       final length = op.length;
-      if (start < selection.end.offset &&
-          start + length > selection.start.offset) {
+      if (start < endOffset && start + length > startOffset) {
         if (op.attributes == null ||
         if (op.attributes == null ||
             !op.attributes!.containsKey(styleKey) ||
             !op.attributes!.containsKey(styleKey) ||
             op.attributes![styleKey] == false) {
             op.attributes![styleKey] == false) {

+ 23 - 24
frontend/app_flowy/packages/flowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart

@@ -43,7 +43,7 @@ bool insertTextNodeAfterSelection(
   }
   }
 
 
   final node = nodes.first;
   final node = nodes.first;
-  if (node is TextNode && node.delta.length == 0) {
+  if (node is TextNode && node.delta.isEmpty) {
     formatTextNodes(editorState, attributes);
     formatTextNodes(editorState, attributes);
   } else {
   } else {
     final next = selection.end.path.next;
     final next = selection.end.path.next;
@@ -157,11 +157,18 @@ bool formatRichTextPartialStyle(EditorState editorState, String styleKey) {
 }
 }
 
 
 bool formatRichTextStyle(EditorState editorState, Attributes attributes) {
 bool formatRichTextStyle(EditorState editorState, Attributes attributes) {
-  final selection = editorState.service.selectionService.currentSelection.value;
-  final nodes = editorState.service.selectionService.currentSelectedNodes;
-  final textNodes = nodes.whereType<TextNode>().toList();
+  var selection = editorState.service.selectionService.currentSelection.value;
+  var nodes = editorState.service.selectionService.currentSelectedNodes;
 
 
-  if (selection == null || textNodes.isEmpty) {
+  if (selection == null) {
+    return false;
+  }
+
+  nodes = selection.isBackward ? nodes : nodes.reversed.toList(growable: false);
+  selection = selection.isBackward ? selection : selection.reversed;
+
+  var textNodes = nodes.whereType<TextNode>().toList();
+  if (textNodes.isEmpty) {
     return false;
     return false;
   }
   }
 
 
@@ -180,28 +187,20 @@ bool formatRichTextStyle(EditorState editorState, Attributes attributes) {
   } else {
   } else {
     for (var i = 0; i < textNodes.length; i++) {
     for (var i = 0; i < textNodes.length; i++) {
       final textNode = textNodes[i];
       final textNode = textNodes[i];
+      var index = 0;
+      var length = textNode.toRawString().length;
       if (i == 0 && textNode == nodes.first) {
       if (i == 0 && textNode == nodes.first) {
-        builder.formatText(
-          textNode,
-          selection.start.offset,
-          textNode.toRawString().length - selection.start.offset,
-          attributes,
-        );
+        index = selection.start.offset;
+        length = textNode.toRawString().length - selection.start.offset;
       } else if (i == textNodes.length - 1 && textNode == nodes.last) {
       } else if (i == textNodes.length - 1 && textNode == nodes.last) {
-        builder.formatText(
-          textNode,
-          0,
-          selection.end.offset,
-          attributes,
-        );
-      } else {
-        builder.formatText(
-          textNode,
-          0,
-          textNode.toRawString().length,
-          attributes,
-        );
+        length = selection.end.offset;
       }
       }
+      builder.formatText(
+        textNode,
+        index,
+        length,
+        attributes,
+      );
     }
     }
   }
   }
 
 

+ 1 - 0
frontend/app_flowy/packages/flowy_editor/lib/src/service/selection_service.dart

@@ -487,6 +487,7 @@ class _FlowySelectionState extends State<FlowySelection>
         max = mid - 1;
         max = mid - 1;
       }
       }
     }
     }
+    min = min.clamp(start, end);
     final node = sortedNodes[min];
     final node = sortedNodes[min];
     if (node.children.isNotEmpty && node.children.first.rect.top <= offset.dy) {
     if (node.children.isNotEmpty && node.children.first.rect.top <= offset.dy) {
       final children = node.children.toList(growable: false);
       final children = node.children.toList(growable: false);