svedit 0.3.0 → 0.4.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 +39 -21
- package/dist/{AnnotatedStringProperty.svelte → AnnotatedTextProperty.svelte} +28 -40
- package/dist/AnnotatedTextProperty.svelte.d.ts +7 -0
- package/dist/AnnotatedTextProperty.svelte.d.ts.map +1 -0
- package/dist/Document.svelte.d.ts +39 -16
- package/dist/Document.svelte.d.ts.map +1 -1
- package/dist/Document.svelte.js +192 -80
- package/dist/Svedit.svelte +149 -97
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.d.ts +4 -4
- package/dist/Transaction.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.js +60 -77
- package/dist/commands.svelte.d.ts.map +1 -1
- package/dist/commands.svelte.js +18 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +66 -21
- package/dist/util.d.ts +16 -16
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +33 -34
- package/package.json +1 -1
- package/src/lib/{AnnotatedStringProperty.svelte → AnnotatedTextProperty.svelte} +28 -40
- package/src/lib/Document.svelte.js +192 -80
- package/src/lib/Svedit.svelte +149 -97
- package/src/lib/Transaction.svelte.js +60 -77
- package/src/lib/commands.svelte.js +18 -10
- package/src/lib/index.js +1 -1
- package/src/lib/types.d.ts +66 -21
- package/src/lib/util.js +33 -34
- package/dist/AnnotatedStringProperty.svelte.d.ts +0 -7
- package/dist/AnnotatedStringProperty.svelte.d.ts.map +0 -1
package/dist/Svedit.svelte
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
editable = $bindable(false),
|
|
11
11
|
path,
|
|
12
12
|
class: css_class,
|
|
13
|
+
autocapitalize = "on",
|
|
14
|
+
spellcheck = "true",
|
|
13
15
|
} = $props();
|
|
14
16
|
|
|
15
17
|
let canvas_ref;
|
|
@@ -27,13 +29,26 @@
|
|
|
27
29
|
// Detect Chrome on desktop (not mobile) - only available in browser
|
|
28
30
|
let is_chrome_desktop = $state(false);
|
|
29
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Detect if the current browser is on a mobile device
|
|
34
|
+
* @returns {boolean} true if mobile browser, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
function is_mobile_browser() {
|
|
37
|
+
if (typeof window === 'undefined' || typeof navigator === 'undefined') {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const user_agent = navigator.userAgent;
|
|
42
|
+
return /iPhone|iPad|iPod|Android|Mobile/i.test(user_agent) ||
|
|
43
|
+
('ontouchstart' in window) ||
|
|
44
|
+
(navigator.maxTouchPoints > 0);
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
$effect(() => {
|
|
31
48
|
if (typeof window !== 'undefined' && typeof navigator !== 'undefined') {
|
|
32
49
|
const user_agent = navigator.userAgent;
|
|
33
50
|
const is_chrome = user_agent.includes('Chrome') && !user_agent.includes('Edg');
|
|
34
|
-
const is_mobile =
|
|
35
|
-
('ontouchstart' in window) ||
|
|
36
|
-
(navigator.maxTouchPoints > 0);
|
|
51
|
+
const is_mobile = is_mobile_browser();
|
|
37
52
|
is_chrome_desktop = is_chrome && !is_mobile;
|
|
38
53
|
}
|
|
39
54
|
});
|
|
@@ -86,7 +101,7 @@
|
|
|
86
101
|
|
|
87
102
|
function commit_input() {
|
|
88
103
|
if (input_selection?.type !== 'text') return;
|
|
89
|
-
const model_text = doc.get(input_selection.path)
|
|
104
|
+
const model_text = doc.get(input_selection.path).text;
|
|
90
105
|
const dom_text_element = document.querySelector(`[data-path="${input_selection.path.join('.')}"]`);
|
|
91
106
|
const dom_text = dom_text_element.textContent;
|
|
92
107
|
const op = diff_text(model_text, dom_text);
|
|
@@ -142,25 +157,98 @@
|
|
|
142
157
|
|
|
143
158
|
// Only take input when in a valid text selection inside the canvas
|
|
144
159
|
if (
|
|
145
|
-
!(canvas_ref?.contains(document.activeElement))
|
|
146
|
-
(doc.selection?.type !== 'text')
|
|
160
|
+
!(canvas_ref?.contains(document.activeElement))
|
|
147
161
|
) {
|
|
148
162
|
event.preventDefault();
|
|
149
163
|
return;
|
|
150
164
|
}
|
|
151
165
|
|
|
152
|
-
if (event.inputType === 'formatBold') {
|
|
166
|
+
if (event.inputType === 'formatBold' && doc.selection?.type === 'text') {
|
|
153
167
|
doc.apply(doc.tr.annotate_text('strong'));
|
|
154
168
|
event.preventDefault();
|
|
155
169
|
event.stopPropagation();
|
|
156
170
|
}
|
|
157
171
|
|
|
158
|
-
if (event.inputType === 'formatItalic') {
|
|
172
|
+
if (event.inputType === 'formatItalic' && doc.selection?.type === 'text') {
|
|
159
173
|
doc.apply(doc.tr.annotate_text('emphasis'));
|
|
160
174
|
event.preventDefault();
|
|
161
175
|
event.stopPropagation();
|
|
162
176
|
}
|
|
163
177
|
|
|
178
|
+
// NOTE: underline doesn't make much sense as a semantic annotation,
|
|
179
|
+
// so we rewire `cmd + u` to toggle highlights
|
|
180
|
+
if (event.inputType === 'formatUnderline' && doc.selection?.type === 'text') {
|
|
181
|
+
doc.apply(doc.tr.annotate_text('highlight'));
|
|
182
|
+
event.preventDefault();
|
|
183
|
+
event.stopPropagation();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
if (event.inputType === 'deleteContentBackward') {
|
|
188
|
+
if (doc.selection?.type === 'property') {
|
|
189
|
+
// For property selections, clear the property value only if it's not already falsy
|
|
190
|
+
if (doc.get(doc.selection.path)) {
|
|
191
|
+
const tr = doc.tr;
|
|
192
|
+
tr.set(doc.selection.path, '');
|
|
193
|
+
doc.apply(tr);
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
if (doc.selection?.type === 'text' && doc.selection?.anchor_offset === 0 && doc.selection?.focus_offset === 0) {
|
|
197
|
+
const tr = doc.tr;
|
|
198
|
+
join_text_node(tr);
|
|
199
|
+
doc.apply(tr);
|
|
200
|
+
} else {
|
|
201
|
+
doc.apply(doc.tr.delete_selection());
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
event.preventDefault();
|
|
206
|
+
event.stopPropagation();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (event.inputType === 'deleteContentForward') {
|
|
210
|
+
// Forward delete: only handle collapsed text selections
|
|
211
|
+
if (doc.selection?.type === 'text' && doc.selection?.anchor_offset === doc.selection?.focus_offset) {
|
|
212
|
+
const text_content = doc.get(doc.selection.path).text;
|
|
213
|
+
const text_length = get_char_length(text_content);
|
|
214
|
+
|
|
215
|
+
if (doc.selection.focus_offset < text_length) {
|
|
216
|
+
// There's a character after the cursor - select and delete it
|
|
217
|
+
const tr = doc.tr;
|
|
218
|
+
tr.set_selection({
|
|
219
|
+
type: 'text',
|
|
220
|
+
path: [...doc.selection.path],
|
|
221
|
+
anchor_offset: doc.selection.focus_offset,
|
|
222
|
+
focus_offset: doc.selection.focus_offset + 1
|
|
223
|
+
});
|
|
224
|
+
tr.delete_selection();
|
|
225
|
+
doc.apply(tr);
|
|
226
|
+
} else {
|
|
227
|
+
// At end of text - try to join with next text node
|
|
228
|
+
const tr = doc.tr;
|
|
229
|
+
const node_index = parseInt(String(doc.selection.path.at(-2)), 10);
|
|
230
|
+
const successor_node = doc.get([...doc.selection.path.slice(0, -2), node_index + 1]);
|
|
231
|
+
|
|
232
|
+
// Check if next node is a text node
|
|
233
|
+
if (successor_node && doc.kind(successor_node) === 'text') {
|
|
234
|
+
// Set selection to beginning of next text node
|
|
235
|
+
tr.set_selection({
|
|
236
|
+
type: 'text',
|
|
237
|
+
path: [...doc.selection.path.slice(0, -2), node_index + 1, 'content'],
|
|
238
|
+
anchor_offset: 0,
|
|
239
|
+
focus_offset: 0
|
|
240
|
+
});
|
|
241
|
+
// Use join_text_node to merge with previous
|
|
242
|
+
join_text_node(tr);
|
|
243
|
+
doc.apply(tr);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
event.preventDefault();
|
|
249
|
+
event.stopPropagation();
|
|
250
|
+
}
|
|
251
|
+
|
|
164
252
|
|
|
165
253
|
// We remember the "input selection", because in some mobile browsers (Samsung Android) the onbeforeinput event
|
|
166
254
|
// is fired on a different selection than the input event.
|
|
@@ -302,9 +390,9 @@ ${fallback_html}`;
|
|
|
302
390
|
for (const [prop_name, prop_value] of Object.entries(node)) {
|
|
303
391
|
if (prop_name === 'id' || prop_name === 'type') continue;
|
|
304
392
|
|
|
305
|
-
// Check if this is an
|
|
306
|
-
if (
|
|
307
|
-
const text_content = prop_value
|
|
393
|
+
// Check if this is an annotated_text property (object with text property)
|
|
394
|
+
if (typeof prop_value === 'object' && prop_value !== null && typeof prop_value.text === 'string') {
|
|
395
|
+
const text_content = prop_value.text;
|
|
308
396
|
if (text_content.trim()) {
|
|
309
397
|
html += `<p>${text_content}</p>\n`;
|
|
310
398
|
has_content = true;
|
|
@@ -313,7 +401,7 @@ ${fallback_html}`;
|
|
|
313
401
|
}
|
|
314
402
|
|
|
315
403
|
if (!has_content) {
|
|
316
|
-
// Generic fallback for unknown node types with no
|
|
404
|
+
// Generic fallback for unknown node types with no annotated_text content
|
|
317
405
|
html += `<div data-node-type="${node.type}">Content from ${node.type}</div>\n`;
|
|
318
406
|
}
|
|
319
407
|
|
|
@@ -389,7 +477,7 @@ ${fallback_html}`;
|
|
|
389
477
|
|
|
390
478
|
console.log('Copy operation:', {
|
|
391
479
|
selected_nodes,
|
|
392
|
-
|
|
480
|
+
nodes,
|
|
393
481
|
total_nodes: Object.keys(nodes).length,
|
|
394
482
|
operation: delete_selection ? 'cut' : 'copy'
|
|
395
483
|
});
|
|
@@ -453,8 +541,6 @@ ${fallback_html}`;
|
|
|
453
541
|
pasted_json = undefined;
|
|
454
542
|
}
|
|
455
543
|
|
|
456
|
-
|
|
457
|
-
|
|
458
544
|
if (pasted_json) {
|
|
459
545
|
const tr = doc.tr;
|
|
460
546
|
|
|
@@ -478,12 +564,18 @@ ${fallback_html}`;
|
|
|
478
564
|
for (const [property, value] of Object.entries(new_node)) {
|
|
479
565
|
if (property === 'id' || property === 'type') continue;
|
|
480
566
|
|
|
481
|
-
const prop_type = doc.schema[node.type]?.[property]?.type;
|
|
567
|
+
const prop_type = doc.schema[node.type]?.properties?.[property]?.type;
|
|
482
568
|
|
|
483
569
|
if (prop_type === 'node_array' && Array.isArray(value)) {
|
|
484
570
|
new_node[property] = value.map(ref_id => id_mapping[ref_id] || ref_id);
|
|
485
571
|
} else if (prop_type === 'node' && typeof value === 'string') {
|
|
486
572
|
new_node[property] = id_mapping[value] || value;
|
|
573
|
+
} else if (prop_type === 'annotated_text') {
|
|
574
|
+
const annotations = value.annotations.map(annotation => {
|
|
575
|
+
const {start_offset, end_offset, node_id} = annotation;
|
|
576
|
+
return {start_offset, end_offset, node_id: id_mapping[node_id] || node_id};
|
|
577
|
+
});
|
|
578
|
+
new_node[property] = {text: value.text, annotations};
|
|
487
579
|
}
|
|
488
580
|
}
|
|
489
581
|
|
|
@@ -588,37 +680,39 @@ ${fallback_html}`;
|
|
|
588
680
|
const is_collapsed = selection?.anchor_offset === selection?.focus_offset;
|
|
589
681
|
|
|
590
682
|
if (
|
|
591
|
-
(e.key === 'ArrowRight' && e.altKey && e.ctrlKey && doc.
|
|
592
|
-
(e.key === 'ArrowRight' && e.altKey && e.ctrlKey && e.shiftKey && doc.
|
|
683
|
+
(e.key === 'ArrowRight' && e.altKey && e.ctrlKey && doc.layout_node) ||
|
|
684
|
+
(e.key === 'ArrowRight' && e.altKey && e.ctrlKey && e.shiftKey && doc.layout_node)
|
|
593
685
|
) {
|
|
594
|
-
const node = doc.
|
|
686
|
+
const node = doc.layout_node;
|
|
595
687
|
const layout_count = doc.config.node_layouts[node.type];
|
|
596
688
|
|
|
597
689
|
if (layout_count > 1 && node?.layout) {
|
|
598
690
|
const next_layout = (node.layout % layout_count) + 1;
|
|
599
691
|
console.log('layout / count / next_layout', node.layout, layout_count, next_layout);
|
|
600
692
|
const tr = doc.tr;
|
|
601
|
-
tr.set([doc.
|
|
693
|
+
tr.set([doc.layout_node?.id, 'layout'], next_layout);
|
|
602
694
|
doc.apply(tr);
|
|
603
695
|
}
|
|
696
|
+
e.preventDefault();
|
|
604
697
|
} else if (
|
|
605
|
-
(e.key === 'ArrowLeft' && e.altKey && e.ctrlKey && doc.
|
|
606
|
-
(e.key === 'ArrowLeft' && e.altKey && e.ctrlKey && e.shiftKey && doc.
|
|
698
|
+
(e.key === 'ArrowLeft' && e.altKey && e.ctrlKey && doc.layout_node) ||
|
|
699
|
+
(e.key === 'ArrowLeft' && e.altKey && e.ctrlKey && e.shiftKey && doc.layout_node)
|
|
607
700
|
) {
|
|
608
|
-
const node = doc.
|
|
701
|
+
const node = doc.layout_node;
|
|
609
702
|
const layout_count = doc.config.node_layouts[node.type];
|
|
610
703
|
if (layout_count > 1 && node?.layout) {
|
|
611
704
|
const prev_layout = ((node.layout - 2 + layout_count) % layout_count) + 1;
|
|
612
705
|
const tr = doc.tr;
|
|
613
|
-
tr.set([doc.
|
|
706
|
+
tr.set([doc.layout_node?.id, 'layout'], prev_layout);
|
|
614
707
|
doc.apply(tr);
|
|
615
708
|
console.log('layout / count / prev_layout', node.layout, layout_count, prev_layout);
|
|
616
709
|
}
|
|
710
|
+
e.preventDefault();
|
|
617
711
|
} else if (
|
|
618
|
-
(e.key === 'ArrowDown' && e.altKey && e.ctrlKey && doc.
|
|
619
|
-
(e.key === 'ArrowDown' && e.altKey && e.ctrlKey && e.shiftKey && doc.
|
|
712
|
+
(e.key === 'ArrowDown' && e.altKey && e.ctrlKey && doc.layout_node) ||
|
|
713
|
+
(e.key === 'ArrowDown' && e.altKey && e.ctrlKey && e.shiftKey && doc.layout_node )
|
|
620
714
|
) {
|
|
621
|
-
const node = doc.
|
|
715
|
+
const node = doc.layout_node;
|
|
622
716
|
|
|
623
717
|
if (doc.selection.type !== 'node') {
|
|
624
718
|
doc.select_parent();
|
|
@@ -636,11 +730,12 @@ ${fallback_html}`;
|
|
|
636
730
|
doc.config.inserters[next_type](tr);
|
|
637
731
|
tr.set_selection(old_selection);
|
|
638
732
|
doc.apply(tr);
|
|
733
|
+
e.preventDefault();
|
|
639
734
|
} else if (
|
|
640
|
-
(e.key === 'ArrowUp' && e.altKey && e.ctrlKey && doc.
|
|
641
|
-
(e.key === 'ArrowUp' && e.altKey && e.ctrlKey && e.shiftKey && doc.
|
|
735
|
+
(e.key === 'ArrowUp' && e.altKey && e.ctrlKey && doc.layout_node) ||
|
|
736
|
+
(e.key === 'ArrowUp' && e.altKey && e.ctrlKey && e.shiftKey && doc.layout_node)
|
|
642
737
|
) {
|
|
643
|
-
const node = doc.
|
|
738
|
+
const node = doc.layout_node;
|
|
644
739
|
|
|
645
740
|
if (doc.selection.type !== 'node') {
|
|
646
741
|
doc.select_parent();
|
|
@@ -660,6 +755,7 @@ ${fallback_html}`;
|
|
|
660
755
|
doc.config.inserters[prev_type](tr);
|
|
661
756
|
tr.set_selection(old_selection);
|
|
662
757
|
doc.apply(tr);
|
|
758
|
+
e.preventDefault();
|
|
663
759
|
|
|
664
760
|
} else if (e.key === 'a' && (e.metaKey || e.ctrlKey)) {
|
|
665
761
|
const tr = doc.tr;
|
|
@@ -676,76 +772,32 @@ ${fallback_html}`;
|
|
|
676
772
|
doc.redo();
|
|
677
773
|
e.preventDefault();
|
|
678
774
|
e.stopPropagation();
|
|
679
|
-
} else if (e.key === 'Enter' && (e.shiftKey)) {
|
|
775
|
+
} else if (e.key === 'Enter' && (e.shiftKey) && !is_mobile_browser() && selection?.type === 'text' && doc.inspect(selection.path).allow_newlines) {
|
|
680
776
|
doc.apply(doc.tr.insert_text('\n'));
|
|
681
777
|
e.preventDefault();
|
|
682
778
|
e.stopPropagation();
|
|
683
|
-
} else if (e.key === '
|
|
684
|
-
doc.apply(doc.tr.annotate_text('
|
|
685
|
-
href: window.prompt('Enter the URL', 'https://example.com')
|
|
686
|
-
}));
|
|
779
|
+
} else if (e.key === 'b' && (e.ctrlKey || e.metaKey) && selection?.type === 'text') {
|
|
780
|
+
doc.apply(doc.tr.annotate_text('strong'));
|
|
687
781
|
e.preventDefault();
|
|
688
782
|
e.stopPropagation();
|
|
689
|
-
} else if (e.key === '
|
|
690
|
-
|
|
691
|
-
// For property selections, clear the property value only if it's not already falsy
|
|
692
|
-
if (doc.get(selection.path)) {
|
|
693
|
-
const tr = doc.tr;
|
|
694
|
-
tr.set(selection.path, '');
|
|
695
|
-
doc.apply(tr);
|
|
696
|
-
}
|
|
697
|
-
} else {
|
|
698
|
-
if (doc.selection?.type === 'text' && doc.selection?.anchor_offset === 0 && doc.selection?.focus_offset === 0) {
|
|
699
|
-
const tr = doc.tr;
|
|
700
|
-
join_text_node(tr);
|
|
701
|
-
doc.apply(tr);
|
|
702
|
-
} else {
|
|
703
|
-
// TODO: Things are not yet properly composable, I think we need to
|
|
704
|
-
// realize delete_selection as a command as well.
|
|
705
|
-
// See https://prosemirror.net/docs/guide/#commands for inspiration.
|
|
706
|
-
// For other selections, use the normal delete behavior
|
|
707
|
-
doc.apply(doc.tr.delete_selection());
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
783
|
+
} else if (e.key === 'i' && (e.ctrlKey || e.metaKey) && selection?.type === 'text') {
|
|
784
|
+
doc.apply(doc.tr.annotate_text('emphasis'));
|
|
711
785
|
e.preventDefault();
|
|
712
786
|
e.stopPropagation();
|
|
713
|
-
} else if (e.key === '
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
});
|
|
728
|
-
tr.delete_selection();
|
|
729
|
-
doc.apply(tr);
|
|
730
|
-
} else {
|
|
731
|
-
// At end of text - try to join with next text node
|
|
732
|
-
const tr = doc.tr;
|
|
733
|
-
const node_index = parseInt(selection.path.at(-2), 10);
|
|
734
|
-
const successor_node = doc.get([...selection.path.slice(0, -2), node_index + 1]);
|
|
735
|
-
|
|
736
|
-
// Check if next node is a text node
|
|
737
|
-
if (successor_node && doc.kind(successor_node) === 'text') {
|
|
738
|
-
// Set selection to beginning of next text node
|
|
739
|
-
tr.set_selection({
|
|
740
|
-
type: 'text',
|
|
741
|
-
path: [...selection.path.slice(0, -2), node_index + 1, 'content'],
|
|
742
|
-
anchor_offset: 0,
|
|
743
|
-
focus_offset: 0
|
|
744
|
-
});
|
|
745
|
-
// Use join_text_node to merge with previous
|
|
746
|
-
join_text_node(tr);
|
|
747
|
-
doc.apply(tr);
|
|
748
|
-
}
|
|
787
|
+
} else if (e.key === 'u' && (e.ctrlKey || e.metaKey) && selection?.type === 'text') {
|
|
788
|
+
doc.apply(doc.tr.annotate_text('highlight'));
|
|
789
|
+
e.preventDefault();
|
|
790
|
+
e.stopPropagation();
|
|
791
|
+
} else if (e.key === 'k' && (e.ctrlKey || e.metaKey)) {
|
|
792
|
+
const has_link = doc.active_annotation('link');
|
|
793
|
+
if (has_link) {
|
|
794
|
+
// Delete link
|
|
795
|
+
doc.apply(doc.tr.annotate_text('link'));
|
|
796
|
+
} else {
|
|
797
|
+
// Create link
|
|
798
|
+
const href = window.prompt('Enter the URL', 'https://example.com');
|
|
799
|
+
if (href) {
|
|
800
|
+
doc.apply(doc.tr.annotate_text('link', { href }));
|
|
749
801
|
}
|
|
750
802
|
}
|
|
751
803
|
|
|
@@ -1023,7 +1075,7 @@ ${fallback_html}`;
|
|
|
1023
1075
|
// 2. Last child node is a <br> (the visual representation of that \n)
|
|
1024
1076
|
// 3. Cursor is positioned at or near the end
|
|
1025
1077
|
// And returns the correct text.length position instead.
|
|
1026
|
-
const text_content = doc.get(path)
|
|
1078
|
+
const text_content = doc.get(path).text;
|
|
1027
1079
|
const text_length = get_char_length(text_content);
|
|
1028
1080
|
if (text_length > 0) {
|
|
1029
1081
|
const last_char = get_char_at(text_content, text_length - 1);
|
|
@@ -1208,7 +1260,7 @@ ${fallback_html}`;
|
|
|
1208
1260
|
const selection = /** @type {any} */ (doc.selection);
|
|
1209
1261
|
// The element that holds the annotated string
|
|
1210
1262
|
const el = canvas_ref.querySelector(`[data-path="${selection.path.join('.')}"][data-type="text"]`);
|
|
1211
|
-
const empty_text = doc.get(selection.path)
|
|
1263
|
+
const empty_text = doc.get(selection.path).text.length === 0;
|
|
1212
1264
|
|
|
1213
1265
|
const range = window.document.createRange();
|
|
1214
1266
|
const dom_selection = window.getSelection();
|
|
@@ -1385,8 +1437,8 @@ ${fallback_html}`;
|
|
|
1385
1437
|
{oncompositionstart}
|
|
1386
1438
|
{oncompositionend}
|
|
1387
1439
|
contenteditable={editable ? 'true' : 'false'}
|
|
1388
|
-
autocapitalize
|
|
1389
|
-
spellcheck
|
|
1440
|
+
{autocapitalize}
|
|
1441
|
+
{spellcheck}
|
|
1390
1442
|
{...{
|
|
1391
1443
|
// NOTE: Autocomplete and autocorrect make immense troubles
|
|
1392
1444
|
// on Desktop Chrome, so we disable them only for Chrome desktop.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Svedit.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Svedit.svelte.js"],"names":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"Svedit.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Svedit.svelte.js"],"names":[],"mappings":";;;;;;;AAo6CA;;eAAqD;iCAx5CgE,cAAc"}
|
|
@@ -51,7 +51,7 @@ export default class Transaction {
|
|
|
51
51
|
* @example
|
|
52
52
|
* ```js
|
|
53
53
|
* tr.set(["list_1", "list_items"], [1, 2, 3]);
|
|
54
|
-
* tr.set(["page_1", "body", "0", "description"],
|
|
54
|
+
* tr.set(["page_1", "body", "0", "description"], {text: "Hello world", annotations: []});
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
57
|
set(path: DocumentPath, value: any): void;
|
|
@@ -94,7 +94,7 @@ export default class Transaction {
|
|
|
94
94
|
*
|
|
95
95
|
* @param {Selection} selection - The new selection object
|
|
96
96
|
* @returns {Transaction} This transaction instance for method chaining
|
|
97
|
-
* @
|
|
97
|
+
* @throws {Error} Throws if the selection is invalid or out of bounds
|
|
98
98
|
*/
|
|
99
99
|
set_selection(selection: Selection): Transaction;
|
|
100
100
|
/**
|
|
@@ -105,7 +105,7 @@ export default class Transaction {
|
|
|
105
105
|
* when conflicting types are applied.
|
|
106
106
|
*
|
|
107
107
|
* @param {any} annotation_type - The type of annotation (e.g., 'link', 'bold', 'italic')
|
|
108
|
-
* @param {any}
|
|
108
|
+
* @param {any} annotation_properties - Additional data for the annotation (e.g., href for links)
|
|
109
109
|
* @returns {Transaction} This transaction instance for method chaining
|
|
110
110
|
*
|
|
111
111
|
* @example
|
|
@@ -117,7 +117,7 @@ export default class Transaction {
|
|
|
117
117
|
* tr.annotate_text('emphasis', {});
|
|
118
118
|
* ```
|
|
119
119
|
*/
|
|
120
|
-
annotate_text(annotation_type: any,
|
|
120
|
+
annotate_text(annotation_type: any, annotation_properties: any): Transaction;
|
|
121
121
|
/**
|
|
122
122
|
* Deletes the currently selected text or nodes.
|
|
123
123
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Transaction.svelte.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH;IACE;;;;OAIG;IACH,iBAFW,GAAG,EAWb;IARC,SAAc;IAEd,oCAAoC;IACpC,KADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CACnB;IACb,oCAAoC;IACpC,aADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CACX;IAErB,sBAA0C;IAG5C;;;;;OAKG;IACH,UAHW,YAAY,GACV,GAAG,CAIf;IAED;;;;OAIG;IACH,iBAFa,SAAS,CAIrB;IAED;;;;;;;;;;;;;;OAcG;IACH,UATW,YAAY,SACZ,GAAG,QA2Bb;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAbW,GAAG,GACD,WAAW,CAyBvB;IAED;;;;;;;;;;;;OAYG;IACH,WARW,GAAG,GACD,WAAW,CAcvB;IAED;;;;;;OAMG;IACH,yBAJW,SAAS,GACP,WAAW,CAOvB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,+BAbW,GAAG,
|
|
1
|
+
{"version":3,"file":"Transaction.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Transaction.svelte.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH;IACE;;;;OAIG;IACH,iBAFW,GAAG,EAWb;IARC,SAAc;IAEd,oCAAoC;IACpC,KADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CACnB;IACb,oCAAoC;IACpC,aADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CACX;IAErB,sBAA0C;IAG5C;;;;;OAKG;IACH,UAHW,YAAY,GACV,GAAG,CAIf;IAED;;;;OAIG;IACH,iBAFa,SAAS,CAIrB;IAED;;;;;;;;;;;;;;OAcG;IACH,UATW,YAAY,SACZ,GAAG,QA2Bb;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAbW,GAAG,GACD,WAAW,CAyBvB;IAED;;;;;;;;;;;;OAYG;IACH,WARW,GAAG,GACD,WAAW,CAcvB;IAED;;;;;;OAMG;IACH,yBAJW,SAAS,GACP,WAAW,CAOvB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,+BAbW,GAAG,yBACH,GAAG,GACD,WAAW,CAuDvB;IAED;;;;;;;;;OASG;IACH,oBAFa,WAAW,CAyGvB;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,oBAbW,cAAc,EAAE,GACd,WAAW,CAqDvB;IAED;;;;;;;;;;;;;;;OAeG;IACH,2BAVW,MAAM,GACJ,WAAW,CA8EvB;IAED;;;;;;;;OAQG;IACH,2CA+BC;IAED;;;;;;;;;;OAUG;IACH,4CAuBC;CACF;kCAxjBmE,YAAY;+BAAZ,YAAY;oCAAZ,YAAY"}
|