Skip to content

Commit

Permalink
feat: support skipping slice attributes (#901)
Browse files Browse the repository at this point in the history
* feat: skip slicing the next inserted text if the previous text has been formatted

* test: skip slicing attribute test

* feat: reset slice flag when updating selection
  • Loading branch information
LucasXu0 authored Sep 26, 2024
1 parent 628d5c8 commit ab977f9
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 2 deletions.
5 changes: 4 additions & 1 deletion lib/src/core/transform/transaction.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ extension TextTransaction on Transaction {
String text, {
Attributes? attributes,
Attributes? toggledAttributes,
bool sliceAttributes = true,
}) {
final delta = node.delta;
if (delta == null) {
Expand All @@ -210,7 +211,9 @@ extension TextTransaction on Transaction {
return;
}

final newAttributes = attributes ?? delta.sliceAttributes(index) ?? {};
final newAttributes = attributes ??
(sliceAttributes ? delta.sliceAttributes(index) : {}) ??
{};

if (toggledAttributes != null) {
newAttributes.addAll(toggledAttributes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Future<void> onInsert(
);

if (execution) {
editorState.sliceUpcomingAttributes = false;
return;
}
}
Expand Down Expand Up @@ -76,7 +77,8 @@ Future<void> onInsert(
selection.startIndex,
textInserted,
toggledAttributes: editorState.toggledStyle,
sliceAttributes: editorState.sliceUpcomingAttributes,
)
..afterSelection = afterSelection;
return editorState.apply(transaction);
await editorState.apply(transaction);
}
9 changes: 9 additions & 0 deletions lib/src/editor_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class EditorState {
_toggledStyle.clear();
}

// reset slice flag
sliceUpcomingAttributes = true;

selectionNotifier.value = value;
}

Expand Down Expand Up @@ -183,6 +186,12 @@ class EditorState {
toggledStyleNotifier.value = {..._toggledStyle};
}

/// Whether the upcoming attributes should be sliced.
///
/// If the value is true, the upcoming attributes will be sliced.
/// If the value is false, the upcoming attributes will be skipped.
bool sliceUpcomingAttributes = true;

final UndoManager undoManager = UndoManager();

Transaction get transaction {
Expand Down
66 changes: 66 additions & 0 deletions test/customer/slice_attributes_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import '../new/infra/testable_editor.dart';

void main() async {
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
});

// input `Hello` World
// only the `Hello` has the code style
testWidgets('skip attributes if pressing space', (tester) async {
final editor = tester.editor..addEmptyParagraph();
await editor.startTesting();
await tester.pumpAndSettle();

final selection = Selection.collapsed(Position(path: [0]));
await editor.updateSelection(selection);
const text = '`Hello` World';
for (var i = 0; i < text.length; i++) {
await editor.ime.typeText(text[i]);
}

final node = editor.editorState.getNodeAtPath([0]);
final delta = node?.delta;
expect(delta?.toPlainText(), 'Hello World');
expect(delta?.toJson(), [
{
'insert': 'Hello',
'attributes': {'code': true},
},
{'insert': ' World'},
]);
});

testWidgets('keep attributes if pressing backspace', (tester) async {
final editor = tester.editor..addEmptyParagraph();
await editor.startTesting();
await tester.pumpAndSettle();

final selection = Selection.collapsed(Position(path: [0]));
await editor.updateSelection(selection);
const text1 = '`Hello` ';
for (var i = 0; i < text1.length; i++) {
await editor.ime.typeText(text1[i]);
}

await tester.editor.pressKey(key: LogicalKeyboardKey.backspace);

const text2 = 'World';
for (var i = 0; i < text2.length; i++) {
await editor.ime.typeText(text2[i]);
}

final node = editor.editorState.getNodeAtPath([0]);
final delta = node?.delta;
expect(delta?.toJson(), [
{
'insert': 'HelloWorld',
'attributes': {'code': true},
},
]);
});
}

0 comments on commit ab977f9

Please sign in to comment.