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
|
/// AppFlowyEditor library
|
||||||
library appflowy_editor;
|
library appflowy_editor;
|
||||||
|
|
||||||
export 'src/commands/command_extension.dart';
|
export 'src/infra/log.dart';
|
||||||
export 'src/commands/text/text_commands.dart';
|
export 'src/render/style/editor_style.dart';
|
||||||
export 'src/core/document/attributes.dart';
|
|
||||||
export 'src/core/document/document.dart';
|
|
||||||
export 'src/core/document/node.dart';
|
export 'src/core/document/node.dart';
|
||||||
export 'src/core/document/node_iterator.dart';
|
|
||||||
export 'src/core/document/path.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/position.dart';
|
||||||
export 'src/core/location/selection.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/operation.dart';
|
||||||
export 'src/core/transform/transaction.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/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_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/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/render_plugin_service.dart';
|
||||||
export 'src/service/scroll_service.dart';
|
|
||||||
export 'src/service/selection_service.dart';
|
|
||||||
export 'src/service/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/keybinding.dart';
|
||||||
export 'src/service/shortcut_event/shortcut_event.dart';
|
export 'src/service/shortcut_event/shortcut_event.dart';
|
||||||
export 'src/service/shortcut_event/shortcut_event_handler.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 {
|
} else {
|
||||||
deleteNode(textNode);
|
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;
|
afterSelection = null;
|
||||||
|
|
@ -371,6 +384,8 @@ extension TextTransaction on Transaction {
|
||||||
|
|
||||||
if (textNodes.length < texts.length) {
|
if (textNodes.length < texts.length) {
|
||||||
final length = texts.length;
|
final length = texts.length;
|
||||||
|
var path = textNodes.first.path;
|
||||||
|
|
||||||
for (var i = 0; i < texts.length; i++) {
|
for (var i = 0; i < texts.length; i++) {
|
||||||
final text = texts[i];
|
final text = texts[i];
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
|
@ -380,13 +395,15 @@ extension TextTransaction on Transaction {
|
||||||
textNodes.first.toPlainText().length,
|
textNodes.first.toPlainText().length,
|
||||||
text,
|
text,
|
||||||
);
|
);
|
||||||
} else if (i == length - 1) {
|
path = path.next;
|
||||||
|
} else if (i == length - 1 && textNodes.length >= 2) {
|
||||||
replaceText(
|
replaceText(
|
||||||
textNodes.last,
|
textNodes.last,
|
||||||
0,
|
0,
|
||||||
selection.endIndex,
|
selection.endIndex,
|
||||||
text,
|
text,
|
||||||
);
|
);
|
||||||
|
path = path.next;
|
||||||
} else {
|
} else {
|
||||||
if (i < textNodes.length - 1) {
|
if (i < textNodes.length - 1) {
|
||||||
replaceText(
|
replaceText(
|
||||||
|
|
@ -395,14 +412,28 @@ extension TextTransaction on Transaction {
|
||||||
textNodes[i].toPlainText().length,
|
textNodes[i].toPlainText().length,
|
||||||
text,
|
text,
|
||||||
);
|
);
|
||||||
|
path = path.next;
|
||||||
} else {
|
} else {
|
||||||
var path = textNodes.first.path;
|
if (i == texts.length - 1) {
|
||||||
var j = i - textNodes.length + length - 1;
|
final delta = Delta()
|
||||||
while (j > 0) {
|
..insert(text)
|
||||||
path = path.next;
|
..addAll(
|
||||||
j--;
|
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/text_node_extensions.dart';
|
||||||
import 'package:appflowy_editor/src/extensions/editor_state_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 '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;
|
import 'package:flutter/material.dart' hide Overlay, OverlayEntry;
|
||||||
|
|
||||||
|
|
@ -127,7 +128,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.bold',
|
id: 'appflowy.toolbar.bold',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.bold,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.bold}\n${Platform.isMacOS ? "⌘ + B" : "CTRL + B"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/bold',
|
name: 'toolbar/bold',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -143,7 +145,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.italic',
|
id: 'appflowy.toolbar.italic',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.italic,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.italic}\n${Platform.isMacOS ? "⌘ + I" : "CTRL + I"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/italic',
|
name: 'toolbar/italic',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -159,7 +162,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.underline',
|
id: 'appflowy.toolbar.underline',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.underline,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.underline}\n${Platform.isMacOS ? "⌘ + U" : "CTRL + U"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/underline',
|
name: 'toolbar/underline',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -175,7 +179,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.strikethrough',
|
id: 'appflowy.toolbar.strikethrough',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.strikethrough,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.strikethrough}\n${Platform.isMacOS ? "⌘ + SHIFT + S" : "CTRL + SHIFT + S"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/strikethrough',
|
name: 'toolbar/strikethrough',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -191,7 +196,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.code',
|
id: 'appflowy.toolbar.code',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.embedCode,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.embedCode}\n${Platform.isMacOS ? "⌘ + E" : "CTRL + E"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/code',
|
name: 'toolbar/code',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -241,7 +247,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.link',
|
id: 'appflowy.toolbar.link',
|
||||||
type: 4,
|
type: 4,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.link,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.link}\n${Platform.isMacOS ? "⌘ + K" : "CTRL + K"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/link',
|
name: 'toolbar/link',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -257,7 +264,8 @@ List<ToolbarItem> defaultToolbarItems = [
|
||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.highlight',
|
id: 'appflowy.toolbar.highlight',
|
||||||
type: 4,
|
type: 4,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.highlight,
|
tooltipsMessage:
|
||||||
|
"${AppFlowyEditorLocalizations.current.highlight}\n${Platform.isMacOS ? "⌘ + SHIFT + H" : "CTRL + SHIFT + H"}",
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/highlight',
|
name: 'toolbar/highlight',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
|
@ -393,7 +401,6 @@ void showLinkMenu(
|
||||||
top: matchRect.bottom + 5.0,
|
top: matchRect.bottom + 5.0,
|
||||||
left: matchRect.left,
|
left: matchRect.left,
|
||||||
child: Material(
|
child: Material(
|
||||||
borderRadius: BorderRadius.circular(6.0),
|
|
||||||
child: LinkMenu(
|
child: LinkMenu(
|
||||||
linkText: linkText,
|
linkText: linkText,
|
||||||
editorState: editorState,
|
editorState: editorState,
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ class ToolbarItemWidget extends StatelessWidget {
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
|
textAlign: TextAlign.center,
|
||||||
preferBelow: false,
|
preferBelow: false,
|
||||||
message: item.tooltipsMessage,
|
message: item.tooltipsMessage,
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ void _pasteSingleLine(
|
||||||
/// parse url from the line text
|
/// parse url from the line text
|
||||||
/// reference: https://stackoverflow.com/questions/59444837/flutter-dart-regex-to-extract-urls-from-a-string
|
/// reference: https://stackoverflow.com/questions/59444837/flutter-dart-regex-to-extract-urls-from-a-string
|
||||||
Delta _lineContentToDelta(String lineContent) {
|
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 Iterable<RegExpMatch> matches = exp.allMatches(lineContent);
|
||||||
|
|
||||||
final delta = Delta();
|
final delta = Delta();
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ ShortcutEventHandler underscoreToItalicHandler = (editorState, event) {
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
};
|
};
|
||||||
|
|
||||||
ShortcutEventHandler doubleAsteriskToBoldHanlder = (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;
|
||||||
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
||||||
|
|
@ -367,7 +367,7 @@ ShortcutEventHandler doubleAsteriskToBoldHanlder = (editorState, event) {
|
||||||
};
|
};
|
||||||
|
|
||||||
//Implement in the same way as doubleAsteriskToBoldHanlder
|
//Implement in the same way as doubleAsteriskToBoldHanlder
|
||||||
ShortcutEventHandler doubleUnderscoreToBoldHanlder = (editorState, event) {
|
ShortcutEventHandler doubleUnderscoreToBoldHandler = (editorState, event) {
|
||||||
final selectionService = editorState.service.selectionService;
|
final selectionService = editorState.service.selectionService;
|
||||||
final selection = selectionService.currentSelection.value;
|
final selection = selectionService.currentSelection.value;
|
||||||
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
||||||
|
|
|
||||||
|
|
@ -121,15 +121,13 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
|
||||||
return KeyEventResult.ignored;
|
return KeyEventResult.ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.keyboard.debug('on keyboard event $event');
|
|
||||||
|
|
||||||
if (event is! RawKeyDownEvent) {
|
if (event is! RawKeyDownEvent) {
|
||||||
return KeyEventResult.ignored;
|
return KeyEventResult.ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use cache to optimize the searching time.
|
// TODO: use cache to optimize the searching time.
|
||||||
for (final shortcutEvent in widget.shortcutEvents) {
|
for (final shortcutEvent in widget.shortcutEvents) {
|
||||||
if (shortcutEvent.keybindings.containsKeyEvent(event)) {
|
if (shortcutEvent.canRespondToRawKeyEvent(event)) {
|
||||||
final result = shortcutEvent.handler(widget.editorState, event);
|
final result = shortcutEvent.handler(widget.editorState, event);
|
||||||
if (result == KeyEventResult.handled) {
|
if (result == KeyEventResult.handled) {
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
|
|
@ -157,3 +155,10 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
|
||||||
return onKey(event);
|
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',
|
linuxCommand: 'shift+alt+arrow left',
|
||||||
handler: cursorLeftWordSelect,
|
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(
|
ShortcutEvent(
|
||||||
key: 'Cursor right word select',
|
key: 'Cursor right word select',
|
||||||
command: 'shift+alt+arrow right',
|
command: 'shift+alt+arrow right',
|
||||||
|
|
@ -261,7 +247,7 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'selection menu',
|
key: 'selection menu',
|
||||||
command: 'slash,shift+slash',
|
character: '/',
|
||||||
handler: slashShortcutHandler,
|
handler: slashShortcutHandler,
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
|
|
@ -303,7 +289,7 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'Double tilde to strikethrough',
|
key: 'Double tilde to strikethrough',
|
||||||
command: 'tilde,shift+tilde',
|
character: '~',
|
||||||
handler: doubleTildeToStrikethrough,
|
handler: doubleTildeToStrikethrough,
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
|
|
@ -318,19 +304,34 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'Underscore to italic',
|
key: 'Underscore to italic',
|
||||||
command: 'shift+underscore',
|
character: '_',
|
||||||
handler: underscoreToItalicHandler,
|
handler: underscoreToItalicHandler,
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'Double asterisk to bold',
|
key: 'Double asterisk to bold',
|
||||||
command: 'shift+digit 8',
|
character: '*',
|
||||||
handler: doubleAsteriskToBoldHanlder,
|
handler: doubleAsteriskToBoldHandler,
|
||||||
),
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'Double underscore to bold',
|
key: 'Double underscore to bold',
|
||||||
command: 'shift+underscore',
|
character: '_',
|
||||||
handler: doubleUnderscoreToBoldHanlder,
|
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
|
// https://github.com/flutter/flutter/issues/104944
|
||||||
// Workaround: Using space editing on the web platform often results in errors,
|
// 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
|
// 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 {
|
class ShortcutEvent {
|
||||||
ShortcutEvent({
|
ShortcutEvent({
|
||||||
required this.key,
|
required this.key,
|
||||||
required this.command,
|
this.character,
|
||||||
|
this.command,
|
||||||
required this.handler,
|
required this.handler,
|
||||||
String? windowsCommand,
|
String? windowsCommand,
|
||||||
String? macOSCommand,
|
String? macOSCommand,
|
||||||
String? linuxCommand,
|
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(
|
updateCommand(
|
||||||
command: command,
|
command: command,
|
||||||
windowsCommand: windowsCommand,
|
windowsCommand: windowsCommand,
|
||||||
|
|
@ -43,7 +60,9 @@ class ShortcutEvent {
|
||||||
///
|
///
|
||||||
/// Like, 'ctrl+c,cmd+c'
|
/// Like, 'ctrl+c,cmd+c'
|
||||||
///
|
///
|
||||||
String command;
|
String? command;
|
||||||
|
|
||||||
|
String? character;
|
||||||
|
|
||||||
final ShortcutEventHandler handler;
|
final ShortcutEventHandler handler;
|
||||||
|
|
||||||
|
|
@ -80,9 +99,9 @@ class ShortcutEvent {
|
||||||
matched = true;
|
matched = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched) {
|
if (matched && this.command != null) {
|
||||||
_keybindings = this
|
_keybindings = this
|
||||||
.command
|
.command!
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((e) => Keybinding.parse(e))
|
.map((e) => Keybinding.parse(e))
|
||||||
.toList(growable: false);
|
.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);
|
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.invert().invert(), op);
|
||||||
expect(op.copyWith(), 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();
|
await tester.pumpAndSettle();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> pressLogicKey(
|
Future<void> pressLogicKey({
|
||||||
LogicalKeyboardKey key, {
|
String? character,
|
||||||
|
LogicalKeyboardKey? key,
|
||||||
bool isControlPressed = false,
|
bool isControlPressed = false,
|
||||||
bool isShiftPressed = false,
|
bool isShiftPressed = false,
|
||||||
bool isAltPressed = false,
|
bool isAltPressed = false,
|
||||||
|
|
@ -134,11 +135,13 @@ class EditorWidgetTester {
|
||||||
if (!isControlPressed &&
|
if (!isControlPressed &&
|
||||||
!isShiftPressed &&
|
!isShiftPressed &&
|
||||||
!isAltPressed &&
|
!isAltPressed &&
|
||||||
!isMetaPressed) {
|
!isMetaPressed &&
|
||||||
|
key != null) {
|
||||||
await tester.sendKeyDownEvent(key);
|
await tester.sendKeyDownEvent(key);
|
||||||
} else {
|
} else {
|
||||||
final testRawKeyEventData = TestRawKeyEventData(
|
final testRawKeyEventData = TestRawKeyEventData(
|
||||||
logicalKey: key,
|
logicalKey: key ?? LogicalKeyboardKey.nonConvert,
|
||||||
|
character: character,
|
||||||
isControlPressed: isControlPressed,
|
isControlPressed: isControlPressed,
|
||||||
isShiftPressed: isShiftPressed,
|
isShiftPressed: isShiftPressed,
|
||||||
isAltPressed: isAltPressed,
|
isAltPressed: isAltPressed,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
|
||||||
class TestRawKeyEvent extends RawKeyDownEvent {
|
class TestRawKeyEvent extends RawKeyDownEvent {
|
||||||
const TestRawKeyEvent({
|
const TestRawKeyEvent({
|
||||||
required super.data,
|
required super.data,
|
||||||
|
required super.character,
|
||||||
this.isControlPressed = false,
|
this.isControlPressed = false,
|
||||||
this.isShiftPressed = false,
|
this.isShiftPressed = false,
|
||||||
this.isAltPressed = false,
|
this.isAltPressed = false,
|
||||||
|
|
@ -24,7 +25,9 @@ class TestRawKeyEvent extends RawKeyDownEvent {
|
||||||
|
|
||||||
class TestRawKeyEventData extends RawKeyEventData {
|
class TestRawKeyEventData extends RawKeyEventData {
|
||||||
const TestRawKeyEventData({
|
const TestRawKeyEventData({
|
||||||
required this.logicalKey,
|
this.logicalKey =
|
||||||
|
LogicalKeyboardKey.nonConvert, // use nonConvert as placeholder.
|
||||||
|
this.character,
|
||||||
this.isControlPressed = false,
|
this.isControlPressed = false,
|
||||||
this.isShiftPressed = false,
|
this.isShiftPressed = false,
|
||||||
this.isAltPressed = false,
|
this.isAltPressed = false,
|
||||||
|
|
@ -46,6 +49,8 @@ class TestRawKeyEventData extends RawKeyEventData {
|
||||||
@override
|
@override
|
||||||
final LogicalKeyboardKey logicalKey;
|
final LogicalKeyboardKey logicalKey;
|
||||||
|
|
||||||
|
final String? character;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
PhysicalKeyboardKey get physicalKey => logicalKey.toPhysicalKey;
|
PhysicalKeyboardKey get physicalKey => logicalKey.toPhysicalKey;
|
||||||
|
|
||||||
|
|
@ -55,8 +60,10 @@ class TestRawKeyEventData extends RawKeyEventData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isModifierPressed(ModifierKey key,
|
bool isModifierPressed(
|
||||||
{KeyboardSide side = KeyboardSide.any}) {
|
ModifierKey key, {
|
||||||
|
KeyboardSide side = KeyboardSide.any,
|
||||||
|
}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +73,7 @@ class TestRawKeyEventData extends RawKeyEventData {
|
||||||
RawKeyEvent get toKeyEvent {
|
RawKeyEvent get toKeyEvent {
|
||||||
return TestRawKeyEvent(
|
return TestRawKeyEvent(
|
||||||
data: this,
|
data: this,
|
||||||
|
character: character,
|
||||||
isAltPressed: isAltPressed,
|
isAltPressed: isAltPressed,
|
||||||
isControlPressed: isControlPressed,
|
isControlPressed: isControlPressed,
|
||||||
isMetaPressed: isMetaPressed,
|
isMetaPressed: isMetaPressed,
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ void main() async {
|
||||||
|
|
||||||
// https://github.com/AppFlowy-IO/AppFlowy/issues/1763
|
// https://github.com/AppFlowy-IO/AppFlowy/issues/1763
|
||||||
// // [Bug] Mouse unable to click a certain area #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 {
|
(tester) async {
|
||||||
// Before
|
// Before
|
||||||
//
|
//
|
||||||
|
|
@ -100,16 +100,16 @@ void main() async {
|
||||||
Selection.single(path: [0], startOffset: text.length),
|
Selection.single(path: [0], startOffset: text.length),
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.enter);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.enter);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
editor.documentSelection,
|
editor.documentSelection,
|
||||||
Selection.single(path: [2], startOffset: 0),
|
Selection.single(path: [2], startOffset: 0),
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.slash);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.slash);
|
||||||
await tester.pumpAndSettle(const Duration(milliseconds: 1000));
|
await tester.pumpAndSettle(const Duration(milliseconds: 1000));
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ void main() async {
|
||||||
(tester) async {
|
(tester) async {
|
||||||
final editor = await _prepare(tester);
|
final editor = await _prepare(tester);
|
||||||
for (var j = 0; j < i; j++) {
|
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(
|
expect(
|
||||||
find.byType(SelectionMenuWidget, skipOffstage: false),
|
find.byType(SelectionMenuWidget, skipOffstage: false),
|
||||||
findsNothing,
|
findsNothing,
|
||||||
|
|
@ -51,33 +51,33 @@ void main() async {
|
||||||
testWidgets('Search item in selection menu util no results',
|
testWidgets('Search item in selection menu util no results',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
final editor = await _prepare(tester);
|
final editor = await _prepare(tester);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(3),
|
findsNWidgets(3),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(5),
|
findsNWidgets(5),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(3),
|
findsNWidgets(3),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyX);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyX);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(1),
|
findsNWidgets(1),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(1),
|
findsNWidgets(1),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNothing,
|
findsNothing,
|
||||||
|
|
@ -87,13 +87,13 @@ void main() async {
|
||||||
testWidgets('Search item in selection menu and presses esc',
|
testWidgets('Search item in selection menu and presses esc',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
final editor = await _prepare(tester);
|
final editor = await _prepare(tester);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(3),
|
findsNWidgets(3),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.escape);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.escape);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNothing,
|
findsNothing,
|
||||||
|
|
@ -103,20 +103,92 @@ void main() async {
|
||||||
testWidgets('Search item in selection menu and presses backspace',
|
testWidgets('Search item in selection menu and presses backspace',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
final editor = await _prepare(tester);
|
final editor = await _prepare(tester);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyT);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyT);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.keyE);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.keyE);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNWidgets(3),
|
findsNWidgets(3),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(
|
expect(
|
||||||
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
find.byType(SelectionMenuItemWidget, skipOffstage: false),
|
||||||
findsNothing,
|
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.startTesting();
|
||||||
await editor.updateSelection(Selection.single(path: [1], startOffset: 0));
|
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));
|
await tester.pumpAndSettle(const Duration(milliseconds: 1000));
|
||||||
|
|
||||||
|
|
@ -177,3 +249,11 @@ Future<void> _testDefaultSelectionMenuItems(
|
||||||
expect(node?.attributes.check, false);
|
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;
|
final textNode = editor.nodeAtPath([0]) as TextNode;
|
||||||
for (var i = 0; i < text.length; i++) {
|
for (var i = 0; i < text.length; i++) {
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowRight);
|
||||||
|
|
||||||
if (i == text.length - 1) {
|
if (i == text.length - 1) {
|
||||||
// Wrap to next node if the cursor is at the end of the current node.
|
// 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(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -76,11 +76,11 @@ void main() async {
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ void main() async {
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -130,7 +130,7 @@ void main() async {
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
for (var i = offset - 1; i >= 0; i--) {
|
for (var i = offset - 1; i >= 0; i--) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -142,7 +142,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
for (var i = text.length; i >= 0; i--) {
|
for (var i = text.length; i >= 0; i--) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -154,7 +154,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
for (var i = 1; i <= text.length; i++) {
|
for (var i = 1; i <= text.length; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -166,7 +166,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
for (var i = 0; i < text.length; i++) {
|
for (var i = 0; i < text.length; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -196,7 +196,7 @@ void main() async {
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
for (var i = end + 1; i <= text.length; i++) {
|
for (var i = end + 1; i <= text.length; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -208,7 +208,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
for (var i = text.length - 1; i >= 0; i--) {
|
for (var i = text.length - 1; i >= 0; i--) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -238,7 +238,7 @@ void main() async {
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
for (var i = end - 1; i >= 0; i--) {
|
for (var i = end - 1; i >= 0; i--) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -250,7 +250,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
for (var i = 1; i <= text.length; i++) {
|
for (var i = 1; i <= text.length; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -295,7 +295,7 @@ void main() async {
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowUp,
|
key: LogicalKeyboardKey.arrowUp,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +307,7 @@ void main() async {
|
||||||
);
|
);
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowDown,
|
key: LogicalKeyboardKey.arrowDown,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -319,7 +319,7 @@ void main() async {
|
||||||
);
|
);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowUp,
|
key: LogicalKeyboardKey.arrowUp,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -341,18 +341,18 @@ void main() async {
|
||||||
final selection = Selection.single(path: [0], startOffset: 8);
|
final selection = Selection.single(path: [0], startOffset: 8);
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowDown,
|
key: LogicalKeyboardKey.arrowDown,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -375,18 +375,18 @@ void main() async {
|
||||||
final selection = Selection.single(path: [1], startOffset: 8);
|
final selection = Selection.single(path: [1], startOffset: 8);
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowUp,
|
key: LogicalKeyboardKey.arrowUp,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
);
|
);
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -409,7 +409,7 @@ void main() async {
|
||||||
final selection = Selection.single(path: [1], startOffset: 10);
|
final selection = Selection.single(path: [1], startOffset: 10);
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -421,7 +421,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -433,7 +433,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -445,7 +445,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -469,7 +469,7 @@ void main() async {
|
||||||
final selection = Selection.single(path: [0], startOffset: 10);
|
final selection = Selection.single(path: [0], startOffset: 10);
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -481,7 +481,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -493,12 +493,12 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -510,7 +510,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isShiftPressed: true,
|
isShiftPressed: true,
|
||||||
isAltPressed: true,
|
isAltPressed: true,
|
||||||
);
|
);
|
||||||
|
|
@ -535,12 +535,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -556,12 +556,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -578,12 +578,12 @@ void main() async {
|
||||||
for (var i = 0; i < words.length; i++) {
|
for (var i = 0; i < words.length; i++) {
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -607,12 +607,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -632,12 +632,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -667,11 +667,11 @@ Future<void> _testPressArrowKeyInNotCollapsedSelection(
|
||||||
end: isBackward ? end : start,
|
end: isBackward ? end : start,
|
||||||
);
|
);
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowLeft);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowLeft);
|
||||||
expect(editor.documentSelection?.start, start);
|
expect(editor.documentSelection?.start, start);
|
||||||
|
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.arrowRight);
|
||||||
expect(editor.documentSelection?.end, end);
|
expect(editor.documentSelection?.end, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -709,12 +709,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
||||||
await editor.updateSelection(selection);
|
await editor.updateSelection(selection);
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowLeft,
|
key: LogicalKeyboardKey.arrowLeft,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -726,12 +726,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowRight,
|
key: LogicalKeyboardKey.arrowRight,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -743,12 +743,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowUp,
|
key: LogicalKeyboardKey.arrowUp,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowUp,
|
key: LogicalKeyboardKey.arrowUp,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -760,12 +760,12 @@ Future<void> _testPressArrowKeyWithMetaInSelection(
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowDown,
|
key: LogicalKeyboardKey.arrowDown,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.arrowDown,
|
key: LogicalKeyboardKey.arrowDown,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ void main() async {
|
||||||
// Pressing the backspace key continuously.
|
// Pressing the backspace key continuously.
|
||||||
for (int i = 1; i <= 1; i++) {
|
for (int i = 1; i <= 1; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
);
|
);
|
||||||
expect(editor.documentLength, 1);
|
expect(editor.documentLength, 1);
|
||||||
expect(editor.documentSelection,
|
expect(editor.documentSelection,
|
||||||
|
|
@ -112,7 +112,7 @@ void main() async {
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [0], startOffset: text.length),
|
Selection.single(path: [0], startOffset: text.length),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||||
|
|
||||||
expect(editor.documentLength, 1);
|
expect(editor.documentLength, 1);
|
||||||
expect(editor.documentSelection,
|
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(editor.documentLength, 3);
|
||||||
expect(find.byType(ImageNodeWidget), findsNothing);
|
expect(find.byType(ImageNodeWidget), findsNothing);
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -249,20 +249,20 @@ void main() async {
|
||||||
final textNode = editor.nodeAtPath([0]) as TextNode;
|
final textNode = editor.nodeAtPath([0]) as TextNode;
|
||||||
|
|
||||||
await editor.insertText(textNode, '#', 0);
|
await editor.insertText(textNode, '#', 0);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.space);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.space);
|
||||||
expect(
|
expect(
|
||||||
(editor.nodeAtPath([0]) as TextNode).attributes.heading,
|
(editor.nodeAtPath([0]) as TextNode).attributes.heading,
|
||||||
BuiltInAttributeKey.h1,
|
BuiltInAttributeKey.h1,
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(
|
expect(
|
||||||
textNode.attributes.heading,
|
textNode.attributes.heading,
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.insertText(textNode, '#', 0);
|
await editor.insertText(textNode, '#', 0);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.space);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.space);
|
||||||
expect(
|
expect(
|
||||||
(editor.nodeAtPath([0]) as TextNode).attributes.heading,
|
(editor.nodeAtPath([0]) as TextNode).attributes.heading,
|
||||||
BuiltInAttributeKey.h1,
|
BuiltInAttributeKey.h1,
|
||||||
|
|
@ -296,17 +296,17 @@ void main() async {
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [0, 0, 0], startOffset: 0),
|
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);
|
expect(editor.nodeAtPath([0, 0, 0])?.subtype, null);
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [0, 0, 0], startOffset: 0),
|
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);
|
expect(editor.nodeAtPath([0, 1]) != null, true);
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [0, 1], startOffset: 0),
|
Selection.single(path: [0, 1], startOffset: 0),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(editor.nodeAtPath([1]) != null, true);
|
expect(editor.nodeAtPath([1]) != null, true);
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [1], startOffset: 0),
|
Selection.single(path: [1], startOffset: 0),
|
||||||
|
|
@ -314,7 +314,7 @@ void main() async {
|
||||||
|
|
||||||
// * Welcome to Appflowy 😁
|
// * Welcome to Appflowy 😁
|
||||||
// * Welcome to Appflowy 😁Welcome to Appflowy 😁
|
// * Welcome to Appflowy 😁Welcome to Appflowy 😁
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(
|
expect(
|
||||||
editor.documentSelection,
|
editor.documentSelection,
|
||||||
Selection.single(path: [0, 0], startOffset: text.length),
|
Selection.single(path: [0, 0], startOffset: text.length),
|
||||||
|
|
@ -356,7 +356,7 @@ void main() async {
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [0, 1], startOffset: 0),
|
Selection.single(path: [0, 1], startOffset: 0),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(
|
expect(
|
||||||
editor.nodeAtPath([0, 1])!.subtype != BuiltInAttributeKey.bulletedList,
|
editor.nodeAtPath([0, 1])!.subtype != BuiltInAttributeKey.bulletedList,
|
||||||
true,
|
true,
|
||||||
|
|
@ -382,7 +382,7 @@ void main() async {
|
||||||
// * Welcome to Appflowy 😁Welcome to Appflowy 😁
|
// * Welcome to Appflowy 😁Welcome to Appflowy 😁
|
||||||
// * Welcome to Appflowy 😁
|
// * Welcome to Appflowy 😁
|
||||||
// * Welcome to Appflowy 😁
|
// * Welcome to Appflowy 😁
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(
|
expect(
|
||||||
editor.nodeAtPath([0, 0])!.subtype == BuiltInAttributeKey.bulletedList,
|
editor.nodeAtPath([0, 0])!.subtype == BuiltInAttributeKey.bulletedList,
|
||||||
true,
|
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(editor.documentLength, 2);
|
||||||
expect(find.byType(ImageNodeWidget), findsNothing);
|
expect(find.byType(ImageNodeWidget), findsNothing);
|
||||||
expect(editor.documentSelection, Selection.collapsed(start));
|
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(editor.documentLength, 2);
|
||||||
expect(find.byType(ImageNodeWidget), findsNothing);
|
expect(find.byType(ImageNodeWidget), findsNothing);
|
||||||
expect(editor.documentSelection, Selection.collapsed(start));
|
expect(editor.documentSelection, Selection.collapsed(start));
|
||||||
|
|
@ -483,12 +483,12 @@ Future<void> _deleteStyledTextByBackspace(
|
||||||
Selection.single(path: [2], startOffset: 0),
|
Selection.single(path: [2], startOffset: 0),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
);
|
);
|
||||||
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 0));
|
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 0));
|
||||||
|
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
);
|
);
|
||||||
expect(editor.documentLength, 2);
|
expect(editor.documentLength, 2);
|
||||||
expect(editor.documentSelection,
|
expect(editor.documentSelection,
|
||||||
|
|
@ -500,7 +500,7 @@ Future<void> _deleteStyledTextByBackspace(
|
||||||
Selection.single(path: [1], startOffset: 0),
|
Selection.single(path: [1], startOffset: 0),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.backspace,
|
key: LogicalKeyboardKey.backspace,
|
||||||
);
|
);
|
||||||
expect(editor.documentLength, 2);
|
expect(editor.documentLength, 2);
|
||||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
||||||
|
|
@ -531,7 +531,7 @@ Future<void> _deleteStyledTextByDelete(
|
||||||
);
|
);
|
||||||
for (var i = 1; i < text.length; i++) {
|
for (var i = 1; i < text.length; i++) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.delete,
|
key: LogicalKeyboardKey.delete,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
||||||
|
|
@ -541,7 +541,7 @@ Future<void> _deleteStyledTextByDelete(
|
||||||
}
|
}
|
||||||
|
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.delete,
|
key: LogicalKeyboardKey.delete,
|
||||||
);
|
);
|
||||||
expect(editor.documentLength, 2);
|
expect(editor.documentLength, 2);
|
||||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
|
||||||
|
|
@ -562,7 +562,7 @@ Future<void> _deleteTextByBackspace(
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [1], startOffset: 10),
|
Selection.single(path: [1], startOffset: 10),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
|
|
||||||
expect(editor.documentLength, 3);
|
expect(editor.documentLength, 3);
|
||||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 9));
|
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 9));
|
||||||
|
|
@ -573,7 +573,7 @@ Future<void> _deleteTextByBackspace(
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [2], startOffset: 8, endOffset: 11),
|
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.documentLength, 3);
|
||||||
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 8));
|
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 8));
|
||||||
expect((editor.nodeAtPath([2]) as TextNode).toPlainText(),
|
expect((editor.nodeAtPath([2]) as TextNode).toPlainText(),
|
||||||
|
|
@ -587,7 +587,7 @@ Future<void> _deleteTextByBackspace(
|
||||||
await editor.updateSelection(Selection(
|
await editor.updateSelection(Selection(
|
||||||
start: isBackwardSelection ? start : end,
|
start: isBackwardSelection ? start : end,
|
||||||
end: isBackwardSelection ? end : start));
|
end: isBackwardSelection ? end : start));
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.backspace);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.backspace);
|
||||||
expect(editor.documentLength, 1);
|
expect(editor.documentLength, 1);
|
||||||
expect(
|
expect(
|
||||||
editor.documentSelection, Selection.single(path: [0], startOffset: 11));
|
editor.documentSelection, Selection.single(path: [0], startOffset: 11));
|
||||||
|
|
@ -608,7 +608,7 @@ Future<void> _deleteTextByDelete(
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [1], startOffset: 9),
|
Selection.single(path: [1], startOffset: 9),
|
||||||
);
|
);
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||||
|
|
||||||
expect(editor.documentLength, 3);
|
expect(editor.documentLength, 3);
|
||||||
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 9));
|
expect(editor.documentSelection, Selection.single(path: [1], startOffset: 9));
|
||||||
|
|
@ -619,7 +619,7 @@ Future<void> _deleteTextByDelete(
|
||||||
await editor.updateSelection(
|
await editor.updateSelection(
|
||||||
Selection.single(path: [2], startOffset: 8, endOffset: 11),
|
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.documentLength, 3);
|
||||||
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 8));
|
expect(editor.documentSelection, Selection.single(path: [2], startOffset: 8));
|
||||||
expect((editor.nodeAtPath([2]) as TextNode).toPlainText(),
|
expect((editor.nodeAtPath([2]) as TextNode).toPlainText(),
|
||||||
|
|
@ -633,7 +633,7 @@ Future<void> _deleteTextByDelete(
|
||||||
await editor.updateSelection(Selection(
|
await editor.updateSelection(Selection(
|
||||||
start: isBackwardSelection ? start : end,
|
start: isBackwardSelection ? start : end,
|
||||||
end: isBackwardSelection ? end : start));
|
end: isBackwardSelection ? end : start));
|
||||||
await editor.pressLogicKey(LogicalKeyboardKey.delete);
|
await editor.pressLogicKey(key: LogicalKeyboardKey.delete);
|
||||||
expect(editor.documentLength, 1);
|
expect(editor.documentLength, 1);
|
||||||
expect(
|
expect(
|
||||||
editor.documentSelection, Selection.single(path: [0], startOffset: 11));
|
editor.documentSelection, Selection.single(path: [0], startOffset: 11));
|
||||||
|
|
|
||||||
|
|
@ -47,12 +47,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -65,12 +65,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -145,12 +145,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -223,12 +223,12 @@ void main() async {
|
||||||
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isControlPressed: true,
|
isControlPressed: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await editor.pressLogicKey(
|
await editor.pressLogicKey(
|
||||||
LogicalKeyboardKey.enter,
|
key: LogicalKeyboardKey.enter,
|
||||||
isMetaPressed: true,
|
isMetaPressed: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue