diff --git a/frontend/app_flowy/packages/flowy_editor/lib/src/extensions/text_node_extensions.dart b/frontend/app_flowy/packages/flowy_editor/lib/src/extensions/text_node_extensions.dart index 3408546c42..315f529710 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/src/extensions/text_node_extensions.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/src/extensions/text_node_extensions.dart @@ -41,6 +41,30 @@ extension TextNodeExtension on TextNode { } return true; } + + bool allNotSatisfyInSelection(String styleKey, Selection selection) { + final ops = delta.whereType(); + final startOffset = + selection.isBackward ? selection.start.offset : selection.end.offset; + final endOffset = + selection.isBackward ? selection.end.offset : selection.start.offset; + var start = 0; + for (final op in ops) { + if (start >= endOffset) { + break; + } + final length = op.length; + if (start < endOffset && start + length > startOffset) { + if (op.attributes != null && + op.attributes!.containsKey(styleKey) && + op.attributes![styleKey] == true) { + return false; + } + } + start += length; + } + return true; + } } extension TextNodesExtension on List { diff --git a/frontend/app_flowy/packages/flowy_editor/test/service/internal_key_event_handlers/update_text_style_by_command_x_handler_test.dart b/frontend/app_flowy/packages/flowy_editor/test/service/internal_key_event_handlers/update_text_style_by_command_x_handler_test.dart index 39c750a933..e91f089def 100644 --- a/frontend/app_flowy/packages/flowy_editor/test/service/internal_key_event_handlers/update_text_style_by_command_x_handler_test.dart +++ b/frontend/app_flowy/packages/flowy_editor/test/service/internal_key_event_handlers/update_text_style_by_command_x_handler_test.dart @@ -18,7 +18,6 @@ void main() async { LogicalKeyboardKey.keyB, ); }); - testWidgets('Presses Command + I to update text style', (tester) async { await _testUpdateTextStyleByCommandX( tester, @@ -26,7 +25,6 @@ void main() async { LogicalKeyboardKey.keyI, ); }); - testWidgets('Presses Command + U to update text style', (tester) async { await _testUpdateTextStyleByCommandX( tester, @@ -34,7 +32,6 @@ void main() async { LogicalKeyboardKey.keyU, ); }); - testWidgets('Presses Command + S to update text style', (tester) async { await _testUpdateTextStyleByCommandX( tester, @@ -83,5 +80,49 @@ Future _testUpdateTextStyleByCommandX( isMetaPressed: true, ); textNode = editor.nodeAtPath([1]) as TextNode; - expect(textNode.allSatisfyInSelection(matchStyle, selection), false); + expect(textNode.allNotSatisfyInSelection(matchStyle, selection), true); + + selection = Selection( + start: Position(path: [0], offset: 0), + end: Position(path: [2], offset: text.length), + ); + await editor.updateSelection(selection); + await editor.pressLogicKey( + key, + isShiftPressed: key == LogicalKeyboardKey.keyS, + isMetaPressed: true, + ); + var nodes = editor.editorState.service.selectionService.currentSelectedNodes + .whereType(); + expect(nodes.length, 3); + for (final node in nodes) { + expect( + node.allSatisfyInSelection( + matchStyle, + Selection.single( + path: node.path, startOffset: 0, endOffset: text.length), + ), + true, + ); + } + + await editor.updateSelection(selection); + await editor.pressLogicKey( + key, + isShiftPressed: key == LogicalKeyboardKey.keyS, + isMetaPressed: true, + ); + nodes = editor.editorState.service.selectionService.currentSelectedNodes + .whereType(); + expect(nodes.length, 3); + for (final node in nodes) { + expect( + node.allNotSatisfyInSelection( + matchStyle, + Selection.single( + path: node.path, startOffset: 0, endOffset: text.length), + ), + true, + ); + } }