Skip to content

Commit 8494e0f

Browse files
authored
Merge pull request #1554 from LucasXu0/rules
feat: add rules for editorstate.apply
2 parents 12441f1 + e94eb20 commit 8494e0f

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

frontend/app_flowy/packages/appflowy_editor/lib/src/editor_state.dart

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:async';
2+
import 'package:appflowy_editor/src/core/document/node.dart';
23
import 'package:appflowy_editor/src/infra/log.dart';
34
import 'package:appflowy_editor/src/render/selection_menu/selection_menu_widget.dart';
45
import 'package:appflowy_editor/src/render/style/editor_style.dart';
@@ -72,6 +73,7 @@ class EditorState {
7273

7374
// TODO: only for testing.
7475
bool disableSealTimer = false;
76+
bool disbaleRules = false;
7577

7678
bool editable = true;
7779

@@ -119,8 +121,12 @@ class EditorState {
119121
///
120122
/// The options can be used to determine whether the editor
121123
/// should record the transaction in undo/redo stack.
122-
apply(Transaction transaction,
123-
[ApplyOptions options = const ApplyOptions(recordUndo: true)]) {
124+
void apply(
125+
Transaction transaction, {
126+
ApplyOptions options = const ApplyOptions(recordUndo: true),
127+
ruleCount = 0,
128+
withUpdateCursor = true,
129+
}) {
124130
if (!editable) {
125131
return;
126132
}
@@ -132,7 +138,10 @@ class EditorState {
132138
_observer.add(transaction);
133139

134140
WidgetsBinding.instance.addPostFrameCallback((_) {
135-
updateCursorSelection(transaction.afterSelection);
141+
_applyRules(ruleCount);
142+
if (withUpdateCursor) {
143+
updateCursorSelection(transaction.afterSelection);
144+
}
136145
});
137146

138147
if (options.recordUndo) {
@@ -153,7 +162,7 @@ class EditorState {
153162
}
154163
}
155164

156-
_debouncedSealHistoryItem() {
165+
void _debouncedSealHistoryItem() {
157166
if (disableSealTimer) {
158167
return;
159168
}
@@ -168,7 +177,7 @@ class EditorState {
168177
});
169178
}
170179

171-
_applyOperation(Operation op) {
180+
void _applyOperation(Operation op) {
172181
if (op is InsertOperation) {
173182
document.insert(op.path, op.nodes);
174183
} else if (op is UpdateOperation) {
@@ -179,4 +188,27 @@ class EditorState {
179188
document.updateText(op.path, op.delta);
180189
}
181190
}
191+
192+
void _applyRules(int ruleCount) {
193+
// Set a maximum count to prevent a dead loop.
194+
if (ruleCount >= 5 || disbaleRules) {
195+
return;
196+
}
197+
198+
final tr = transaction;
199+
200+
// Rules
201+
_insureLastNodeEditable(tr);
202+
203+
if (tr.operations.isNotEmpty) {
204+
apply(tr, ruleCount: ruleCount + 1, withUpdateCursor: false);
205+
}
206+
}
207+
208+
void _insureLastNodeEditable(Transaction tr) {
209+
if (document.root.children.isEmpty ||
210+
document.root.children.last.id != 'text') {
211+
tr.insertNode([document.root.children.length], TextNode.empty());
212+
}
213+
}
182214
}

frontend/app_flowy/packages/appflowy_editor/lib/src/history/undo_manager.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class UndoManager {
123123
final transaction = historyItem.toTransaction(s);
124124
s.apply(
125125
transaction,
126-
const ApplyOptions(
126+
options: const ApplyOptions(
127127
recordUndo: false,
128128
recordRedo: true,
129129
),
@@ -143,7 +143,7 @@ class UndoManager {
143143
final transaction = historyItem.toTransaction(s);
144144
s.apply(
145145
transaction,
146-
const ApplyOptions(
146+
options: const ApplyOptions(
147147
recordUndo: true,
148148
recordRedo: false,
149149
),

frontend/app_flowy/packages/appflowy_editor/test/infra/test_editor.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ class EditorWidgetTester {
157157
document: Document(
158158
root: _createEmptyEditorRoot(),
159159
),
160-
)..disableSealTimer = true;
160+
)
161+
..disableSealTimer = true
162+
..disbaleRules = true;
161163
}
162164
}
163165

frontend/app_flowy/packages/appflowy_editor_plugins/lib/src/code_block/code_block_shortcut_event.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ SelectionMenuItem codeBlockMenuItem = SelectionMenuItem(
9797
return;
9898
}
9999
final transaction = editorState.transaction;
100-
if (textNodes.first.toPlainText().isEmpty) {
100+
final textNode = textNodes.first;
101+
if (textNode.toPlainText().isEmpty && textNode.next is TextNode) {
101102
transaction.updateNode(textNodes.first, {
102103
BuiltInAttributeKey.subtype: kCodeBlockSubType,
103104
kCodeBlockAttrTheme: 'vs',

0 commit comments

Comments
 (0)