Merge pull request #1554 from LucasXu0/rules

feat: add rules for editorstate.apply
This commit is contained in:
Lucas.Xu 2022-12-09 11:31:51 +08:00 committed by GitHub
commit 8494e0f0a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 9 deletions

View File

@ -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';
@ -72,6 +73,7 @@ class EditorState {
// TODO: only for testing. // TODO: only for testing.
bool disableSealTimer = false; bool disableSealTimer = false;
bool disbaleRules = false;
bool editable = true; bool editable = true;
@ -119,8 +121,12 @@ 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,
withUpdateCursor = true,
}) {
if (!editable) { if (!editable) {
return; return;
} }
@ -132,7 +138,10 @@ class EditorState {
_observer.add(transaction); _observer.add(transaction);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_applyRules(ruleCount);
if (withUpdateCursor) {
updateCursorSelection(transaction.afterSelection); updateCursorSelection(transaction.afterSelection);
}
}); });
if (options.recordUndo) { if (options.recordUndo) {
@ -153,7 +162,7 @@ class EditorState {
} }
} }
_debouncedSealHistoryItem() { void _debouncedSealHistoryItem() {
if (disableSealTimer) { if (disableSealTimer) {
return; return;
} }
@ -168,7 +177,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 +188,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 || disbaleRules) {
return;
}
final tr = transaction;
// Rules
_insureLastNodeEditable(tr);
if (tr.operations.isNotEmpty) {
apply(tr, ruleCount: ruleCount + 1, withUpdateCursor: false);
}
}
void _insureLastNodeEditable(Transaction tr) {
if (document.root.children.isEmpty ||
document.root.children.last.id != 'text') {
tr.insertNode([document.root.children.length], TextNode.empty());
}
}
} }

View File

@ -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,
), ),

View File

@ -157,7 +157,9 @@ class EditorWidgetTester {
document: Document( document: Document(
root: _createEmptyEditorRoot(), root: _createEmptyEditorRoot(),
), ),
)..disableSealTimer = true; )
..disableSealTimer = true
..disbaleRules = true;
} }
} }

View File

@ -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',