feat: convert = and > to ⇒ (#523)
This commit is contained in:
parent
6d163b8897
commit
51f8f791c8
4 changed files with 151 additions and 11 deletions
|
|
@ -1,13 +1,12 @@
|
||||||
export 'insert_newline.dart';
|
|
||||||
export 'slash_command.dart';
|
|
||||||
export 'markdown_syntax_character_shortcut_events.dart';
|
|
||||||
|
|
||||||
export 'format_single_character/format_single_character.dart';
|
|
||||||
export 'format_single_character/format_italic.dart';
|
|
||||||
export 'format_single_character/format_code.dart';
|
|
||||||
export 'format_single_character/format_strikethrough.dart';
|
|
||||||
|
|
||||||
export 'format_double_characters/format_double_characters.dart';
|
|
||||||
export 'format_double_characters/format_bold.dart';
|
export 'format_double_characters/format_bold.dart';
|
||||||
export 'format_double_characters/format_strikethrough.dart';
|
export 'format_double_characters/format_double_characters.dart';
|
||||||
export 'format_double_characters/format_double_hyphen.dart';
|
export 'format_double_characters/format_double_hyphen.dart';
|
||||||
|
export 'format_double_characters/format_equal_greater_character.dart';
|
||||||
|
export 'format_double_characters/format_strikethrough.dart';
|
||||||
|
export 'format_single_character/format_code.dart';
|
||||||
|
export 'format_single_character/format_italic.dart';
|
||||||
|
export 'format_single_character/format_single_character.dart';
|
||||||
|
export 'format_single_character/format_strikethrough.dart';
|
||||||
|
export 'insert_newline.dart';
|
||||||
|
export 'markdown_syntax_character_shortcut_events.dart';
|
||||||
|
export 'slash_command.dart';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
|
||||||
|
const _greater = '>';
|
||||||
|
const _equals = '=';
|
||||||
|
const _arrow = '⇒';
|
||||||
|
|
||||||
|
/// format '=' + '>' into an ⇒
|
||||||
|
///
|
||||||
|
/// - support
|
||||||
|
/// - desktop
|
||||||
|
/// - mobile
|
||||||
|
/// - web
|
||||||
|
///
|
||||||
|
final CharacterShortcutEvent formatGreaterEqual = CharacterShortcutEvent(
|
||||||
|
key: 'format = + > into ⇒',
|
||||||
|
character: _greater,
|
||||||
|
handler: (editorState) async => handleEqualGreaterReplacement(
|
||||||
|
editorState: editorState,
|
||||||
|
character: _greater,
|
||||||
|
replacement: _arrow,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
@ -32,4 +32,6 @@ final List<CharacterShortcutEvent> markdownSyntaxShortcutEvents = [
|
||||||
|
|
||||||
// format -- into em dash
|
// format -- into em dash
|
||||||
formatDoubleHyphenEmDash,
|
formatDoubleHyphenEmDash,
|
||||||
|
// format = + > into ⇒
|
||||||
|
formatGreaterEqual,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../../../../infra/testable_editor.dart';
|
||||||
|
|
||||||
|
const _greater = '>';
|
||||||
|
const _equals = '=';
|
||||||
|
const _arrow = '⇒';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
group('format_equal_greater.dart', () {
|
||||||
|
testWidgets('= + > to ⇒ in empty paragraph', (tester) async {
|
||||||
|
final editor = tester.editor..addEmptyParagraph();
|
||||||
|
await editor.startTesting();
|
||||||
|
|
||||||
|
await editor.updateSelection(Selection.collapsed(Position(path: [0])));
|
||||||
|
|
||||||
|
await editor.ime.typeText(_equals);
|
||||||
|
await editor.ime.typeText(_greater);
|
||||||
|
|
||||||
|
final delta = editor.nodeAtPath([0])!.delta!;
|
||||||
|
expect(delta.length, 1);
|
||||||
|
expect(delta.toPlainText(), _arrow);
|
||||||
|
|
||||||
|
await editor.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('= + > to ⇒ in non-empty paragraph, undo, redo',
|
||||||
|
(tester) async {
|
||||||
|
const text = 'Hello World';
|
||||||
|
final editor = tester.editor..addParagraph(initialText: text);
|
||||||
|
await editor.startTesting();
|
||||||
|
|
||||||
|
await editor.updateSelection(
|
||||||
|
Selection.collapsed(
|
||||||
|
Position(
|
||||||
|
path: [0],
|
||||||
|
offset: text.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await editor.ime.typeText(_equals);
|
||||||
|
await editor.ime.typeText(_greater);
|
||||||
|
|
||||||
|
Delta delta = editor.nodeAtPath([0])!.delta!;
|
||||||
|
expect(delta.toPlainText(), text + _arrow);
|
||||||
|
|
||||||
|
undoCommand.execute(editor.editorState);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
delta = editor.nodeAtPath([0])!.delta!;
|
||||||
|
expect(delta.toPlainText(), text + _equals);
|
||||||
|
|
||||||
|
undoCommand.execute(editor.editorState);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
delta = editor.nodeAtPath([0])!.delta!;
|
||||||
|
expect(delta.toPlainText(), text);
|
||||||
|
|
||||||
|
await editor.dispose();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue