From 826a5787d04d09a3064c92501defdd001a21f88f Mon Sep 17 00:00:00 2001 From: Jonathan Rufus Samuel <70965472+JRS296@users.noreply.github.com> Date: Thu, 30 Mar 2023 08:48:58 +0530 Subject: [PATCH] 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 --- .../markdown_syntax_to_styled_text.dart | 41 ++++++++++++++++ .../built_in_shortcut_events.dart | 5 ++ .../markdown_syntax_to_styled_text_test.dart | 49 +++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart index 1f798f4114..ae2c354389 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart +++ b/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; }; +//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(); + 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) { final selectionService = editorState.service.selectionService; final selection = selectionService.currentSelection.value; diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart index 3d8fa6839d..222b412e7c 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart @@ -307,6 +307,11 @@ List builtInShortcutEvents = [ character: '_', handler: underscoreToItalicHandler, ), + ShortcutEvent( + key: 'Asterisk to italic', + character: '*', + handler: asteriskToItalicHandler, + ), ShortcutEvent( key: 'Double asterisk to bold', character: '*', diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart b/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart index c7bb897034..28b27a1c29 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart +++ b/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); })); }); + + 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); + }); + }); }