chore: refactor character replacement (#570)

This commit is contained in:
Mathias Mogensen 2023-10-31 15:53:48 +01:00 • committed by GitHub
commit 7ab33c0ee4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 105 deletions

View file

@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/shortcuts/character_shortcut_events/format_double_characters/utils.dart';
const _greater = '>'; const _greater = '>';
const _equals = '='; const _equals = '=';
@ -14,62 +15,10 @@ const _arrow = '⇒';
final CharacterShortcutEvent formatGreaterEqual = CharacterShortcutEvent( final CharacterShortcutEvent formatGreaterEqual = CharacterShortcutEvent(
key: 'format = + > into ⇒', key: 'format = + > into ⇒',
character: _greater, character: _greater,
handler: (editorState) async => handleEqualGreaterReplacement( handler: (editorState) async => handleDoubleCharacterReplacement(
editorState: editorState, editorState: editorState,
character: _greater, character: _greater,
replacement: _arrow, replacement: _arrow,
prefixCharacter: _equals,
), ),
); );
// TODO(Xazin): Combine two character replacement methods into
// a helper function
Future<bool> handleEqualGreaterReplacement({
required EditorState editorState,
required String character,
required String replacement,
}) async {
assert(character.length == 1);
Selection? selection = editorState.selection;
if (selection == null) {
return false;
}
if (!selection.isCollapsed) {
await editorState.deleteSelection(selection);
}
selection = editorState.selection;
if (selection == null) {
return false;
}
final node = editorState.getNodeAtPath(selection.end.path);
final delta = node?.delta;
if (node == null || delta == null || delta.isEmpty) {
return false;
}
if (selection.end.offset > 0) {
final plain = delta.toPlainText();
final previousCharacter = plain[selection.end.offset - 1];
if (previousCharacter != _equals) {
return false;
}
final replace = editorState.transaction
..replaceText(
node,
selection.end.offset - 1,
1,
_arrow,
);
await editorState.apply(replace);
return true;
}
return false;
}

View file

@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/shortcuts/character_shortcut_events/format_double_characters/utils.dart';
const _hyphen = '-'; const _hyphen = '-';
const _emDash = '—'; // This is an em dash — not a single dash - !! const _emDash = '—'; // This is an em dash — not a single dash - !!
@ -19,54 +20,3 @@ final CharacterShortcutEvent formatDoubleHyphenEmDash = CharacterShortcutEvent(
replacement: _emDash, replacement: _emDash,
), ),
); );
Future<bool> handleDoubleCharacterReplacement({
required EditorState editorState,
required String character,
required String replacement,
}) async {
assert(character.length == 1);
Selection? selection = editorState.selection;
if (selection == null) {
return false;
}
if (!selection.isCollapsed) {
await editorState.deleteSelection(selection);
}
selection = editorState.selection;
if (selection == null) {
return false;
}
final node = editorState.getNodeAtPath(selection.end.path);
final delta = node?.delta;
if (node == null || delta == null || delta.isEmpty) {
return false;
}
if (selection.end.offset > 0) {
final plain = delta.toPlainText();
final previousCharacter = plain[selection.end.offset - 1];
if (previousCharacter != _hyphen) {
return false;
}
final replace = editorState.transaction
..replaceText(
node,
selection.end.offset - 1,
1,
_emDash,
);
await editorState.apply(replace);
return true;
}
return false;
}

View file

@ -0,0 +1,57 @@
import 'package:appflowy_editor/appflowy_editor.dart';
/// If [prefixCharacter] is null or empty, [character] is used
Future<bool> handleDoubleCharacterReplacement({
required EditorState editorState,
required String character,
required String replacement,
String? prefixCharacter,
}) async {
assert(character.length == 1);
Selection? selection = editorState.selection;
if (selection == null) {
return false;
}
if (!selection.isCollapsed) {
await editorState.deleteSelection(selection);
}
selection = editorState.selection;
if (selection == null) {
return false;
}
final node = editorState.getNodeAtPath(selection.end.path);
final delta = node?.delta;
if (node == null || delta == null || delta.isEmpty) {
return false;
}
if (selection.end.offset > 0) {
final plain = delta.toPlainText();
final expectedPrevious =
prefixCharacter?.isEmpty ?? true ? character : prefixCharacter;
final previousCharacter = plain[selection.end.offset - 1];
if (previousCharacter != expectedPrevious) {
return false;
}
final replace = editorState.transaction
..replaceText(
node,
selection.end.offset - 1,
1,
replacement,
);
await editorState.apply(replace);
return true;
}
return false;
}