Sfoglia il codice sorgente

fix: Fixed Italics via Single Asterisk (#2115)

* Fixed Italics via Single Asterisk

* Changed shift+asterisk to *

* Mardown Syntax Function vaiable name changes + cleanup

* feat: single asterisk to italic markdown command

---------

Co-authored-by: Lucas.Xu <[email protected]>
Jonathan Rufus Samuel 2 anni fa
parent
commit
826a5787d0

+ 41 - 0
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart

@@ -310,6 +310,47 @@ ShortcutEventHandler underscoreToItalicHandler = (editorState, event) {
   return KeyEventResult.handled;
   return KeyEventResult.handled;
 };
 };
 
 
+//Same functionality implemented via Asterisk - for italics
+ShortcutEventHandler asteriskToItalicHandler = (editorState, event) {
+  final selectionService = editorState.service.selectionService;
+  final selection = selectionService.currentSelection.value;
+  final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
+  if (selection == null || !selection.isSingle || textNodes.length != 1) {
+    return KeyEventResult.ignored;
+  }
+
+  final textNode = textNodes.first;
+  final text = textNode.toPlainText();
+  // Determine if an 'asterisk' already exists in the text node and only once.
+  final firstAsterisk = text.indexOf('*');
+  final lastAsterisk = text.lastIndexOf('*');
+  if (firstAsterisk == -1 ||
+      firstAsterisk != lastAsterisk ||
+      firstAsterisk == selection.start.offset - 1) {
+    return KeyEventResult.ignored;
+  }
+
+  final transaction = editorState.transaction
+    ..deleteText(textNode, firstAsterisk, 1)
+    ..formatText(
+      textNode,
+      firstAsterisk,
+      selection.end.offset - firstAsterisk - 1,
+      {
+        BuiltInAttributeKey.italic: true,
+      },
+    )
+    ..afterSelection = Selection.collapsed(
+      Position(
+        path: textNode.path,
+        offset: selection.end.offset - 1,
+      ),
+    );
+  editorState.apply(transaction);
+
+  return KeyEventResult.handled;
+};
+
 ShortcutEventHandler doubleAsteriskToBoldHandler = (editorState, event) {
 ShortcutEventHandler doubleAsteriskToBoldHandler = (editorState, event) {
   final selectionService = editorState.service.selectionService;
   final selectionService = editorState.service.selectionService;
   final selection = selectionService.currentSelection.value;
   final selection = selectionService.currentSelection.value;

+ 5 - 0
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart

@@ -307,6 +307,11 @@ List<ShortcutEvent> builtInShortcutEvents = [
     character: '_',
     character: '_',
     handler: underscoreToItalicHandler,
     handler: underscoreToItalicHandler,
   ),
   ),
+  ShortcutEvent(
+    key: 'Asterisk to italic',
+    character: '*',
+    handler: asteriskToItalicHandler,
+  ),
   ShortcutEvent(
   ShortcutEvent(
     key: 'Double asterisk to bold',
     key: 'Double asterisk to bold',
     character: '*',
     character: '*',

+ 49 - 0
frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart

@@ -441,4 +441,53 @@ void main() async {
       expect(textNode.toPlainText(), text);
       expect(textNode.toPlainText(), text);
     }));
     }));
   });
   });
+
+  group('Convert single asterisk to italic', () {
+    testWidgets('Test Single Asterisk for Italics', (tester) async {
+      const text = '*Hello World';
+      final editor = tester.editor..insertTextNode(text);
+      await editor.startTesting();
+
+      await editor.updateSelection(
+        Selection.single(path: [0], startOffset: text.length),
+      );
+
+      await editor.pressLogicKey(character: '*');
+
+      final textNode = editor.nodeAtPath([0]) as TextNode;
+      final allItalic = textNode.allSatisfyItalicInSelection(
+        Selection.single(
+          path: [0],
+          startOffset: 0,
+          endOffset: text.length - 1, // delete the first *
+        ),
+      );
+      expect(allItalic, true);
+    });
+
+    testWidgets(
+        'nothing happens if there\'re more than one * precede the current position',
+        (tester) async {
+      const text = '**Hello World';
+      final editor = tester.editor..insertTextNode(text);
+      await editor.startTesting();
+
+      await editor.updateSelection(
+        Selection.single(path: [0], startOffset: text.length),
+      );
+
+      await editor.pressLogicKey(character: '*');
+      await tester.pumpAndSettle();
+
+      final textNode = editor.nodeAtPath([0]) as TextNode;
+      final allItalic = textNode.allSatisfyItalicInSelection(
+        Selection.single(
+          path: [0],
+          startOffset: 0,
+          endOffset: text.length, // insert a new *
+        ),
+      );
+      expect(allItalic, false);
+    });
+  });
 }
 }