Skip to content

Commit 51fed2c

Browse files
angelosilvestrematthew-carroll
authored andcommitted
[SuperEditor] Don't activate an action tag when placing the caret at an existing tag pattern. (Resolves #2392) (#2771)
1 parent 6e2f8e1 commit 51fed2c

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

super_editor/lib/src/default_editor/text_tokenizing/action_tags.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:math';
22

33
import 'package:attributed_text/attributed_text.dart';
44
import 'package:characters/characters.dart';
5+
import 'package:collection/collection.dart';
56
import 'package:flutter/foundation.dart';
67
import 'package:flutter/services.dart';
78
import 'package:super_editor/src/core/document.dart';
@@ -326,6 +327,17 @@ class ActionTagComposingReaction extends EditReaction {
326327
return;
327328
}
328329

330+
final hasComposingTagAttribution = textNode!.text
331+
.getAttributionSpansInRange(
332+
attributionFilter: (attribution) => attribution == actionTagComposingAttribution,
333+
range: SpanRange(tagAroundPosition.indexedTag.startOffset, tagAroundPosition.indexedTag.endOffset),
334+
)
335+
.isNotEmpty;
336+
if (changeList.none((event) => event is DocumentEdit) && !hasComposingTagAttribution) {
337+
// The user is neither typing nor moving the caret within an existing composing tag.
338+
return;
339+
}
340+
329341
_updateComposingTag(requestDispatcher, tagAroundPosition.indexedTag);
330342
editorContext.composingActionTag.value = tagAroundPosition.indexedTag;
331343
_onUpdateComposingActionTag(tagAroundPosition.indexedTag);

super_editor/test/super_editor/text_entry/tagging/action_tags_test.dart

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,63 @@ void main() {
768768
// Ensure that we received a notification when the tag was cancelled.
769769
expect(tagNotificationCount, 7);
770770
});
771+
772+
testWidgetsOnAllPlatforms("does not start composing when placing the caret at an existing tag pattern",
773+
(tester) async {
774+
await _pumpTestEditor(
775+
tester,
776+
MutableDocument(
777+
nodes: [
778+
ParagraphNode(
779+
id: "1",
780+
text: AttributedText("This is origin/main branch"),
781+
),
782+
],
783+
),
784+
);
785+
786+
// Place the caret at "mai|n".
787+
await tester.placeCaretInParagraph("1", 18);
788+
789+
// Ensure that we are not composing a tag.
790+
final text = SuperEditorInspector.findTextInComponent("1");
791+
expect(
792+
text.getAttributionSpansInRange(
793+
attributionFilter: (attribution) => attribution == actionTagComposingAttribution,
794+
range: const SpanRange(0, 26),
795+
),
796+
isEmpty,
797+
);
798+
});
799+
800+
testWidgetsOnAllPlatforms("updates composing when moving the caret within an existing composing tag",
801+
(tester) async {
802+
await _pumpTestEditor(
803+
tester,
804+
singleParagraphEmptyDoc(),
805+
);
806+
await tester.placeCaretInParagraph("1", 0);
807+
808+
// Compose an action tag.
809+
await tester.typeImeText("/header");
810+
811+
// Ensure that the tag has a composing attribution.
812+
final textBefore = SuperEditorInspector.findTextInComponent("1");
813+
expect(
814+
textBefore.getAttributedRange({actionTagComposingAttribution}, 0),
815+
const SpanRange(0, 6),
816+
);
817+
818+
// Press the left arrow to move the caret within the tag.
819+
await tester.pressLeftArrow();
820+
821+
// Ensure that the tag was updated.
822+
final textAfter = SuperEditorInspector.findTextInComponent("1");
823+
expect(
824+
textAfter.getAttributedRange({actionTagComposingAttribution}, 0),
825+
const SpanRange(0, 5),
826+
);
827+
});
771828
});
772829

773830
group("submissions >", () {

0 commit comments

Comments
 (0)