fix: paste single line text will remove the children block (#1100)
* fix: paste single line text will remove the children block * fix: ignore deletion in table cell blocl * chore: update undo redo stack size and seal time * chore: refactor undo logic * Revert "chore: refactor undo logic" This reverts commit 98d64528845eba23f145827d331606afeb2840e5.
This commit is contained in:
parent
37c99eee9a
commit
e56746ac65
3 changed files with 27 additions and 19 deletions
|
|
@ -47,7 +47,12 @@ extension SelectionTransform on EditorState {
|
||||||
/// and deletes the nodes expect for the first node.
|
/// and deletes the nodes expect for the first node.
|
||||||
///
|
///
|
||||||
/// For the other cases, this function just deletes all the nodes.
|
/// For the other cases, this function just deletes all the nodes.
|
||||||
Future<bool> deleteSelection(Selection selection) async {
|
Future<bool> deleteSelection(
|
||||||
|
Selection selection, {
|
||||||
|
List<String> ignoreNodeTypes = const [
|
||||||
|
TableCellBlockKeys.type,
|
||||||
|
],
|
||||||
|
}) async {
|
||||||
// Nothing to do if the selection is collapsed.
|
// Nothing to do if the selection is collapsed.
|
||||||
if (selection.isCollapsed) {
|
if (selection.isCollapsed) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -66,7 +71,7 @@ extension SelectionTransform on EditorState {
|
||||||
// or node.
|
// or node.
|
||||||
if (nodes.length == 1) {
|
if (nodes.length == 1) {
|
||||||
// If table cell is selected, clear the cell node child.
|
// If table cell is selected, clear the cell node child.
|
||||||
final node = nodes.first.type == TableCellBlockKeys.type
|
final node = ignoreNodeTypes.contains(nodes.first.type)
|
||||||
? nodes.first.children.first
|
? nodes.first.children.first
|
||||||
: nodes.first;
|
: nodes.first;
|
||||||
if (node.delta != null) {
|
if (node.delta != null) {
|
||||||
|
|
@ -75,7 +80,7 @@ extension SelectionTransform on EditorState {
|
||||||
selection.startIndex,
|
selection.startIndex,
|
||||||
selection.length,
|
selection.length,
|
||||||
);
|
);
|
||||||
} else if (node.parent?.type != TableCellBlockKeys.type) {
|
} else if (!ignoreNodeTypes.contains(node.parent?.type)) {
|
||||||
transaction.deleteNode(node);
|
transaction.deleteNode(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +97,7 @@ extension SelectionTransform on EditorState {
|
||||||
// All other nodes can be deleted.
|
// All other nodes can be deleted.
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
// Never delete a table cell node child
|
// Never delete a table cell node child
|
||||||
if (node.parent?.type == TableCellBlockKeys.type) {
|
if (ignoreNodeTypes.contains(node.parent?.type)) {
|
||||||
if (!nodes.any((n) => n.id == node.parent?.parent?.id)) {
|
if (!nodes.any((n) => n.id == node.parent?.parent?.id)) {
|
||||||
transaction.deleteText(
|
transaction.deleteText(
|
||||||
node,
|
node,
|
||||||
|
|
@ -105,13 +110,13 @@ extension SelectionTransform on EditorState {
|
||||||
// node, So we should not delete the last node. Just delete part of
|
// node, So we should not delete the last node. Just delete part of
|
||||||
// the text inside selection
|
// the text inside selection
|
||||||
else if (node.id == nodes.last.id &&
|
else if (node.id == nodes.last.id &&
|
||||||
nodes.first.parent?.type == TableCellBlockKeys.type) {
|
ignoreNodeTypes.contains(nodes.first.parent?.type)) {
|
||||||
transaction.deleteText(
|
transaction.deleteText(
|
||||||
node,
|
node,
|
||||||
0,
|
0,
|
||||||
selection.end.offset,
|
selection.end.offset,
|
||||||
);
|
);
|
||||||
} else if (node.type != TableCellBlockKeys.type) {
|
} else if (!ignoreNodeTypes.contains(node.type)) {
|
||||||
transaction.deleteNode(node);
|
transaction.deleteNode(node);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -122,7 +127,7 @@ extension SelectionTransform on EditorState {
|
||||||
// the text between the two nodes.
|
// the text between the two nodes.
|
||||||
if (nodes.last.delta != null &&
|
if (nodes.last.delta != null &&
|
||||||
![node.parent?.type, nodes.last.parent?.type]
|
![node.parent?.type, nodes.last.parent?.type]
|
||||||
.contains(TableCellBlockKeys.type)) {
|
.any((type) => ignoreNodeTypes.contains(type))) {
|
||||||
transaction.mergeText(
|
transaction.mergeText(
|
||||||
node,
|
node,
|
||||||
nodes.last,
|
nodes.last,
|
||||||
|
|
@ -154,8 +159,8 @@ extension SelectionTransform on EditorState {
|
||||||
else {
|
else {
|
||||||
// If the last or first node is inside table we will only delete
|
// If the last or first node is inside table we will only delete
|
||||||
// selection part of first node.
|
// selection part of first node.
|
||||||
if (nodes.last.parent?.type == TableCellBlockKeys.type ||
|
if (ignoreNodeTypes.contains(nodes.last.parent?.type) ||
|
||||||
node.parent?.type == TableCellBlockKeys.type) {
|
ignoreNodeTypes.contains(node.parent?.type)) {
|
||||||
transaction.deleteText(
|
transaction.deleteText(
|
||||||
node,
|
node,
|
||||||
selection.startIndex,
|
selection.startIndex,
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,18 @@ extension EditorCopyPaste on EditorState {
|
||||||
final insertedDelta = insertedNode.delta;
|
final insertedDelta = insertedNode.delta;
|
||||||
// if the node is empty paragraph (default), replace it with the inserted node.
|
// if the node is empty paragraph (default), replace it with the inserted node.
|
||||||
if (delta.isEmpty && node.type == ParagraphBlockKeys.type) {
|
if (delta.isEmpty && node.type == ParagraphBlockKeys.type) {
|
||||||
transaction.insertNode(
|
final List<Node> combinedChildren = [
|
||||||
selection.end.path.next,
|
...insertedNode.children.map((e) => e.deepCopy()),
|
||||||
insertedNode,
|
// if the original node has children, copy them to the inserted node.
|
||||||
);
|
...node.children.map((e) => e.deepCopy()),
|
||||||
|
];
|
||||||
|
insertedNode = insertedNode.copyWith(children: combinedChildren);
|
||||||
|
transaction.insertNode(selection.end.path, insertedNode);
|
||||||
transaction.deleteNode(node);
|
transaction.deleteNode(node);
|
||||||
final path = calculatePath(selection.end.path, [insertedNode]);
|
|
||||||
final offset = calculateLength([insertedNode]);
|
|
||||||
transaction.afterSelection = Selection.collapsed(
|
transaction.afterSelection = Selection.collapsed(
|
||||||
Position(
|
Position(
|
||||||
path: path,
|
path: selection.end.path,
|
||||||
offset: offset,
|
offset: insertedDelta?.length ?? 0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (insertedDelta != null) {
|
} else if (insertedDelta != null) {
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,10 @@ enum TransactionTime {
|
||||||
class EditorState {
|
class EditorState {
|
||||||
EditorState({
|
EditorState({
|
||||||
required this.document,
|
required this.document,
|
||||||
this.minHistoryItemDuration = const Duration(milliseconds: 200),
|
this.minHistoryItemDuration = const Duration(milliseconds: 50),
|
||||||
|
int? maxHistoryItemSize,
|
||||||
}) {
|
}) {
|
||||||
|
undoManager = UndoManager(maxHistoryItemSize ?? 200);
|
||||||
undoManager.state = this;
|
undoManager.state = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,7 +254,7 @@ class EditorState {
|
||||||
_sliceUpcomingAttributes = value;
|
_sliceUpcomingAttributes = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
final UndoManager undoManager = UndoManager();
|
late final UndoManager undoManager;
|
||||||
|
|
||||||
Transaction get transaction {
|
Transaction get transaction {
|
||||||
final transaction = Transaction(document: document);
|
final transaction = Transaction(document: document);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue