svedit 0.11.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +230 -64
- package/dist/Command.svelte.d.ts +21 -4
- package/dist/Command.svelte.d.ts.map +1 -1
- package/dist/Command.svelte.js +85 -27
- package/dist/Node.svelte +29 -1
- package/dist/Node.svelte.d.ts.map +1 -1
- package/dist/NodeArrayProperty.svelte +119 -12
- package/dist/NodeArrayProperty.svelte.d.ts.map +1 -1
- package/dist/NodeGap.svelte +48 -6
- package/dist/NodeGap.svelte.d.ts.map +1 -1
- package/dist/Session.svelte.d.ts +31 -14
- package/dist/Session.svelte.d.ts.map +1 -1
- package/dist/Session.svelte.js +155 -77
- package/dist/Svedit.svelte +110 -89
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/dist/{AnnotatedTextProperty.svelte → TextProperty.svelte} +45 -44
- package/dist/TextProperty.svelte.d.ts +7 -0
- package/dist/TextProperty.svelte.d.ts.map +1 -0
- package/dist/Transaction.svelte.d.ts +78 -40
- package/dist/Transaction.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.js +412 -234
- package/dist/doc_utils.d.ts +96 -21
- package/dist/doc_utils.d.ts.map +1 -1
- package/dist/doc_utils.js +440 -168
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node_visibility.svelte.d.ts +30 -4
- package/dist/node_visibility.svelte.d.ts.map +1 -1
- package/dist/node_visibility.svelte.js +327 -363
- package/dist/paste_utils.d.ts +3 -2
- package/dist/paste_utils.d.ts.map +1 -1
- package/dist/paste_utils.js +16 -13
- package/dist/transforms.svelte.d.ts.map +1 -1
- package/dist/transforms.svelte.js +5 -6
- package/dist/types.d.ts +112 -42
- package/dist/utils.d.ts +75 -12
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +292 -78
- package/package.json +4 -1
- package/src/lib/Command.svelte.js +85 -27
- package/src/lib/Node.svelte +29 -1
- package/src/lib/NodeArrayProperty.svelte +119 -12
- package/src/lib/NodeGap.svelte +48 -6
- package/src/lib/Session.svelte.js +155 -77
- package/src/lib/Svedit.svelte +110 -89
- package/src/lib/{AnnotatedTextProperty.svelte → TextProperty.svelte} +45 -44
- package/src/lib/Transaction.svelte.js +412 -234
- package/src/lib/doc_utils.js +440 -168
- package/src/lib/index.js +1 -1
- package/src/lib/node_visibility.svelte.js +327 -363
- package/src/lib/paste_utils.js +16 -13
- package/src/lib/transforms.svelte.js +5 -6
- package/src/lib/types.d.ts +112 -42
- package/src/lib/utils.js +292 -78
- package/dist/AnnotatedTextProperty.svelte.d.ts +0 -7
- package/dist/AnnotatedTextProperty.svelte.d.ts.map +0 -1
package/src/lib/utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @import { Annotation, AnnotatedText, SelectionRange, Selection } from './types.d.ts';
|
|
2
|
+
* @import { Attachment, Mark, Annotation, AnnotatedText, SelectionRange, Selection } from './types.d.ts';
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const SEGMENTER = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
@@ -176,110 +176,109 @@ export function char_to_utf16_offset(str, char_offset) {
|
|
|
176
176
|
/**
|
|
177
177
|
* Splits an annotated text at the specified character position.
|
|
178
178
|
*
|
|
179
|
-
*
|
|
180
|
-
* with offsets adjusted for each resulting part.
|
|
179
|
+
* Marks and annotations that span the split point will be divided
|
|
180
|
+
* appropriately, with offsets adjusted for each resulting part.
|
|
181
181
|
*
|
|
182
|
-
* @param {AnnotatedText}
|
|
182
|
+
* @param {AnnotatedText} text_value - Annotated text object
|
|
183
183
|
* @param {number} at_position - Character position where to split (0-based)
|
|
184
184
|
* @returns {[AnnotatedText, AnnotatedText]} Tuple of [left_part, right_part]
|
|
185
185
|
*
|
|
186
186
|
* @example
|
|
187
|
-
*
|
|
187
|
+
* split_text({content: "Hello world", marks: [{start_offset: 6, end_offset: 11, node_id: "strong"}], annotations: []}, 8)
|
|
188
188
|
* // Returns:
|
|
189
189
|
* // [
|
|
190
|
-
* // {
|
|
191
|
-
* // {
|
|
190
|
+
* // {content: "Hello wo", marks: [{start_offset: 6, end_offset: 8, node_id: "strong"}], annotations: []},
|
|
191
|
+
* // {content: "rld", marks: [{start_offset: 0, end_offset: 3, node_id: "strong"}], annotations: []}
|
|
192
192
|
* // ]
|
|
193
193
|
*/
|
|
194
|
-
export function
|
|
195
|
-
const {
|
|
194
|
+
export function split_text(text_value, at_position) {
|
|
195
|
+
const { content } = text_value;
|
|
196
196
|
|
|
197
197
|
// Split the text using character-aware slicing
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
node_id
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
// Annotation spans the split point - split it
|
|
220
|
-
left_annotations.push({ start_offset, end_offset: at_position, node_id });
|
|
221
|
-
right_annotations.push({ start_offset: 0, end_offset: end_offset - at_position, node_id });
|
|
198
|
+
const left = { content: char_slice(content, 0, at_position), marks: [], annotations: [] };
|
|
199
|
+
const right = { content: char_slice(content, at_position), marks: [], annotations: [] };
|
|
200
|
+
|
|
201
|
+
// Process marks and annotations with the same range logic
|
|
202
|
+
for (const key of ['marks', 'annotations']) {
|
|
203
|
+
for (const { start_offset, end_offset, node_id } of text_value[key] ?? []) {
|
|
204
|
+
if (end_offset <= at_position) {
|
|
205
|
+
// Range is entirely in the left part
|
|
206
|
+
left[key].push({ start_offset, end_offset, node_id });
|
|
207
|
+
} else if (start_offset >= at_position) {
|
|
208
|
+
// Range is entirely in the right part - shift offsets
|
|
209
|
+
right[key].push({
|
|
210
|
+
start_offset: start_offset - at_position,
|
|
211
|
+
end_offset: end_offset - at_position,
|
|
212
|
+
node_id
|
|
213
|
+
});
|
|
214
|
+
} else {
|
|
215
|
+
// Range spans the split point - split it
|
|
216
|
+
left[key].push({ start_offset, end_offset: at_position, node_id });
|
|
217
|
+
right[key].push({ start_offset: 0, end_offset: end_offset - at_position, node_id });
|
|
218
|
+
}
|
|
222
219
|
}
|
|
223
220
|
}
|
|
224
221
|
|
|
225
|
-
return [
|
|
226
|
-
{ text: left_text, annotations: left_annotations },
|
|
227
|
-
{ text: right_text, annotations: right_annotations }
|
|
228
|
-
];
|
|
222
|
+
return [left, right];
|
|
229
223
|
}
|
|
230
224
|
|
|
231
225
|
/**
|
|
232
226
|
* Joins two annotated texts into a single annotated text.
|
|
233
227
|
*
|
|
234
|
-
*
|
|
235
|
-
* of the first text. Adjacent
|
|
228
|
+
* Marks and annotations from the second text will have their offsets shifted
|
|
229
|
+
* by the length of the first text. Adjacent ranges referencing the same node
|
|
230
|
+
* will be merged.
|
|
236
231
|
*
|
|
237
232
|
* @param {AnnotatedText} first_text - First annotated text object
|
|
238
233
|
* @param {AnnotatedText} second_text - Second annotated text object
|
|
239
234
|
* @returns {AnnotatedText} Combined annotated text object
|
|
240
235
|
*
|
|
241
236
|
* @example
|
|
242
|
-
*
|
|
243
|
-
* // Returns: {
|
|
237
|
+
* join_text({content: "Hello wo", marks: [{start_offset: 6, end_offset: 8, node_id: "strong"}], annotations: []}, {content: "rld", marks: [{start_offset: 0, end_offset: 3, node_id: "strong"}], annotations: []})
|
|
238
|
+
* // Returns: {content: "Hello world", marks: [{start_offset: 6, end_offset: 11, node_id: "strong"}], annotations: []}
|
|
244
239
|
*/
|
|
245
|
-
export function
|
|
246
|
-
const { text: first_text_content, annotations: first_annotations } = first_text;
|
|
247
|
-
const { text: second_text_content, annotations: second_annotations } = second_text;
|
|
248
|
-
|
|
240
|
+
export function join_text(first_text, second_text) {
|
|
249
241
|
// Join the text content
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
// Add annotations from the second text, shifting their offsets
|
|
257
|
-
const offset = get_char_length(first_text_content);
|
|
258
|
-
for (const { start_offset, end_offset, node_id } of second_annotations) {
|
|
259
|
-
/** @type {Annotation} */
|
|
260
|
-
const shifted_annotation = {
|
|
261
|
-
start_offset: start_offset + offset,
|
|
262
|
-
end_offset: end_offset + offset,
|
|
263
|
-
node_id
|
|
264
|
-
};
|
|
242
|
+
const joined = {
|
|
243
|
+
content: first_text.content + second_text.content,
|
|
244
|
+
marks: [],
|
|
245
|
+
annotations: []
|
|
246
|
+
};
|
|
265
247
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
248
|
+
const offset = get_char_length(first_text.content);
|
|
249
|
+
|
|
250
|
+
for (const key of ['marks', 'annotations']) {
|
|
251
|
+
// Start with all ranges from the first text (unchanged)
|
|
252
|
+
const joined_ranges = (first_text[key] ?? []).map((range) => ({ ...range }));
|
|
253
|
+
|
|
254
|
+
// Add ranges from the second text, shifting their offsets
|
|
255
|
+
for (const { start_offset, end_offset, node_id } of second_text[key] ?? []) {
|
|
256
|
+
const shifted_range = {
|
|
257
|
+
start_offset: start_offset + offset,
|
|
258
|
+
end_offset: end_offset + offset,
|
|
259
|
+
node_id
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// Check if this range can be merged with the last range from the first text
|
|
263
|
+
const last_range = joined_ranges[joined_ranges.length - 1];
|
|
264
|
+
if (
|
|
265
|
+
last_range &&
|
|
266
|
+
last_range.end_offset === shifted_range.start_offset && // ranges are adjacent
|
|
267
|
+
last_range.node_id === shifted_range.node_id
|
|
268
|
+
) {
|
|
269
|
+
// same node_id
|
|
270
|
+
// Merge by extending the end position of the last range
|
|
271
|
+
last_range.end_offset = shifted_range.end_offset;
|
|
272
|
+
} else {
|
|
273
|
+
// Add as separate range
|
|
274
|
+
joined_ranges.push(shifted_range);
|
|
275
|
+
}
|
|
279
276
|
}
|
|
277
|
+
|
|
278
|
+
joined[key] = joined_ranges;
|
|
280
279
|
}
|
|
281
280
|
|
|
282
|
-
return
|
|
281
|
+
return joined;
|
|
283
282
|
}
|
|
284
283
|
|
|
285
284
|
/**
|
|
@@ -405,6 +404,51 @@ export function paths_equal(a, b) {
|
|
|
405
404
|
return a.every((segment, index) => segment === b[index]);
|
|
406
405
|
}
|
|
407
406
|
|
|
407
|
+
/**
|
|
408
|
+
* Like traverse, but returns only node ids in depth-first order and never
|
|
409
|
+
* clones nodes. Use this when only the reachable id set is needed (e.g.
|
|
410
|
+
* reference bookkeeping) — traverse() deep-clones every visited node,
|
|
411
|
+
* which is wasteful for id-only consumers.
|
|
412
|
+
*
|
|
413
|
+
* @param {string} node_id - The ID of the node to start traversing from
|
|
414
|
+
* @param {object} schema - The document schema
|
|
415
|
+
* @param {Record<string, any>} nodes - All document nodes
|
|
416
|
+
* @returns {string[]} Node ids in depth-first order (entry point last)
|
|
417
|
+
*/
|
|
418
|
+
export function traverse_ids(node_id, schema, nodes) {
|
|
419
|
+
const ids = [];
|
|
420
|
+
const visited = {};
|
|
421
|
+
const visit = (node) => {
|
|
422
|
+
if (!node || visited[node.id]) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
visited[node.id] = true;
|
|
426
|
+
for (const [property_name, value] of Object.entries(node)) {
|
|
427
|
+
const property_definition = schema[node.type].properties[property_name];
|
|
428
|
+
|
|
429
|
+
if (property_definition?.type === 'node_array') {
|
|
430
|
+
for (const v of value?.nodes || []) {
|
|
431
|
+
if (typeof v === 'string') {
|
|
432
|
+
visit(nodes[v]);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
for (const range of [...(value?.marks || []), ...(value?.annotations || [])]) {
|
|
436
|
+
visit(nodes[range.node_id]);
|
|
437
|
+
}
|
|
438
|
+
} else if (property_definition?.type === 'node') {
|
|
439
|
+
visit(nodes[value]);
|
|
440
|
+
} else if (property_definition?.type === 'text') {
|
|
441
|
+
for (const range of [...(value.marks || []), ...(value.annotations || [])]) {
|
|
442
|
+
visit(nodes[range.node_id]);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
ids.push(node.id);
|
|
447
|
+
};
|
|
448
|
+
visit(nodes[node_id]);
|
|
449
|
+
return ids;
|
|
450
|
+
}
|
|
451
|
+
|
|
408
452
|
export function traverse(node_id, schema, nodes) {
|
|
409
453
|
const json = [];
|
|
410
454
|
const visited = {};
|
|
@@ -417,16 +461,22 @@ export function traverse(node_id, schema, nodes) {
|
|
|
417
461
|
const property_definition = schema[node.type].properties[property_name];
|
|
418
462
|
|
|
419
463
|
if (property_definition?.type === 'node_array') {
|
|
420
|
-
|
|
464
|
+
const node_ids = value?.nodes || [];
|
|
465
|
+
|
|
466
|
+
for (const v of node_ids) {
|
|
421
467
|
if (typeof v === 'string') {
|
|
422
468
|
visit(nodes[v]);
|
|
423
469
|
}
|
|
424
470
|
}
|
|
471
|
+
|
|
472
|
+
for (const range of [...(value?.marks || []), ...(value?.annotations || [])]) {
|
|
473
|
+
visit(nodes[range.node_id]);
|
|
474
|
+
}
|
|
425
475
|
} else if (property_definition?.type === 'node') {
|
|
426
476
|
visit(nodes[value]);
|
|
427
|
-
} else if (property_definition?.type === '
|
|
428
|
-
for (const
|
|
429
|
-
visit(nodes[
|
|
477
|
+
} else if (property_definition?.type === 'text') {
|
|
478
|
+
for (const range of [...(value.marks || []), ...(value.annotations || [])]) {
|
|
479
|
+
visit(nodes[range.node_id]);
|
|
430
480
|
}
|
|
431
481
|
}
|
|
432
482
|
}
|
|
@@ -463,3 +513,167 @@ export function is_selection_collapsed(selection) {
|
|
|
463
513
|
return false;
|
|
464
514
|
}
|
|
465
515
|
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Adjust ranges (marks or annotations) after deleting a sequence range.
|
|
519
|
+
*
|
|
520
|
+
* Works for both annotated text (character offsets) and annotated node arrays
|
|
521
|
+
* (node offsets).
|
|
522
|
+
*
|
|
523
|
+
* @param {Array<import('./types.d.ts').Attachment>} ranges
|
|
524
|
+
* @param {number} start
|
|
525
|
+
* @param {number} end
|
|
526
|
+
* @returns {{ranges: Array<import('./types.d.ts').Attachment>, removed_node_ids: string[]}}
|
|
527
|
+
*/
|
|
528
|
+
export function adjust_ranges_for_deletion(ranges, start, end) {
|
|
529
|
+
const removed_node_ids = [];
|
|
530
|
+
const deletion_length = end - start;
|
|
531
|
+
|
|
532
|
+
const next_ranges = ranges
|
|
533
|
+
.map((range) => {
|
|
534
|
+
if (range.end_offset <= start) return range;
|
|
535
|
+
|
|
536
|
+
let start_offset = range.start_offset;
|
|
537
|
+
if (range.start_offset >= end) {
|
|
538
|
+
start_offset -= deletion_length;
|
|
539
|
+
} else if (range.start_offset > start) {
|
|
540
|
+
start_offset = start;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
let end_offset = range.end_offset;
|
|
544
|
+
if (range.end_offset >= end) {
|
|
545
|
+
end_offset -= deletion_length;
|
|
546
|
+
} else if (range.end_offset > start) {
|
|
547
|
+
end_offset = start;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (start_offset >= end_offset) {
|
|
551
|
+
removed_node_ids.push(range.node_id);
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return { start_offset, end_offset, node_id: range.node_id };
|
|
556
|
+
})
|
|
557
|
+
.filter(Boolean);
|
|
558
|
+
|
|
559
|
+
return { ranges: next_ranges, removed_node_ids };
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Adjust ranges (marks or annotations) after inserting into a sequence.
|
|
564
|
+
*
|
|
565
|
+
* Insertion inside a range extends it. Insertion exactly at either edge
|
|
566
|
+
* stays outside the range.
|
|
567
|
+
*
|
|
568
|
+
* @param {Array<import('./types.d.ts').Attachment>} ranges
|
|
569
|
+
* @param {number} offset
|
|
570
|
+
* @param {number} length
|
|
571
|
+
* @returns {Array<import('./types.d.ts').Attachment>}
|
|
572
|
+
*/
|
|
573
|
+
export function adjust_ranges_for_insertion(ranges, offset, length) {
|
|
574
|
+
if (length === 0) return ranges;
|
|
575
|
+
|
|
576
|
+
return ranges.map((range) => {
|
|
577
|
+
if (range.end_offset <= offset) return range;
|
|
578
|
+
|
|
579
|
+
if (range.start_offset < offset) {
|
|
580
|
+
return {
|
|
581
|
+
start_offset: range.start_offset,
|
|
582
|
+
end_offset: range.end_offset + length,
|
|
583
|
+
node_id: range.node_id
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return {
|
|
588
|
+
start_offset: range.start_offset + length,
|
|
589
|
+
end_offset: range.end_offset + length,
|
|
590
|
+
node_id: range.node_id
|
|
591
|
+
};
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Check whether ranges are non-empty and mutually exclusive.
|
|
597
|
+
*
|
|
598
|
+
* @param {Array<import('./types.d.ts').Attachment>} ranges
|
|
599
|
+
* @param {number} [length]
|
|
600
|
+
* @returns {boolean}
|
|
601
|
+
*/
|
|
602
|
+
export function are_ranges_exclusive(ranges, length = Infinity) {
|
|
603
|
+
const sorted = [...ranges].sort(
|
|
604
|
+
(a, b) => a.start_offset - b.start_offset || a.end_offset - b.end_offset
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
return sorted.every(
|
|
608
|
+
(range, index) =>
|
|
609
|
+
Number.isInteger(range.start_offset) &&
|
|
610
|
+
Number.isInteger(range.end_offset) &&
|
|
611
|
+
range.start_offset >= 0 &&
|
|
612
|
+
range.start_offset < range.end_offset &&
|
|
613
|
+
range.end_offset <= length &&
|
|
614
|
+
(index === 0 || range.start_offset >= sorted[index - 1].end_offset)
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Calculates abstract fragment ranges from a length and marks.
|
|
620
|
+
*
|
|
621
|
+
* @param {number} length - Length of the sequence (e.g. text length or array length)
|
|
622
|
+
* @param {Array<import('./types.d.ts').Mark>} marks - Array of marks
|
|
623
|
+
* @param {import('./types.d.ts').SelectionRange} [selection_highlight_range] - Optional selection highlight range
|
|
624
|
+
* @returns {Array<{type: 'content' | 'mark' | 'selection_highlight', start_offset: number, end_offset: number, mark_index?: number, node_id?: string}>}
|
|
625
|
+
*/
|
|
626
|
+
export function calculate_fragment_ranges(length, marks, selection_highlight_range) {
|
|
627
|
+
/** @type {Array<{type: 'content' | 'mark' | 'selection_highlight', start_offset: number, end_offset: number, mark_index?: number, node_id?: string}>} */
|
|
628
|
+
const fragments = [];
|
|
629
|
+
let last_index = 0;
|
|
630
|
+
|
|
631
|
+
// Merge marks with selection highlight and sort by start offset
|
|
632
|
+
const ranges = [...marks, ...(selection_highlight_range ? [selection_highlight_range] : [])].sort(
|
|
633
|
+
(a, b) => a.start_offset - b.start_offset
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
for (const range of ranges) {
|
|
637
|
+
// Add content before this range
|
|
638
|
+
if (range.start_offset > last_index) {
|
|
639
|
+
fragments.push({
|
|
640
|
+
type: 'content',
|
|
641
|
+
start_offset: last_index,
|
|
642
|
+
end_offset: range.start_offset
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if ('node_id' in range) {
|
|
647
|
+
const mark = /** @type {import('./types.d.ts').Mark} */ (range);
|
|
648
|
+
const mark_index =
|
|
649
|
+
/** @type {import('./types.d.ts').Mark & { mark_index?: number }} */ (mark).mark_index ??
|
|
650
|
+
marks.indexOf(mark);
|
|
651
|
+
fragments.push({
|
|
652
|
+
type: 'mark',
|
|
653
|
+
start_offset: mark.start_offset,
|
|
654
|
+
end_offset: mark.end_offset,
|
|
655
|
+
node_id: mark.node_id,
|
|
656
|
+
mark_index
|
|
657
|
+
});
|
|
658
|
+
} else {
|
|
659
|
+
fragments.push({
|
|
660
|
+
type: 'selection_highlight',
|
|
661
|
+
start_offset: range.start_offset,
|
|
662
|
+
end_offset: range.end_offset
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
last_index = range.end_offset;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Add any remaining content
|
|
670
|
+
if (last_index < length) {
|
|
671
|
+
fragments.push({
|
|
672
|
+
type: 'content',
|
|
673
|
+
start_offset: last_index,
|
|
674
|
+
end_offset: length
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return fragments;
|
|
679
|
+
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export default AnnotatedTextProperty;
|
|
2
|
-
type AnnotatedTextProperty = {
|
|
3
|
-
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
-
$set?(props: Partial<AnnotatedTextPropertyProps>): void;
|
|
5
|
-
};
|
|
6
|
-
declare const AnnotatedTextProperty: import("svelte").Component<import("./types.d.ts").AnnotatedTextPropertyProps, {}, "">;
|
|
7
|
-
//# sourceMappingURL=AnnotatedTextProperty.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnnotatedTextProperty.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AnnotatedTextProperty.svelte.js"],"names":[],"mappings":";;;;;AAwIA,2HAAoE"}
|