mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add rules for editorstate.apply
This commit is contained in:
parent
a507fb8ec6
commit
8bbae46a7c
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:appflowy_editor/src/core/document/node.dart';
|
||||||
import 'package:appflowy_editor/src/infra/log.dart';
|
import 'package:appflowy_editor/src/infra/log.dart';
|
||||||
import 'package:appflowy_editor/src/render/selection_menu/selection_menu_widget.dart';
|
import 'package:appflowy_editor/src/render/selection_menu/selection_menu_widget.dart';
|
||||||
import 'package:appflowy_editor/src/render/style/editor_style.dart';
|
import 'package:appflowy_editor/src/render/style/editor_style.dart';
|
||||||
@ -119,8 +120,11 @@ class EditorState {
|
|||||||
///
|
///
|
||||||
/// The options can be used to determine whether the editor
|
/// The options can be used to determine whether the editor
|
||||||
/// should record the transaction in undo/redo stack.
|
/// should record the transaction in undo/redo stack.
|
||||||
apply(Transaction transaction,
|
void apply(
|
||||||
[ApplyOptions options = const ApplyOptions(recordUndo: true)]) {
|
Transaction transaction, {
|
||||||
|
ApplyOptions options = const ApplyOptions(recordUndo: true),
|
||||||
|
ruleCount = 0,
|
||||||
|
}) {
|
||||||
if (!editable) {
|
if (!editable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -132,6 +136,7 @@ class EditorState {
|
|||||||
_observer.add(transaction);
|
_observer.add(transaction);
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_applyRules(ruleCount);
|
||||||
updateCursorSelection(transaction.afterSelection);
|
updateCursorSelection(transaction.afterSelection);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,7 +158,7 @@ class EditorState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_debouncedSealHistoryItem() {
|
void _debouncedSealHistoryItem() {
|
||||||
if (disableSealTimer) {
|
if (disableSealTimer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -168,7 +173,7 @@ class EditorState {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyOperation(Operation op) {
|
void _applyOperation(Operation op) {
|
||||||
if (op is InsertOperation) {
|
if (op is InsertOperation) {
|
||||||
document.insert(op.path, op.nodes);
|
document.insert(op.path, op.nodes);
|
||||||
} else if (op is UpdateOperation) {
|
} else if (op is UpdateOperation) {
|
||||||
@ -179,4 +184,27 @@ class EditorState {
|
|||||||
document.updateText(op.path, op.delta);
|
document.updateText(op.path, op.delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _applyRules(int ruleCount) {
|
||||||
|
// Set a maximum count to prevent a dead loop.
|
||||||
|
if (ruleCount >= 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final tr = transaction;
|
||||||
|
|
||||||
|
// Rules
|
||||||
|
_insureLastNodeEditable(tr);
|
||||||
|
|
||||||
|
if (tr.operations.isNotEmpty) {
|
||||||
|
apply(tr, ruleCount: ruleCount + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _insureLastNodeEditable(Transaction tr) {
|
||||||
|
if (document.root.children.isEmpty ||
|
||||||
|
document.root.children.last.id != 'text') {
|
||||||
|
tr.insertNode([document.root.children.length], TextNode.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ class UndoManager {
|
|||||||
final transaction = historyItem.toTransaction(s);
|
final transaction = historyItem.toTransaction(s);
|
||||||
s.apply(
|
s.apply(
|
||||||
transaction,
|
transaction,
|
||||||
const ApplyOptions(
|
options: const ApplyOptions(
|
||||||
recordUndo: false,
|
recordUndo: false,
|
||||||
recordRedo: true,
|
recordRedo: true,
|
||||||
),
|
),
|
||||||
@ -143,7 +143,7 @@ class UndoManager {
|
|||||||
final transaction = historyItem.toTransaction(s);
|
final transaction = historyItem.toTransaction(s);
|
||||||
s.apply(
|
s.apply(
|
||||||
transaction,
|
transaction,
|
||||||
const ApplyOptions(
|
options: const ApplyOptions(
|
||||||
recordUndo: true,
|
recordUndo: true,
|
||||||
recordRedo: false,
|
recordRedo: false,
|
||||||
),
|
),
|
||||||
|
@ -97,7 +97,8 @@ SelectionMenuItem codeBlockMenuItem = SelectionMenuItem(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final transaction = editorState.transaction;
|
final transaction = editorState.transaction;
|
||||||
if (textNodes.first.toPlainText().isEmpty) {
|
final textNode = textNodes.first;
|
||||||
|
if (textNode.toPlainText().isEmpty && textNode.next is TextNode) {
|
||||||
transaction.updateNode(textNodes.first, {
|
transaction.updateNode(textNodes.first, {
|
||||||
BuiltInAttributeKey.subtype: kCodeBlockSubType,
|
BuiltInAttributeKey.subtype: kCodeBlockSubType,
|
||||||
kCodeBlockAttrTheme: 'vs',
|
kCodeBlockAttrTheme: 'vs',
|
||||||
|
Loading…
Reference in New Issue
Block a user