Skip to content

Commit ddb1af5

Browse files
committed
Updating various parts of super_editor to support AttributedSpans with exclusive end positions
1 parent 79b9e84 commit ddb1af5

File tree

8 files changed

+46
-50
lines changed

8 files changed

+46
-50
lines changed

attributed_text/lib/src/attributed_spans.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ class AttributedSpans {
559559
required AttributedSpans other,
560560
required int index,
561561
}) {
562-
if (markers.isNotEmpty && markers.last.offset >= index) {
562+
if (markers.isNotEmpty && markers.last.offset > index) {
563563
throw Exception(
564564
'Another AttributedSpans can only be appended after the final marker in this AttributedSpans. Final marker: ${markers.last}');
565565
}
@@ -605,7 +605,7 @@ class AttributedSpans {
605605
// Look for any compatible attributions at
606606
// `mergePoint - 1` and `mergePoint` and combine them.
607607
final endAtMergePointMarkers =
608-
attributions.where((marker) => marker.isEnd && marker.offset == mergePoint - 1).toList();
608+
attributions.where((marker) => marker.isEnd && marker.offset == mergePoint).toList();
609609
final startAtMergePointMarkers =
610610
attributions.where((marker) => marker.isStart && marker.offset == mergePoint).toList();
611611
for (final startMarker in startAtMergePointMarkers) {

attributed_text/lib/src/attributed_text.dart

+3-5
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,14 @@ class AttributedText {
186186
AttributedText copyText(int startOffset, [int? endOffset]) {
187187
_log.fine('start: $startOffset, end: $endOffset');
188188

189-
// Note: -1 because copyText() uses an exclusive `start` and `end` but
190-
// _copyAttributionRegion() uses an inclusive `start` and `end`.
191189
final startCopyOffset = startOffset < text.length ? startOffset : text.length - 1;
192190
int endCopyOffset;
193191
if (endOffset == startOffset) {
194192
endCopyOffset = startCopyOffset;
195193
} else if (endOffset != null) {
196-
endCopyOffset = endOffset - 1;
194+
endCopyOffset = endOffset;
197195
} else {
198-
endCopyOffset = text.length - 1;
196+
endCopyOffset = text.length;
199197
}
200198
_log.fine('offsets, start: $startCopyOffset, end: $endCopyOffset');
201199

@@ -269,7 +267,7 @@ class AttributedText {
269267
final insertedText = AttributedText(
270268
text: textToInsert,
271269
);
272-
final insertTextRange = SpanRange(start: 0, end: textToInsert.length - 1);
270+
final insertTextRange = SpanRange(start: 0, end: textToInsert.length);
273271
for (dynamic attribution in applyAttributions) {
274272
insertedText.addAttribution(attribution, insertTextRange);
275273
}

super_editor/lib/src/infrastructure/super_textfield/infrastructure/attributed_text_editing_controller.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class AttributedTextEditingController with ChangeNotifier {
119119
for (final attribution in attributions) {
120120
_text.toggleAttribution(
121121
attribution,
122-
SpanRange(start: selection.start, end: selection.end - 1),
122+
SpanRange(start: selection.start, end: selection.end),
123123
);
124124
}
125125

@@ -133,7 +133,7 @@ class AttributedTextEditingController with ChangeNotifier {
133133
}
134134

135135
_text.clearAttributions(
136-
SpanRange(start: selection.start, end: selection.end - 1),
136+
SpanRange(start: selection.start, end: selection.end),
137137
);
138138

139139
notifyListeners();

super_editor/test/src/attributed_text_styles_test.dart

+11-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void main() {
2121
spans: AttributedSpans(
2222
attributions: [
2323
const SpanMarker(attribution: ExpectedSpans.bold, offset: 0, markerType: SpanMarkerType.start),
24-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 9, markerType: SpanMarkerType.end),
24+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 10, markerType: SpanMarkerType.end),
2525
],
2626
),
2727
);
@@ -38,7 +38,7 @@ void main() {
3838
spans: AttributedSpans(
3939
attributions: [
4040
const SpanMarker(attribution: ExpectedSpans.bold, offset: 1, markerType: SpanMarkerType.start),
41-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 1, markerType: SpanMarkerType.end),
41+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 2, markerType: SpanMarkerType.end),
4242
],
4343
),
4444
);
@@ -61,7 +61,7 @@ void main() {
6161
// Notice that the markers are provided in reverse order:
6262
// end then start. Order shouldn't matter within a single
6363
// position index. This test ensures that.
64-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 1, markerType: SpanMarkerType.end),
64+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 2, markerType: SpanMarkerType.end),
6565
const SpanMarker(attribution: ExpectedSpans.bold, offset: 1, markerType: SpanMarkerType.start),
6666
],
6767
),
@@ -79,7 +79,7 @@ void main() {
7979

8080
test('add single character style', () {
8181
final text = AttributedText(text: 'abcdefghij');
82-
text.addAttribution(ExpectedSpans.bold, const SpanRange(start: 1, end: 1));
82+
text.addAttribution(ExpectedSpans.bold, const SpanRange(start: 1, end: 2));
8383
final textSpan = text.computeTextSpan(_styleBuilder);
8484

8585
expect(textSpan.text, null);
@@ -97,7 +97,7 @@ void main() {
9797
spans: AttributedSpans(
9898
attributions: [
9999
const SpanMarker(attribution: ExpectedSpans.bold, offset: 2, markerType: SpanMarkerType.start),
100-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 7, markerType: SpanMarkerType.end),
100+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 8, markerType: SpanMarkerType.end),
101101
],
102102
),
103103
);
@@ -117,7 +117,7 @@ void main() {
117117
spans: AttributedSpans(
118118
attributions: [
119119
const SpanMarker(attribution: ExpectedSpans.bold, offset: 9, markerType: SpanMarkerType.start),
120-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 9, markerType: SpanMarkerType.end),
120+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 10, markerType: SpanMarkerType.end),
121121
],
122122
),
123123
);
@@ -127,7 +127,7 @@ void main() {
127127
spans: AttributedSpans(
128128
attributions: [
129129
const SpanMarker(attribution: ExpectedSpans.bold, offset: 0, markerType: SpanMarkerType.start),
130-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 0, markerType: SpanMarkerType.end),
130+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 1, markerType: SpanMarkerType.end),
131131
],
132132
),
133133
));
@@ -152,9 +152,9 @@ void main() {
152152
spans: AttributedSpans(
153153
attributions: [
154154
const SpanMarker(attribution: ExpectedSpans.bold, offset: 0, markerType: SpanMarkerType.start),
155-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 4, markerType: SpanMarkerType.end),
155+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 5, markerType: SpanMarkerType.end),
156156
const SpanMarker(attribution: ExpectedSpans.italics, offset: 5, markerType: SpanMarkerType.start),
157-
const SpanMarker(attribution: ExpectedSpans.italics, offset: 9, markerType: SpanMarkerType.end),
157+
const SpanMarker(attribution: ExpectedSpans.italics, offset: 10, markerType: SpanMarkerType.end),
158158
],
159159
),
160160
);
@@ -177,8 +177,8 @@ void main() {
177177
attributions: [
178178
const SpanMarker(attribution: ExpectedSpans.bold, offset: 2, markerType: SpanMarkerType.start),
179179
const SpanMarker(attribution: ExpectedSpans.italics, offset: 4, markerType: SpanMarkerType.start),
180-
const SpanMarker(attribution: ExpectedSpans.bold, offset: 5, markerType: SpanMarkerType.end),
181-
const SpanMarker(attribution: ExpectedSpans.italics, offset: 7, markerType: SpanMarkerType.end),
180+
const SpanMarker(attribution: ExpectedSpans.bold, offset: 6, markerType: SpanMarkerType.end),
181+
const SpanMarker(attribution: ExpectedSpans.italics, offset: 8, markerType: SpanMarkerType.end),
182182
],
183183
),
184184
);

super_editor/test/super_textfield/attributed_text_editing_controller_test.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void main() {
8383
spans: AttributedSpans(
8484
attributions: [
8585
const SpanMarker(attribution: boldAttribution, offset: 7, markerType: SpanMarkerType.start),
86-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
86+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
8787
],
8888
),
8989
),
@@ -105,7 +105,7 @@ void main() {
105105
spans: AttributedSpans(
106106
attributions: [
107107
const SpanMarker(attribution: boldAttribution, offset: 7, markerType: SpanMarkerType.start),
108-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
108+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
109109
],
110110
),
111111
),
@@ -404,7 +404,7 @@ void main() {
404404
spans: AttributedSpans(
405405
attributions: [
406406
const SpanMarker(attribution: boldAttribution, offset: 0, markerType: SpanMarkerType.start),
407-
const SpanMarker(attribution: boldAttribution, offset: 0, markerType: SpanMarkerType.end),
407+
const SpanMarker(attribution: boldAttribution, offset: 1, markerType: SpanMarkerType.end),
408408
],
409409
),
410410
),
@@ -500,7 +500,7 @@ void main() {
500500
spans: AttributedSpans(
501501
attributions: [
502502
const SpanMarker(attribution: boldAttribution, offset: 0, markerType: SpanMarkerType.start),
503-
const SpanMarker(attribution: boldAttribution, offset: 10, markerType: SpanMarkerType.end),
503+
const SpanMarker(attribution: boldAttribution, offset: 11, markerType: SpanMarkerType.end),
504504
],
505505
),
506506
),

super_editor/test/super_textfield/ime_attributed_text_editing_controller_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ void main() {
189189
spans: AttributedSpans(
190190
attributions: [
191191
const SpanMarker(attribution: boldAttribution, offset: 7, markerType: SpanMarkerType.start),
192-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
192+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
193193
],
194194
),
195195
),
@@ -221,7 +221,7 @@ void main() {
221221
spans: AttributedSpans(
222222
attributions: [
223223
const SpanMarker(attribution: boldAttribution, offset: 7, markerType: SpanMarkerType.start),
224-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
224+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
225225
],
226226
),
227227
),

super_editor_markdown/lib/src/markdown.dart

+4-6
Original file line numberDiff line numberDiff line change
@@ -381,23 +381,23 @@ class _InlineMarkdownToDocument implements md.NodeVisitor {
381381
boldAttribution,
382382
SpanRange(
383383
start: 0,
384-
end: styledText.text.length - 1,
384+
end: styledText.text.length,
385385
),
386386
);
387387
} else if (element.tag == 'em') {
388388
styledText.addAttribution(
389389
italicsAttribution,
390390
SpanRange(
391391
start: 0,
392-
end: styledText.text.length - 1,
392+
end: styledText.text.length,
393393
),
394394
);
395395
} else if (element.tag == 'a') {
396396
styledText.addAttribution(
397397
LinkAttribution(url: Uri.parse(element.attributes['href']!)),
398398
SpanRange(
399399
start: 0,
400-
end: styledText.text.length - 1,
400+
end: styledText.text.length,
401401
),
402402
);
403403
}
@@ -478,10 +478,8 @@ extension on AttributedText {
478478
..write(markdownStyles);
479479
break;
480480
case AttributionVisitEvent.end:
481-
// +1 on end index because this visitor has inclusive indices
482-
// whereas substring() expects an exclusive ending index.
483481
buffer
484-
..write(fullText.text.substring(spanStart, index + 1))
482+
..write(fullText.text.substring(spanStart, index))
485483
..write(markdownStyles)
486484
..write(linkMarker);
487485
break;

super_editor_markdown/test/super_editor_markdown_test.dart

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import 'package:super_editor/super_editor.dart';
21
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:super_editor/super_editor.dart';
33
import 'package:super_editor_markdown/super_editor_markdown.dart';
44

55
void main() {
@@ -41,7 +41,7 @@ void main() {
4141
spans: AttributedSpans(
4242
attributions: [
4343
const SpanMarker(attribution: boldAttribution, offset: 3, markerType: SpanMarkerType.start),
44-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
44+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
4545
],
4646
),
4747
),
@@ -73,7 +73,7 @@ void main() {
7373
spans: AttributedSpans(
7474
attributions: [
7575
const SpanMarker(attribution: boldAttribution, offset: 10, markerType: SpanMarkerType.start),
76-
const SpanMarker(attribution: boldAttribution, offset: 19, markerType: SpanMarkerType.end),
76+
const SpanMarker(attribution: boldAttribution, offset: 20, markerType: SpanMarkerType.end),
7777
],
7878
),
7979
),
@@ -122,7 +122,7 @@ This is some code
122122
spans: AttributedSpans(
123123
attributions: [
124124
const SpanMarker(attribution: boldAttribution, offset: 5, markerType: SpanMarkerType.start),
125-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
125+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
126126
],
127127
),
128128
),
@@ -141,9 +141,9 @@ This is some code
141141
spans: AttributedSpans(
142142
attributions: [
143143
const SpanMarker(attribution: boldAttribution, offset: 5, markerType: SpanMarkerType.start),
144-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
144+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
145145
const SpanMarker(attribution: italicsAttribution, offset: 5, markerType: SpanMarkerType.start),
146-
const SpanMarker(attribution: italicsAttribution, offset: 8, markerType: SpanMarkerType.end),
146+
const SpanMarker(attribution: italicsAttribution, offset: 9, markerType: SpanMarkerType.end),
147147
],
148148
),
149149
),
@@ -162,9 +162,9 @@ This is some code
162162
spans: AttributedSpans(
163163
attributions: [
164164
const SpanMarker(attribution: boldAttribution, offset: 5, markerType: SpanMarkerType.start),
165-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
165+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
166166
const SpanMarker(attribution: italicsAttribution, offset: 5, markerType: SpanMarkerType.start),
167-
const SpanMarker(attribution: italicsAttribution, offset: 18, markerType: SpanMarkerType.end),
167+
const SpanMarker(attribution: italicsAttribution, offset: 19, markerType: SpanMarkerType.end),
168168
],
169169
),
170170
),
@@ -184,9 +184,9 @@ This is some code
184184
spans: AttributedSpans(
185185
attributions: [
186186
const SpanMarker(attribution: boldAttribution, offset: 5, markerType: SpanMarkerType.start),
187-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
187+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
188188
const SpanMarker(attribution: codeAttribution, offset: 5, markerType: SpanMarkerType.start),
189-
const SpanMarker(attribution: codeAttribution, offset: 8, markerType: SpanMarkerType.end),
189+
const SpanMarker(attribution: codeAttribution, offset: 9, markerType: SpanMarkerType.end),
190190
],
191191
),
192192
),
@@ -210,7 +210,7 @@ This is some code
210210
markerType: SpanMarkerType.start),
211211
SpanMarker(
212212
attribution: LinkAttribution(url: Uri.https('example.org', '')),
213-
offset: 18,
213+
offset: 19,
214214
markerType: SpanMarkerType.end),
215215
],
216216
),
@@ -235,10 +235,10 @@ This is some code
235235
markerType: SpanMarkerType.start),
236236
SpanMarker(
237237
attribution: LinkAttribution(url: Uri.https('example.org', '')),
238-
offset: 18,
238+
offset: 19,
239239
markerType: SpanMarkerType.end),
240240
const SpanMarker(attribution: boldAttribution, offset: 10, markerType: SpanMarkerType.start),
241-
const SpanMarker(attribution: boldAttribution, offset: 18, markerType: SpanMarkerType.end),
241+
const SpanMarker(attribution: boldAttribution, offset: 19, markerType: SpanMarkerType.end),
242242
],
243243
),
244244
),
@@ -265,7 +265,7 @@ This is some code
265265
offset: 18,
266266
markerType: SpanMarkerType.end),
267267
const SpanMarker(attribution: boldAttribution, offset: 5, markerType: SpanMarkerType.start),
268-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
268+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
269269
],
270270
),
271271
),
@@ -350,7 +350,7 @@ This is some code
350350
spans: AttributedSpans(
351351
attributions: [
352352
const SpanMarker(attribution: boldAttribution, offset: 0, markerType: SpanMarkerType.start),
353-
const SpanMarker(attribution: boldAttribution, offset: 8, markerType: SpanMarkerType.end),
353+
const SpanMarker(attribution: boldAttribution, offset: 9, markerType: SpanMarkerType.end),
354354
],
355355
),
356356
),
@@ -412,7 +412,7 @@ This is some code
412412
spans: AttributedSpans(
413413
attributions: [
414414
const SpanMarker(attribution: boldAttribution, offset: 0, markerType: SpanMarkerType.start),
415-
const SpanMarker(attribution: boldAttribution, offset: 6, markerType: SpanMarkerType.end),
415+
const SpanMarker(attribution: boldAttribution, offset: 7, markerType: SpanMarkerType.end),
416416
],
417417
),
418418
),
@@ -566,8 +566,8 @@ This is some code
566566
expect(styledText.getAllAttributionsAt(0).isEmpty, true);
567567
expect(styledText.getAllAttributionsAt(8).contains(boldAttribution), true);
568568
expect(styledText.getAllAttributionsAt(13).containsAll([boldAttribution, italicsAttribution]), true);
569-
expect(styledText.getAllAttributionsAt(19).isEmpty, true);
570-
expect(styledText.getAllAttributionsAt(40).single, LinkAttribution(url: Uri.https('example.org', '')));
569+
expect(styledText.getAllAttributionsAt(20).isEmpty, true);
570+
expect(styledText.getAllAttributionsAt(41).single, LinkAttribution(url: Uri.https('example.org', '')));
571571
});
572572

573573
test('link within multiple styles', () {

0 commit comments

Comments
 (0)