chore: sync the latest code from AppFlowy (#41)
* chore: sync latest code from appflowy * chore: sync latest tests from appflowy
This commit is contained in:
parent
06240a0b2d
commit
7885d5f1ff
32 changed files with 723 additions and 304 deletions
|
|
@ -1,51 +1,51 @@
|
|||
/// AppFlowyEditor library
|
||||
library appflowy_editor;
|
||||
|
||||
export 'src/commands/command_extension.dart';
|
||||
export 'src/commands/text/text_commands.dart';
|
||||
export 'src/core/document/attributes.dart';
|
||||
export 'src/core/document/document.dart';
|
||||
export 'src/infra/log.dart';
|
||||
export 'src/render/style/editor_style.dart';
|
||||
export 'src/core/document/node.dart';
|
||||
export 'src/core/document/node_iterator.dart';
|
||||
export 'src/core/document/path.dart';
|
||||
export 'src/core/document/text_delta.dart';
|
||||
export 'src/core/legacy/built_in_attribute_keys.dart';
|
||||
export 'src/core/location/position.dart';
|
||||
export 'src/core/location/selection.dart';
|
||||
export 'src/core/document/document.dart';
|
||||
export 'src/core/document/text_delta.dart';
|
||||
export 'src/core/document/attributes.dart';
|
||||
export 'src/core/legacy/built_in_attribute_keys.dart';
|
||||
export 'src/editor_state.dart';
|
||||
export 'src/core/transform/operation.dart';
|
||||
export 'src/core/transform/transaction.dart';
|
||||
export 'src/editor_state.dart';
|
||||
export 'src/extensions/attributes_extension.dart';
|
||||
export 'src/extensions/node_extensions.dart';
|
||||
export 'src/infra/log.dart';
|
||||
export 'src/l10n/l10n.dart';
|
||||
export 'src/plugins/markdown/decoder/delta_markdown_decoder.dart';
|
||||
export 'src/plugins/markdown/document_markdown.dart';
|
||||
export 'src/plugins/markdown/encoder/delta_markdown_encoder.dart';
|
||||
export 'src/plugins/markdown/encoder/document_markdown_encoder.dart';
|
||||
export 'src/plugins/markdown/encoder/parser/image_node_parser.dart';
|
||||
export 'src/plugins/markdown/encoder/parser/node_parser.dart';
|
||||
export 'src/plugins/markdown/encoder/parser/text_node_parser.dart';
|
||||
export 'src/plugins/quill_delta/delta_document_encoder.dart';
|
||||
export 'src/render/action_menu/action_menu.dart';
|
||||
export 'src/render/action_menu/action_menu_item.dart';
|
||||
export 'src/render/rich_text/default_selectable.dart';
|
||||
export 'src/render/rich_text/flowy_rich_text.dart';
|
||||
export 'src/render/selection/selectable.dart';
|
||||
export 'src/render/selection_menu/selection_menu_item_widget.dart';
|
||||
export 'src/render/selection_menu/selection_menu_service.dart';
|
||||
export 'src/render/selection_menu/selection_menu_widget.dart';
|
||||
export 'src/render/style/editor_style.dart';
|
||||
export 'src/render/style/plugin_styles.dart';
|
||||
export 'src/render/toolbar/toolbar_item.dart';
|
||||
export 'src/service/editor_service.dart';
|
||||
export 'src/service/input_service.dart';
|
||||
export 'src/service/keyboard_service.dart';
|
||||
export 'src/service/render_plugin_service.dart';
|
||||
export 'src/service/scroll_service.dart';
|
||||
export 'src/service/selection_service.dart';
|
||||
export 'src/service/service.dart';
|
||||
export 'src/service/selection_service.dart';
|
||||
export 'src/service/scroll_service.dart';
|
||||
export 'src/service/toolbar_service.dart';
|
||||
export 'src/service/keyboard_service.dart';
|
||||
export 'src/service/input_service.dart';
|
||||
export 'src/service/shortcut_event/keybinding.dart';
|
||||
export 'src/service/shortcut_event/shortcut_event.dart';
|
||||
export 'src/service/shortcut_event/shortcut_event_handler.dart';
|
||||
export 'src/service/toolbar_service.dart';
|
||||
export 'src/extensions/attributes_extension.dart';
|
||||
export 'src/render/rich_text/default_selectable.dart';
|
||||
export 'src/render/rich_text/flowy_rich_text.dart';
|
||||
export 'src/render/selection_menu/selection_menu_widget.dart';
|
||||
export 'src/render/selection_menu/selection_menu_item_widget.dart';
|
||||
export 'src/l10n/l10n.dart';
|
||||
export 'src/render/style/plugin_styles.dart';
|
||||
export 'src/plugins/markdown/encoder/delta_markdown_encoder.dart';
|
||||
export 'src/plugins/markdown/encoder/document_markdown_encoder.dart';
|
||||
export 'src/plugins/markdown/encoder/parser/node_parser.dart';
|
||||
export 'src/plugins/markdown/encoder/parser/text_node_parser.dart';
|
||||
export 'src/plugins/markdown/encoder/parser/image_node_parser.dart';
|
||||
export 'src/plugins/markdown/decoder/delta_markdown_decoder.dart';
|
||||
export 'src/plugins/markdown/document_markdown.dart';
|
||||
export 'src/plugins/quill_delta/delta_document_encoder.dart';
|
||||
export 'src/commands/text/text_commands.dart';
|
||||
export 'src/commands/command_extension.dart';
|
||||
export 'src/render/toolbar/toolbar_item.dart';
|
||||
export 'src/extensions/node_extensions.dart';
|
||||
export 'src/render/action_menu/action_menu.dart';
|
||||
export 'src/render/action_menu/action_menu_item.dart';
|
||||
export 'src/core/document/node_iterator.dart';
|
||||
|
|
|
|||
|
|
@ -363,6 +363,19 @@ extension TextTransaction on Transaction {
|
|||
);
|
||||
} else {
|
||||
deleteNode(textNode);
|
||||
if (i == textNodes.length - 1) {
|
||||
final delta = Delta()
|
||||
..insert(texts[0])
|
||||
..addAll(
|
||||
textNodes.last.delta.slice(selection.end.offset),
|
||||
);
|
||||
replaceText(
|
||||
textNode,
|
||||
selection.start.offset,
|
||||
texts[0].length,
|
||||
delta.toPlainText(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
afterSelection = null;
|
||||
|
|
@ -371,6 +384,8 @@ extension TextTransaction on Transaction {
|
|||
|
||||
if (textNodes.length < texts.length) {
|
||||
final length = texts.length;
|
||||
var path = textNodes.first.path;
|
||||
|
||||
for (var i = 0; i < texts.length; i++) {
|
||||
final text = texts[i];
|
||||
if (i == 0) {
|
||||
|
|
@ -380,13 +395,15 @@ extension TextTransaction on Transaction {
|
|||
textNodes.first.toPlainText().length,
|
||||
text,
|
||||
);
|
||||
} else if (i == length - 1) {
|
||||
path = path.next;
|
||||
} else if (i == length - 1 && textNodes.length >= 2) {
|
||||
replaceText(
|
||||
textNodes.last,
|
||||
0,
|
||||
selection.endIndex,
|
||||
text,
|
||||
);
|
||||
path = path.next;
|
||||
} else {
|
||||
if (i < textNodes.length - 1) {
|
||||
replaceText(
|
||||
|
|
@ -395,14 +412,28 @@ extension TextTransaction on Transaction {
|
|||
textNodes[i].toPlainText().length,
|
||||
text,
|
||||
);
|
||||
path = path.next;
|
||||
} else {
|
||||
var path = textNodes.first.path;
|
||||
var j = i - textNodes.length + length - 1;
|
||||
while (j > 0) {
|
||||
path = path.next;
|
||||
j--;
|
||||
if (i == texts.length - 1) {
|
||||
final delta = Delta()
|
||||
..insert(text)
|
||||
..addAll(
|
||||
textNodes.last.delta.slice(selection.end.offset),
|
||||
);
|
||||
insertNode(
|
||||
path,
|
||||
TextNode(
|
||||
delta: delta,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
insertNode(
|
||||
path,
|
||||
TextNode(
|
||||
delta: Delta()..insert(text),
|
||||
),
|
||||
);
|
||||
}
|
||||
insertNode(path, TextNode(delta: Delta()..insert(text)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import 'package:appflowy_editor/src/render/link_menu/link_menu.dart';
|
|||
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
|
||||
import 'package:appflowy_editor/src/extensions/editor_state_extensions.dart';
|
||||
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:flutter/material.dart' hide Overlay, OverlayEntry;
|
||||
|
||||
|
|
@ -127,7 +128,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.bold',
|
||||
type: 2,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.bold,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.bold}\n${Platform.isMacOS ? "⌘ + B" : "CTRL + B"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/bold',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -143,7 +145,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.italic',
|
||||
type: 2,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.italic,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.italic}\n${Platform.isMacOS ? "⌘ + I" : "CTRL + I"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/italic',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -159,7 +162,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.underline',
|
||||
type: 2,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.underline,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.underline}\n${Platform.isMacOS ? "⌘ + U" : "CTRL + U"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/underline',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -175,7 +179,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.strikethrough',
|
||||
type: 2,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.strikethrough,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.strikethrough}\n${Platform.isMacOS ? "⌘ + SHIFT + S" : "CTRL + SHIFT + S"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/strikethrough',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -191,7 +196,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.code',
|
||||
type: 2,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.embedCode,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.embedCode}\n${Platform.isMacOS ? "⌘ + E" : "CTRL + E"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/code',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -241,7 +247,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.link',
|
||||
type: 4,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.link,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.link}\n${Platform.isMacOS ? "⌘ + K" : "CTRL + K"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/link',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -257,7 +264,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||
ToolbarItem(
|
||||
id: 'appflowy.toolbar.highlight',
|
||||
type: 4,
|
||||
tooltipsMessage: AppFlowyEditorLocalizations.current.highlight,
|
||||
tooltipsMessage:
|
||||
"${AppFlowyEditorLocalizations.current.highlight}\n${Platform.isMacOS ? "⌘ + SHIFT + H" : "CTRL + SHIFT + H"}",
|
||||
iconBuilder: (isHighlight) => FlowySvg(
|
||||
name: 'toolbar/highlight',
|
||||
color: isHighlight ? Colors.lightBlue : null,
|
||||
|
|
@ -393,7 +401,6 @@ void showLinkMenu(
|
|||
top: matchRect.bottom + 5.0,
|
||||
left: matchRect.left,
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
child: LinkMenu(
|
||||
linkText: linkText,
|
||||
editorState: editorState,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class ToolbarItemWidget extends StatelessWidget {
|
|||
width: 28,
|
||||
height: 28,
|
||||
child: Tooltip(
|
||||
textAlign: TextAlign.center,
|
||||
preferBelow: false,
|
||||
message: item.tooltipsMessage,
|
||||
child: MouseRegion(
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ void _pasteSingleLine(
|
|||
/// parse url from the line text
|
||||
/// reference: https://stackoverflow.com/questions/59444837/flutter-dart-regex-to-extract-urls-from-a-string
|
||||
Delta _lineContentToDelta(String lineContent) {
|
||||
final exp = RegExp(r'(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-?=%.]+');
|
||||
final exp = RegExp(r'(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\#\w/\-?=%.]+');
|
||||
final Iterable<RegExpMatch> matches = exp.allMatches(lineContent);
|
||||
|
||||
final delta = Delta();
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ ShortcutEventHandler underscoreToItalicHandler = (editorState, event) {
|
|||
return KeyEventResult.handled;
|
||||
};
|
||||
|
||||
ShortcutEventHandler doubleAsteriskToBoldHanlder = (editorState, event) {
|
||||
ShortcutEventHandler doubleAsteriskToBoldHandler = (editorState, event) {
|
||||
final selectionService = editorState.service.selectionService;
|
||||
final selection = selectionService.currentSelection.value;
|
||||
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
||||
|
|
@ -367,7 +367,7 @@ ShortcutEventHandler doubleAsteriskToBoldHanlder = (editorState, event) {
|
|||
};
|
||||
|
||||
//Implement in the same way as doubleAsteriskToBoldHanlder
|
||||
ShortcutEventHandler doubleUnderscoreToBoldHanlder = (editorState, event) {
|
||||
ShortcutEventHandler doubleUnderscoreToBoldHandler = (editorState, event) {
|
||||
final selectionService = editorState.service.selectionService;
|
||||
final selection = selectionService.currentSelection.value;
|
||||
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
||||
|
|
|
|||
|
|
@ -121,15 +121,13 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
|
|||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
Log.keyboard.debug('on keyboard event $event');
|
||||
|
||||
if (event is! RawKeyDownEvent) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
// TODO: use cache to optimize the searching time.
|
||||
for (final shortcutEvent in widget.shortcutEvents) {
|
||||
if (shortcutEvent.keybindings.containsKeyEvent(event)) {
|
||||
if (shortcutEvent.canRespondToRawKeyEvent(event)) {
|
||||
final result = shortcutEvent.handler(widget.editorState, event);
|
||||
if (result == KeyEventResult.handled) {
|
||||
return KeyEventResult.handled;
|
||||
|
|
@ -157,3 +155,10 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
|
|||
return onKey(event);
|
||||
}
|
||||
}
|
||||
|
||||
extension on ShortcutEvent {
|
||||
bool canRespondToRawKeyEvent(RawKeyEvent event) {
|
||||
return ((character?.isNotEmpty ?? false) && character == event.character) ||
|
||||
keybindings.containsKeyEvent(event);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,20 +54,6 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||
linuxCommand: 'shift+alt+arrow left',
|
||||
handler: cursorLeftWordSelect,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Move cursor left one word',
|
||||
command: 'alt+arrow left',
|
||||
windowsCommand: 'alt+arrow left',
|
||||
linuxCommand: 'alt+arrow left',
|
||||
handler: cursorLeftWordMove,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Move cursor right one word',
|
||||
command: 'alt+arrow right',
|
||||
windowsCommand: 'alt+arrow right',
|
||||
linuxCommand: 'alt+arrow right',
|
||||
handler: cursorRightWordMove,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Cursor right word select',
|
||||
command: 'shift+alt+arrow right',
|
||||
|
|
@ -261,7 +247,7 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||
),
|
||||
ShortcutEvent(
|
||||
key: 'selection menu',
|
||||
command: 'slash,shift+slash',
|
||||
character: '/',
|
||||
handler: slashShortcutHandler,
|
||||
),
|
||||
ShortcutEvent(
|
||||
|
|
@ -303,7 +289,7 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||
),
|
||||
ShortcutEvent(
|
||||
key: 'Double tilde to strikethrough',
|
||||
command: 'tilde,shift+tilde',
|
||||
character: '~',
|
||||
handler: doubleTildeToStrikethrough,
|
||||
),
|
||||
ShortcutEvent(
|
||||
|
|
@ -318,19 +304,34 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||
),
|
||||
ShortcutEvent(
|
||||
key: 'Underscore to italic',
|
||||
command: 'shift+underscore',
|
||||
character: '_',
|
||||
handler: underscoreToItalicHandler,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Double asterisk to bold',
|
||||
command: 'shift+digit 8',
|
||||
handler: doubleAsteriskToBoldHanlder,
|
||||
character: '*',
|
||||
handler: doubleAsteriskToBoldHandler,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Double underscore to bold',
|
||||
command: 'shift+underscore',
|
||||
handler: doubleUnderscoreToBoldHanlder,
|
||||
character: '_',
|
||||
handler: doubleUnderscoreToBoldHandler,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Move cursor left one word',
|
||||
command: 'alt+arrow left',
|
||||
windowsCommand: 'alt+arrow left',
|
||||
linuxCommand: 'alt+arrow left',
|
||||
handler: cursorLeftWordMove,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Move cursor right one word',
|
||||
command: 'alt+arrow right',
|
||||
windowsCommand: 'alt+arrow right',
|
||||
linuxCommand: 'alt+arrow right',
|
||||
handler: cursorRightWordMove,
|
||||
),
|
||||
|
||||
// https://github.com/flutter/flutter/issues/104944
|
||||
// Workaround: Using space editing on the web platform often results in errors,
|
||||
// so adding a shortcut event to handle the space input instead of using the
|
||||
|
|
|
|||
|
|
@ -8,12 +8,29 @@ import 'package:flutter/foundation.dart';
|
|||
class ShortcutEvent {
|
||||
ShortcutEvent({
|
||||
required this.key,
|
||||
required this.command,
|
||||
this.character,
|
||||
this.command,
|
||||
required this.handler,
|
||||
String? windowsCommand,
|
||||
String? macOSCommand,
|
||||
String? linuxCommand,
|
||||
}) {
|
||||
// character and command cannot be null at the same time
|
||||
assert(
|
||||
!(character == null &&
|
||||
command == null &&
|
||||
windowsCommand == null &&
|
||||
macOSCommand == null &&
|
||||
linuxCommand == null),
|
||||
'character and command cannot be null at the same time');
|
||||
assert(
|
||||
!(character != null &&
|
||||
(command != null &&
|
||||
windowsCommand != null &&
|
||||
macOSCommand != null &&
|
||||
linuxCommand != null)),
|
||||
'character and command cannot be set at the same time');
|
||||
|
||||
updateCommand(
|
||||
command: command,
|
||||
windowsCommand: windowsCommand,
|
||||
|
|
@ -43,7 +60,9 @@ class ShortcutEvent {
|
|||
///
|
||||
/// Like, 'ctrl+c,cmd+c'
|
||||
///
|
||||
String command;
|
||||
String? command;
|
||||
|
||||
String? character;
|
||||
|
||||
final ShortcutEventHandler handler;
|
||||
|
||||
|
|
@ -80,9 +99,9 @@ class ShortcutEvent {
|
|||
matched = true;
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
if (matched && this.command != null) {
|
||||
_keybindings = this
|
||||
.command
|
||||
.command!
|
||||
.split(',')
|
||||
.map((e) => Keybinding.parse(e))
|
||||
.toList(growable: false);
|
||||
|
|
|
|||
36
test/command/command_extension_test.dart
Normal file
36
test/command/command_extension_test.dart
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../infra/test_editor.dart';
|
||||
|
||||
void main() {
|
||||
group('command_extension.dart', () {
|
||||
testWidgets('insert a new checkbox after an existing checkbox',
|
||||
(tester) async {
|
||||
final editor = tester.editor
|
||||
..insertTextNode(
|
||||
'Welcome',
|
||||
)
|
||||
..insertTextNode(
|
||||
'to',
|
||||
)
|
||||
..insertTextNode(
|
||||
'Appflowy 😁',
|
||||
);
|
||||
await editor.startTesting();
|
||||
final selection = Selection(
|
||||
start: Position(path: [2], offset: 5),
|
||||
end: Position(path: [0], offset: 5),
|
||||
);
|
||||
await editor.updateSelection(selection);
|
||||
final textNodes = editor
|
||||
.editorState.service.selectionService.currentSelectedNodes
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
final texts = editor.editorState.getTextInSelection(
|
||||
textNodes.normalized,
|
||||
selection.normalized,
|
||||
);
|
||||
expect(texts, ['me', 'to', 'Appfl']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -28,5 +28,29 @@ void main() async {
|
|||
}
|
||||
expect(nodes.moveNext(), false);
|
||||
});
|
||||
|
||||
test('toList - when we have at least three level nested nodes (children)',
|
||||
() {
|
||||
final root = Node(type: 'root'),
|
||||
n1 = Node(type: 'node_1'),
|
||||
n2 = Node(type: 'node_2');
|
||||
|
||||
root.insert(n1);
|
||||
root.insert(n2);
|
||||
n1.insert(Node(type: 'node_1_1'));
|
||||
n1.insert(Node(type: 'node_1_2'));
|
||||
n1.childAtIndex(0)?.insert(Node(type: 'node_1_1_1'));
|
||||
n1.childAtIndex(1)?.insert(Node(type: 'node_1_2_1'));
|
||||
|
||||
final nodes = NodeIterator(
|
||||
document: Document(root: root),
|
||||
startNode: root.childAtPath([0])!,
|
||||
endNode: root.childAtPath([1]),
|
||||
).toList();
|
||||
|
||||
expect(nodes[0].id, n1.id);
|
||||
expect(nodes[1].id, n1.childAtIndex(0)!.id);
|
||||
expect(nodes[nodes.length - 1].id, n2.id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,9 +75,5 @@ void main() async {
|
|||
expect(op.invert().invert(), op);
|
||||
expect(op.copyWith(), op);
|
||||
});
|
||||
|
||||
test('Operation.fromJson throws', () {
|
||||
expect(() => Operation.fromJson(), throwsA(isA<UnimplementedError>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
206
test/core/transform/transaction_test.dart
Normal file
206
test/core/transform/transaction_test.dart
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../../infra/test_editor.dart';
|
||||
|
||||
Document createEmptyDocument() {
|
||||
return Document(
|
||||
root: Node(
|
||||
type: 'editor',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void main() async {
|
||||
group('transaction.dart', () {
|
||||
testWidgets('test replaceTexts, textNodes.length == texts.length',
|
||||
(tester) async {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final editor = tester.editor
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789');
|
||||
await editor.startTesting();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 4);
|
||||
|
||||
final selection = Selection(
|
||||
start: Position(path: [0], offset: 4),
|
||||
end: Position(path: [3], offset: 4),
|
||||
);
|
||||
final transaction = editor.editorState.transaction;
|
||||
var textNodes = [0, 1, 2, 3]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
final texts = ['ABC', 'ABC', 'ABC', 'ABC'];
|
||||
transaction.replaceTexts(textNodes, selection, texts);
|
||||
editor.editorState.apply(transaction);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 4);
|
||||
textNodes = [0, 1, 2, 3]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
expect(textNodes[0].toPlainText(), '0123ABC');
|
||||
expect(textNodes[1].toPlainText(), 'ABC');
|
||||
expect(textNodes[2].toPlainText(), 'ABC');
|
||||
expect(textNodes[3].toPlainText(), 'ABC456789');
|
||||
});
|
||||
|
||||
testWidgets('test replaceTexts, textNodes.length > texts.length',
|
||||
(tester) async {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final editor = tester.editor
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789');
|
||||
await editor.startTesting();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 5);
|
||||
|
||||
final selection = Selection(
|
||||
start: Position(path: [0], offset: 4),
|
||||
end: Position(path: [4], offset: 4),
|
||||
);
|
||||
final transaction = editor.editorState.transaction;
|
||||
var textNodes = [0, 1, 2, 3, 4]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
final texts = ['ABC', 'ABC', 'ABC', 'ABC'];
|
||||
transaction.replaceTexts(textNodes, selection, texts);
|
||||
editor.editorState.apply(transaction);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 4);
|
||||
textNodes = [0, 1, 2, 3]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
expect(textNodes[0].toPlainText(), '0123ABC');
|
||||
expect(textNodes[1].toPlainText(), 'ABC');
|
||||
expect(textNodes[2].toPlainText(), 'ABC');
|
||||
expect(textNodes[3].toPlainText(), 'ABC456789');
|
||||
});
|
||||
|
||||
testWidgets('test replaceTexts, textNodes.length >> texts.length',
|
||||
(tester) async {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final editor = tester.editor
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789');
|
||||
await editor.startTesting();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 5);
|
||||
|
||||
final selection = Selection(
|
||||
start: Position(path: [0], offset: 4),
|
||||
end: Position(path: [4], offset: 4),
|
||||
);
|
||||
final transaction = editor.editorState.transaction;
|
||||
var textNodes = [0, 1, 2, 3, 4]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
final texts = ['ABC'];
|
||||
transaction.replaceTexts(textNodes, selection, texts);
|
||||
editor.editorState.apply(transaction);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 1);
|
||||
textNodes = [0]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
expect(textNodes[0].toPlainText(), '0123ABC456789');
|
||||
});
|
||||
|
||||
testWidgets('test replaceTexts, textNodes.length < texts.length',
|
||||
(tester) async {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final editor = tester.editor
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789')
|
||||
..insertTextNode('0123456789');
|
||||
await editor.startTesting();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 3);
|
||||
|
||||
final selection = Selection(
|
||||
start: Position(path: [0], offset: 4),
|
||||
end: Position(path: [2], offset: 4),
|
||||
);
|
||||
final transaction = editor.editorState.transaction;
|
||||
var textNodes = [0, 1, 2]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
final texts = ['ABC', 'ABC', 'ABC', 'ABC'];
|
||||
transaction.replaceTexts(textNodes, selection, texts);
|
||||
editor.editorState.apply(transaction);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 4);
|
||||
textNodes = [0, 1, 2, 3]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
expect(textNodes[0].toPlainText(), '0123ABC');
|
||||
expect(textNodes[1].toPlainText(), 'ABC');
|
||||
expect(textNodes[2].toPlainText(), 'ABC');
|
||||
expect(textNodes[3].toPlainText(), 'ABC456789');
|
||||
});
|
||||
|
||||
testWidgets('test replaceTexts, textNodes.length << texts.length',
|
||||
(tester) async {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final editor = tester.editor..insertTextNode('Welcome to AppFlowy!');
|
||||
await editor.startTesting();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 1);
|
||||
|
||||
// select 'to'
|
||||
final selection = Selection(
|
||||
start: Position(path: [0], offset: 8),
|
||||
end: Position(path: [0], offset: 10),
|
||||
);
|
||||
final transaction = editor.editorState.transaction;
|
||||
var textNodes = [0]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
final texts = ['ABC1', 'ABC2', 'ABC3', 'ABC4', 'ABC5'];
|
||||
transaction.replaceTexts(textNodes, selection, texts);
|
||||
editor.editorState.apply(transaction);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentLength, 5);
|
||||
textNodes = [0, 1, 2, 3, 4]
|
||||
.map((e) => editor.nodeAtPath([e])!)
|
||||
.whereType<TextNode>()
|
||||
.toList(growable: false);
|
||||
expect(textNodes[0].toPlainText(), 'Welcome ABC1');
|
||||
expect(textNodes[1].toPlainText(), 'ABC2');
|
||||
expect(textNodes[2].toPlainText(), 'ABC3');
|
||||
expect(textNodes[3].toPlainText(), 'ABC4');
|
||||
expect(textNodes[4].toPlainText(), 'ABC5 AppFlowy!');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -124,8 +124,9 @@ class EditorWidgetTester {
|
|||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> pressLogicKey(
|
||||
LogicalKeyboardKey key, {
|
||||
Future<void> pressLogicKey({
|
||||
String? character,
|
||||
LogicalKeyboardKey? key,
|
||||
bool isControlPressed = false,
|
||||
bool isShiftPressed = false,
|
||||
bool isAltPressed = false,
|
||||
|
|
@ -134,11 +135,13 @@ class EditorWidgetTester {
|
|||
if (!isControlPressed &&
|
||||
!isShiftPressed &&
|
||||
!isAltPressed &&
|
||||
!isMetaPressed) {
|
||||
!isMetaPressed &&
|
||||
key != null) {
|
||||
await tester.sendKeyDownEvent(key);
|
||||
} else {
|
||||
final testRawKeyEventData = TestRawKeyEventData(
|
||||
logicalKey: key,
|
||||
logicalKey: key ?? LogicalKeyboardKey.nonConvert,
|
||||
character: character,
|
||||
isControlPressed: isControlPressed,
|
||||
isShiftPressed: isShiftPressed,
|
||||
isAltPressed: isAltPressed,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
|
|||
class TestRawKeyEvent extends RawKeyDownEvent {
|
||||
const TestRawKeyEvent({
|
||||
required super.data,
|
||||
required super.character,
|
||||
this.isControlPressed = false,
|
||||
this.isShiftPressed = false,
|
||||
this.isAltPressed = false,
|
||||
|
|
@ -24,7 +25,9 @@ class TestRawKeyEvent extends RawKeyDownEvent {
|
|||
|
||||
class TestRawKeyEventData extends RawKeyEventData {
|
||||
const TestRawKeyEventData({
|
||||
required this.logicalKey,
|
||||
this.logicalKey =
|
||||
LogicalKeyboardKey.nonConvert, // use nonConvert as placeholder.
|
||||
this.character,
|
||||
this.isControlPressed = false,
|
||||
this.isShiftPressed = false,
|
||||
this.isAltPressed = false,
|
||||
|
|
@ -46,6 +49,8 @@ class TestRawKeyEventData extends RawKeyEventData {
|
|||
@override
|
||||
final LogicalKeyboardKey logicalKey;
|
||||
|
||||
final String? character;
|
||||
|
||||
@override
|
||||
PhysicalKeyboardKey get physicalKey => logicalKey.toPhysicalKey;
|
||||
|
||||
|
|
@ -55,8 +60,10 @@ class TestRawKeyEventData extends RawKeyEventData {
|
|||
}
|
||||
|
||||
@override
|
||||
bool isModifierPressed(ModifierKey key,
|
||||
{KeyboardSide side = KeyboardSide.any}) {
|
||||
bool isModifierPressed(
|
||||
ModifierKey key, {
|
||||
KeyboardSide side = KeyboardSide.any,
|
||||
}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +73,7 @@ class TestRawKeyEventData extends RawKeyEventData {
|
|||
RawKeyEvent get toKeyEvent {
|
||||
return TestRawKeyEvent(
|
||||
data: this,
|
||||
character: character,
|
||||
isAltPressed: isAltPressed,
|
||||
isControlPressed: isControlPressed,
|
||||
isMetaPressed: isMetaPressed,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ void main() async {
|
|||
|
||||
// https://github.com/AppFlowy-IO/AppFlowy/issues/1763
|
||||
// // [Bug] Mouse unable to click a certain area #1763
|
||||
testWidgets('insert a new checkbox after an exsiting checkbox',
|
||||
testWidgets('insert a new checkbox after an existing checkbox',
|
||||
(tester) async {
|
||||
// Before
|
||||
//
|
||||
|
|
@ -100,16 +100,16 @@ void main() async {
|
|||
Selection.single(path: [0], startOffset: text.length),
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||
|
||||
expect(
|
||||
editor.documentSelection,
|
||||
Selection.single(path: [2], startOffset: 0),
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.slash);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.slash);
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 1000));
|
||||
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ void main() async {
|
|||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
for (var j = 0; j < i; j++) {
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowDown);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowDown);
|
||||
}
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||
expect(
|
||||
find.byType(SelectionMenuWidget, skipOffstage: false),
|
||||
findsNothing,
|
||||
|
|
@ -51,33 +51,33 @@ void main() async {
|
|||
testWidgets('Search item in selection menu util no results',
|
||||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(3),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(5),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(3),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyX);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyX);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(1),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(1),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNothing,
|
||||
|
|
@ -87,13 +87,13 @@ void main() async {
|
|||
testWidgets('Search item in selection menu and presses esc',
|
||||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(3),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.escape);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.escape);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNothing,
|
||||
|
|
@ -103,20 +103,92 @@ void main() async {
|
|||
testWidgets('Search item in selection menu and presses backspace',
|
||||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNWidgets(3),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(
|
||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||
findsNothing,
|
||||
);
|
||||
});
|
||||
|
||||
group('tab and arrow keys move selection in desired direction', () {
|
||||
testWidgets('left and right keys move selection in desired direction',
|
||||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
|
||||
var initialSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowRight);
|
||||
|
||||
var newSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(newSelection.item), 5);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowLeft);
|
||||
|
||||
var finalSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 0);
|
||||
});
|
||||
|
||||
testWidgets('up and down keys move selection in desired direction',
|
||||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
|
||||
var initialSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowDown);
|
||||
|
||||
var newSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(newSelection.item), 1);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowUp);
|
||||
|
||||
var finalSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 0);
|
||||
});
|
||||
|
||||
testWidgets('arrow keys and tab move same selection', (tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
|
||||
var initialSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowDown);
|
||||
|
||||
var newSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(newSelection.item), 1);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.tab);
|
||||
|
||||
var finalSelection = getSelectedMenuItem(tester);
|
||||
expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 6);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'tab moves selection to next row Item on reaching end of current row',
|
||||
(tester) async {
|
||||
final editor = await _prepare(tester);
|
||||
|
||||
final initialSelection = getSelectedMenuItem(tester);
|
||||
|
||||
expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
|
||||
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.tab);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.tab);
|
||||
|
||||
final finalSelection = getSelectedMenuItem(tester);
|
||||
|
||||
expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +201,7 @@ Future<EditorWidgetTester> _prepare(WidgetTester tester) async {
|
|||
}
|
||||
await editor.startTesting();
|
||||
await editor.updateSelection(Selection.single(path: [1], startOffset: 0));
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.slash);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.slash);
|
||||
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 1000));
|
||||
|
||||
|
|
@ -177,3 +249,11 @@ Future<void> _testDefaultSelectionMenuItems(
|
|||
expect(node?.attributes.check, false);
|
||||
}
|
||||
}
|
||||
|
||||
SelectionMenuItemWidget getSelectedMenuItem(WidgetTester tester) {
|
||||
return tester
|
||||
.state(find.byWidgetPredicate(
|
||||
(widget) => widget is SelectionMenuItemWidget && widget.isSelected,
|
||||
))
|
||||
.widget as SelectionMenuItemWidget;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void main() async {
|
|||
|
||||
final textNode = editor.nodeAtPath([0]) as TextNode;
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowRight);
|
||||
|
||||
if (i == text.length - 1) {
|
||||
// Wrap to next node if the cursor is at the end of the current node.
|
||||
|
|
@ -63,7 +63,7 @@ void main() async {
|
|||
);
|
||||
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
||||
|
|
@ -76,11 +76,11 @@ void main() async {
|
|||
);
|
||||
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ void main() async {
|
|||
);
|
||||
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ void main() async {
|
|||
await editor.updateSelection(selection);
|
||||
for (var i = offset - 1; i >= 0; i--) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -142,7 +142,7 @@ void main() async {
|
|||
}
|
||||
for (var i = text.length; i >= 0; i--) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -154,7 +154,7 @@ void main() async {
|
|||
}
|
||||
for (var i = 1; i <= text.length; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -166,7 +166,7 @@ void main() async {
|
|||
}
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -196,7 +196,7 @@ void main() async {
|
|||
await editor.updateSelection(selection);
|
||||
for (var i = end + 1; i <= text.length; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -208,7 +208,7 @@ void main() async {
|
|||
}
|
||||
for (var i = text.length - 1; i >= 0; i--) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -238,7 +238,7 @@ void main() async {
|
|||
await editor.updateSelection(selection);
|
||||
for (var i = end - 1; i >= 0; i--) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -250,7 +250,7 @@ void main() async {
|
|||
}
|
||||
for (var i = 1; i <= text.length; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
expect(
|
||||
|
|
@ -295,7 +295,7 @@ void main() async {
|
|||
await editor.updateSelection(selection);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowUp,
|
||||
key: LogicalKeyboardKey.arrowUp,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -307,7 +307,7 @@ void main() async {
|
|||
);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
key: LogicalKeyboardKey.arrowDown,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -319,7 +319,7 @@ void main() async {
|
|||
);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowUp,
|
||||
key: LogicalKeyboardKey.arrowUp,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -341,18 +341,18 @@ void main() async {
|
|||
final selection = Selection.single(path: [0], startOffset: 8);
|
||||
await editor.updateSelection(selection);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
key: LogicalKeyboardKey.arrowDown,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
|
|
@ -375,18 +375,18 @@ void main() async {
|
|||
final selection = Selection.single(path: [1], startOffset: 8);
|
||||
await editor.updateSelection(selection);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowUp,
|
||||
key: LogicalKeyboardKey.arrowUp,
|
||||
isShiftPressed: true,
|
||||
);
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
|
|
@ -409,7 +409,7 @@ void main() async {
|
|||
final selection = Selection.single(path: [1], startOffset: 10);
|
||||
await editor.updateSelection(selection);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -421,7 +421,7 @@ void main() async {
|
|||
),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -433,7 +433,7 @@ void main() async {
|
|||
),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -445,7 +445,7 @@ void main() async {
|
|||
),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -469,7 +469,7 @@ void main() async {
|
|||
final selection = Selection.single(path: [0], startOffset: 10);
|
||||
await editor.updateSelection(selection);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -481,7 +481,7 @@ void main() async {
|
|||
),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -493,12 +493,12 @@ void main() async {
|
|||
),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -510,7 +510,7 @@ void main() async {
|
|||
),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isShiftPressed: true,
|
||||
isAltPressed: true,
|
||||
);
|
||||
|
|
@ -535,12 +535,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -556,12 +556,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -578,12 +578,12 @@ void main() async {
|
|||
for (var i = 0; i < words.length; i++) {
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -607,12 +607,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -632,12 +632,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -667,11 +667,11 @@ Future<void> _testPressArrowKeyInNotCollapsedSelection(
|
|||
end: isBackward ? end : start,
|
||||
);
|
||||
await editor.updateSelection(selection);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowLeft);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowLeft);
|
||||
expect(editor.documentSelection?.start, start);
|
||||
|
||||
await editor.updateSelection(selection);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowRight);
|
||||
expect(editor.documentSelection?.end, end);
|
||||
}
|
||||
|
||||
|
|
@ -709,12 +709,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
|||
await editor.updateSelection(selection);
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
key: LogicalKeyboardKey.arrowLeft,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -726,12 +726,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
key: LogicalKeyboardKey.arrowRight,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -743,12 +743,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowUp,
|
||||
key: LogicalKeyboardKey.arrowUp,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowUp,
|
||||
key: LogicalKeyboardKey.arrowUp,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -760,12 +760,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
key: LogicalKeyboardKey.arrowDown,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
key: LogicalKeyboardKey.arrowDown,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ void main() async {
|
|||
// Pressing the backspace key continuously.
|
||||
for (int i = 1; i <= 1; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
);
|
||||
expect(editor.documentLength, 1);
|
||||
expect(editor.documentSelection,
|
||||
|
|
@ -112,7 +112,7 @@ void main() async {
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [0], startOffset: text.length),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||
|
||||
expect(editor.documentLength, 1);
|
||||
expect(editor.documentSelection,
|
||||
|
|
@ -207,7 +207,7 @@ void main() async {
|
|||
),
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.documentLength, 3);
|
||||
expect(find.byType(ImageNodeWidget), findsNothing);
|
||||
expect(
|
||||
|
|
@ -249,20 +249,20 @@ void main() async {
|
|||
final textNode = editor.nodeAtPath([0]) as TextNode;
|
||||
|
||||
await editor.insertText(textNode, '#', 0);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.space);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.space);
|
||||
expect(
|
||||
(editor.nodeAtPath([0]) as TextNode).attributes.heading,
|
||||
BuiltInAttributeKey.h1,
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(
|
||||
textNode.attributes.heading,
|
||||
null,
|
||||
);
|
||||
|
||||
await editor.insertText(textNode, '#', 0);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.space);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.space);
|
||||
expect(
|
||||
(editor.nodeAtPath([0]) as TextNode).attributes.heading,
|
||||
BuiltInAttributeKey.h1,
|
||||
|
|
@ -296,17 +296,17 @@ void main() async {
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [0, 0, 0], startOffset: 0),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.nodeAtPath([0, 0, 0])?.subtype, null);
|
||||
await editor.updateSelection(
|
||||
Selection.single(path: [0, 0, 0], startOffset: 0),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.nodeAtPath([0, 1]) != null, true);
|
||||
await editor.updateSelection(
|
||||
Selection.single(path: [0, 1], startOffset: 0),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.nodeAtPath([1]) != null, true);
|
||||
await editor.updateSelection(
|
||||
Selection.single(path: [1], startOffset: 0),
|
||||
|
|
@ -314,7 +314,7 @@ void main() async {
|
|||
|
||||
// * Welcome to Appflowy 😁
|
||||
// * Welcome to Appflowy 😁Welcome to Appflowy 😁
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(
|
||||
editor.documentSelection,
|
||||
Selection.single(path: [0, 0], startOffset: text.length),
|
||||
|
|
@ -356,7 +356,7 @@ void main() async {
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [0, 1], startOffset: 0),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(
|
||||
editor.nodeAtPath([0, 1])!.subtype != BuiltInAttributeKey.bulletedList,
|
||||
true,
|
||||
|
|
@ -382,7 +382,7 @@ void main() async {
|
|||
// * Welcome to Appflowy 😁Welcome to Appflowy 😁
|
||||
// * Welcome to Appflowy 😁
|
||||
// * Welcome to Appflowy 😁
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(
|
||||
editor.nodeAtPath([0, 0])!.subtype == BuiltInAttributeKey.bulletedList,
|
||||
true,
|
||||
|
|
@ -424,7 +424,7 @@ Future<void> _deleteFirstImage(WidgetTester tester, bool isBackward) async {
|
|||
),
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.documentLength, 2);
|
||||
expect(find.byType(ImageNodeWidget), findsNothing);
|
||||
expect(editor.documentSelection, Selection.collapsed(start));
|
||||
|
|
@ -453,7 +453,7 @@ Future<void> _deleteLastImage(WidgetTester tester, bool isBackward) async {
|
|||
),
|
||||
);
|
||||
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.documentLength, 2);
|
||||
expect(find.byType(ImageNodeWidget), findsNothing);
|
||||
expect(editor.documentSelection, Selection.collapsed(start));
|
||||
|
|
@ -483,12 +483,12 @@ Future<void> _deleteStyledTextByBackspace(
|
|||
Selection.single(path: [2], startOffset: 0),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
);
|
||||
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 0));
|
||||
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
);
|
||||
expect(editor.documentLength, 2);
|
||||
expect(editor.documentSelection,
|
||||
|
|
@ -500,7 +500,7 @@ Future<void> _deleteStyledTextByBackspace(
|
|||
Selection.single(path: [1], startOffset: 0),
|
||||
);
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.backspace,
|
||||
key: LogicalKeyboardKey.backspace,
|
||||
);
|
||||
expect(editor.documentLength, 2);
|
||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
||||
|
|
@ -531,7 +531,7 @@ Future<void> _deleteStyledTextByDelete(
|
|||
);
|
||||
for (var i = 1; i < text.length; i++) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.delete,
|
||||
key: LogicalKeyboardKey.delete,
|
||||
);
|
||||
expect(
|
||||
editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
||||
|
|
@ -541,7 +541,7 @@ Future<void> _deleteStyledTextByDelete(
|
|||
}
|
||||
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.delete,
|
||||
key: LogicalKeyboardKey.delete,
|
||||
);
|
||||
expect(editor.documentLength, 2);
|
||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
||||
|
|
@ -562,7 +562,7 @@ Future<void> _deleteTextByBackspace(
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [1], startOffset: 10),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
|
||||
expect(editor.documentLength, 3);
|
||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 9));
|
||||
|
|
@ -573,7 +573,7 @@ Future<void> _deleteTextByBackspace(
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [2], startOffset: 8, endOffset: 11),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.documentLength, 3);
|
||||
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 8));
|
||||
expect((editor.nodeAtPath([2]) as TextNode).toPlainText(),
|
||||
|
|
@ -587,7 +587,7 @@ Future<void> _deleteTextByBackspace(
|
|||
await editor.updateSelection(Selection(
|
||||
start: isBackwardSelection ? start : end,
|
||||
end: isBackwardSelection ? end : start));
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||
expect(editor.documentLength, 1);
|
||||
expect(
|
||||
editor.documentSelection, Selection.single(path: [0], startOffset: 11));
|
||||
|
|
@ -608,7 +608,7 @@ Future<void> _deleteTextByDelete(
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [1], startOffset: 9),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||
|
||||
expect(editor.documentLength, 3);
|
||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 9));
|
||||
|
|
@ -619,7 +619,7 @@ Future<void> _deleteTextByDelete(
|
|||
await editor.updateSelection(
|
||||
Selection.single(path: [2], startOffset: 8, endOffset: 11),
|
||||
);
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||
expect(editor.documentLength, 3);
|
||||
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 8));
|
||||
expect((editor.nodeAtPath([2]) as TextNode).toPlainText(),
|
||||
|
|
@ -633,7 +633,7 @@ Future<void> _deleteTextByDelete(
|
|||
await editor.updateSelection(Selection(
|
||||
start: isBackwardSelection ? start : end,
|
||||
end: isBackwardSelection ? end : start));
|
||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
||||
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||
expect(editor.documentLength, 1);
|
||||
expect(
|
||||
editor.documentSelection, Selection.single(path: [0], startOffset: 11));
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -65,12 +65,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -145,12 +145,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
@ -223,12 +223,12 @@ void main() async {
|
|||
|
||||
if (Platform.isWindows || Platform.isLinux) {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isControlPressed: true,
|
||||
);
|
||||
} else {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.enter,
|
||||
key: LogicalKeyboardKey.enter,
|
||||
isMetaPressed: true,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue