svedit 0.6.0 → 0.6.1
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/dist/AnnotatedTextProperty.svelte +18 -12
- package/dist/AnnotatedTextProperty.svelte.d.ts.map +1 -1
- package/dist/Svedit.svelte +22 -36
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/lib/AnnotatedTextProperty.svelte +18 -12
- package/src/lib/Svedit.svelte +22 -36
|
@@ -16,8 +16,18 @@
|
|
|
16
16
|
);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
let plain_text = $derived(svedit.session.get(path).text);
|
|
20
|
+
let is_empty = $derived(
|
|
21
|
+
get_char_length(plain_text) === 0 && !(svedit.is_composing && is_focused)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
let is_collapsed = $derived(
|
|
25
|
+
is_focused && svedit.session.selection?.anchor_offset == svedit.session.selection?.focus_offset
|
|
26
|
+
);
|
|
27
|
+
|
|
19
28
|
// Get selection highlight range if not inside an annotation
|
|
20
29
|
let selection_highlight_range = $derived.by(() => {
|
|
30
|
+
if (is_collapsed) return null;
|
|
21
31
|
if (!is_focused) return null;
|
|
22
32
|
if (svedit.session.active_annotation()) return null;
|
|
23
33
|
const sel = svedit.session.selection;
|
|
@@ -25,6 +35,14 @@
|
|
|
25
35
|
return get_selection_range(sel);
|
|
26
36
|
});
|
|
27
37
|
|
|
38
|
+
let fragments = $derived(
|
|
39
|
+
get_fragments(
|
|
40
|
+
svedit.session.get(path).text,
|
|
41
|
+
svedit.session.get(path).annotations,
|
|
42
|
+
selection_highlight_range
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
|
|
28
46
|
/**
|
|
29
47
|
* Converts text with annotations into renderable fragments for display.
|
|
30
48
|
* @param {string} text - The plain text content
|
|
@@ -78,18 +96,6 @@
|
|
|
78
96
|
|
|
79
97
|
return fragments;
|
|
80
98
|
}
|
|
81
|
-
|
|
82
|
-
let fragments = $derived(
|
|
83
|
-
get_fragments(
|
|
84
|
-
svedit.session.get(path).text,
|
|
85
|
-
svedit.session.get(path).annotations,
|
|
86
|
-
selection_highlight_range
|
|
87
|
-
)
|
|
88
|
-
);
|
|
89
|
-
let plain_text = $derived(svedit.session.get(path).text);
|
|
90
|
-
let is_empty = $derived(
|
|
91
|
-
get_char_length(plain_text) === 0 && !(svedit.is_composing && is_focused)
|
|
92
|
-
);
|
|
93
99
|
</script>
|
|
94
100
|
|
|
95
101
|
<!-- ATTENTION: The comments are needed to prevent unwanted text nodes with whitespace. -->
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnnotatedTextProperty.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AnnotatedTextProperty.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"AnnotatedTextProperty.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AnnotatedTextProperty.svelte.js"],"names":[],"mappings":";;;;;AA6HA,2HAAoE"}
|
package/dist/Svedit.svelte
CHANGED
|
@@ -68,7 +68,9 @@
|
|
|
68
68
|
const key_mapper = getContext('key_mapper');
|
|
69
69
|
|
|
70
70
|
// Initialize commands and keymap on the session
|
|
71
|
-
|
|
71
|
+
$effect(() => {
|
|
72
|
+
session.initialize_commands(context);
|
|
73
|
+
});
|
|
72
74
|
|
|
73
75
|
// Handle focus - push session's keymap onto stack
|
|
74
76
|
function handle_canvas_focus() {
|
|
@@ -977,8 +979,8 @@ ${fallback_html}`;
|
|
|
977
979
|
}
|
|
978
980
|
}
|
|
979
981
|
|
|
980
|
-
let
|
|
981
|
-
let
|
|
982
|
+
let start_offset = 0;
|
|
983
|
+
let end_offset = 0;
|
|
982
984
|
let current_offset = 0;
|
|
983
985
|
|
|
984
986
|
function processNode(node) {
|
|
@@ -988,12 +990,12 @@ ${fallback_html}`;
|
|
|
988
990
|
if (node === range.startContainer) {
|
|
989
991
|
// Convert UTF-16 offset to character offset
|
|
990
992
|
const char_start_offset = utf16_to_char_offset(nodeText, range.startOffset);
|
|
991
|
-
|
|
993
|
+
start_offset = current_offset + char_start_offset;
|
|
992
994
|
}
|
|
993
995
|
if (node === range.endContainer) {
|
|
994
996
|
// Convert UTF-16 offset to character offset
|
|
995
997
|
const char_end_offset = utf16_to_char_offset(nodeText, range.endOffset);
|
|
996
|
-
|
|
998
|
+
end_offset = current_offset + char_end_offset;
|
|
997
999
|
}
|
|
998
1000
|
current_offset += nodeCharLength;
|
|
999
1001
|
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
@@ -1001,7 +1003,7 @@ ${fallback_html}`;
|
|
|
1001
1003
|
processNode(childNode);
|
|
1002
1004
|
}
|
|
1003
1005
|
}
|
|
1004
|
-
return
|
|
1006
|
+
return end_offset !== 0;
|
|
1005
1007
|
}
|
|
1006
1008
|
|
|
1007
1009
|
// Process nodes to find offsets
|
|
@@ -1012,21 +1014,17 @@ ${fallback_html}`;
|
|
|
1012
1014
|
// Check if it's a backward selection
|
|
1013
1015
|
// When range is provided, we can't detect backward selection from the range alone
|
|
1014
1016
|
// since ranges are always normalized (start before end)
|
|
1015
|
-
const is_backward = dom_selection
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
// Swap offsets if it's a backward selection
|
|
1021
|
-
if (is_backward) {
|
|
1022
|
-
[anchor_offset, focus_offset] = [focus_offset, anchor_offset];
|
|
1023
|
-
}
|
|
1017
|
+
const is_backward = dom_selection ? __is_dom_selection_backwards() : false;
|
|
1018
|
+
|
|
1019
|
+
// Assign to anchor/focus based on direction
|
|
1020
|
+
const anchor_offset = is_backward ? end_offset : start_offset;
|
|
1021
|
+
const focus_offset = is_backward ? start_offset : end_offset;
|
|
1024
1022
|
|
|
1025
1023
|
return {
|
|
1026
1024
|
type: 'text',
|
|
1027
1025
|
path,
|
|
1028
|
-
anchor_offset
|
|
1029
|
-
focus_offset
|
|
1026
|
+
anchor_offset,
|
|
1027
|
+
focus_offset
|
|
1030
1028
|
};
|
|
1031
1029
|
}
|
|
1032
1030
|
|
|
@@ -1163,8 +1161,6 @@ ${fallback_html}`;
|
|
|
1163
1161
|
`[data-path="${selection.path.join('.')}"][data-type="text"]`
|
|
1164
1162
|
);
|
|
1165
1163
|
const empty_text = session.get(selection.path).text.length === 0;
|
|
1166
|
-
|
|
1167
|
-
const range = window.document.createRange();
|
|
1168
1164
|
const dom_selection = window.getSelection();
|
|
1169
1165
|
let current_offset = 0;
|
|
1170
1166
|
/** @type {HTMLElement | Text} */
|
|
@@ -1241,24 +1237,14 @@ ${fallback_html}`;
|
|
|
1241
1237
|
|
|
1242
1238
|
// Set the range if both start and end were found
|
|
1243
1239
|
if (anchor_node && focus_node) {
|
|
1244
|
-
// Always set range in document order (start to end)
|
|
1245
|
-
if (is_backward) {
|
|
1246
|
-
range.setStart(focus_node, focus_node_offset);
|
|
1247
|
-
range.setEnd(anchor_node, anchor_node_offset);
|
|
1248
|
-
} else {
|
|
1249
|
-
range.setStart(anchor_node, anchor_node_offset);
|
|
1250
|
-
range.setEnd(focus_node, focus_node_offset);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
1240
|
dom_selection.removeAllRanges();
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1241
|
+
// NOTE: Only using setBaseAndExtent() will preserve selection direction
|
|
1242
|
+
dom_selection.setBaseAndExtent(
|
|
1243
|
+
anchor_node,
|
|
1244
|
+
anchor_node_offset,
|
|
1245
|
+
focus_node,
|
|
1246
|
+
focus_node_offset
|
|
1247
|
+
);
|
|
1262
1248
|
el.focus(); // needed?
|
|
1263
1249
|
|
|
1264
1250
|
// Scroll the selection into view
|
|
@@ -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":";;;;;;;AAwyCA;;eAAqD;iCAhxC1C,cAAc"}
|
package/package.json
CHANGED
|
@@ -16,8 +16,18 @@
|
|
|
16
16
|
);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
let plain_text = $derived(svedit.session.get(path).text);
|
|
20
|
+
let is_empty = $derived(
|
|
21
|
+
get_char_length(plain_text) === 0 && !(svedit.is_composing && is_focused)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
let is_collapsed = $derived(
|
|
25
|
+
is_focused && svedit.session.selection?.anchor_offset == svedit.session.selection?.focus_offset
|
|
26
|
+
);
|
|
27
|
+
|
|
19
28
|
// Get selection highlight range if not inside an annotation
|
|
20
29
|
let selection_highlight_range = $derived.by(() => {
|
|
30
|
+
if (is_collapsed) return null;
|
|
21
31
|
if (!is_focused) return null;
|
|
22
32
|
if (svedit.session.active_annotation()) return null;
|
|
23
33
|
const sel = svedit.session.selection;
|
|
@@ -25,6 +35,14 @@
|
|
|
25
35
|
return get_selection_range(sel);
|
|
26
36
|
});
|
|
27
37
|
|
|
38
|
+
let fragments = $derived(
|
|
39
|
+
get_fragments(
|
|
40
|
+
svedit.session.get(path).text,
|
|
41
|
+
svedit.session.get(path).annotations,
|
|
42
|
+
selection_highlight_range
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
|
|
28
46
|
/**
|
|
29
47
|
* Converts text with annotations into renderable fragments for display.
|
|
30
48
|
* @param {string} text - The plain text content
|
|
@@ -78,18 +96,6 @@
|
|
|
78
96
|
|
|
79
97
|
return fragments;
|
|
80
98
|
}
|
|
81
|
-
|
|
82
|
-
let fragments = $derived(
|
|
83
|
-
get_fragments(
|
|
84
|
-
svedit.session.get(path).text,
|
|
85
|
-
svedit.session.get(path).annotations,
|
|
86
|
-
selection_highlight_range
|
|
87
|
-
)
|
|
88
|
-
);
|
|
89
|
-
let plain_text = $derived(svedit.session.get(path).text);
|
|
90
|
-
let is_empty = $derived(
|
|
91
|
-
get_char_length(plain_text) === 0 && !(svedit.is_composing && is_focused)
|
|
92
|
-
);
|
|
93
99
|
</script>
|
|
94
100
|
|
|
95
101
|
<!-- ATTENTION: The comments are needed to prevent unwanted text nodes with whitespace. -->
|
package/src/lib/Svedit.svelte
CHANGED
|
@@ -68,7 +68,9 @@
|
|
|
68
68
|
const key_mapper = getContext('key_mapper');
|
|
69
69
|
|
|
70
70
|
// Initialize commands and keymap on the session
|
|
71
|
-
|
|
71
|
+
$effect(() => {
|
|
72
|
+
session.initialize_commands(context);
|
|
73
|
+
});
|
|
72
74
|
|
|
73
75
|
// Handle focus - push session's keymap onto stack
|
|
74
76
|
function handle_canvas_focus() {
|
|
@@ -977,8 +979,8 @@ ${fallback_html}`;
|
|
|
977
979
|
}
|
|
978
980
|
}
|
|
979
981
|
|
|
980
|
-
let
|
|
981
|
-
let
|
|
982
|
+
let start_offset = 0;
|
|
983
|
+
let end_offset = 0;
|
|
982
984
|
let current_offset = 0;
|
|
983
985
|
|
|
984
986
|
function processNode(node) {
|
|
@@ -988,12 +990,12 @@ ${fallback_html}`;
|
|
|
988
990
|
if (node === range.startContainer) {
|
|
989
991
|
// Convert UTF-16 offset to character offset
|
|
990
992
|
const char_start_offset = utf16_to_char_offset(nodeText, range.startOffset);
|
|
991
|
-
|
|
993
|
+
start_offset = current_offset + char_start_offset;
|
|
992
994
|
}
|
|
993
995
|
if (node === range.endContainer) {
|
|
994
996
|
// Convert UTF-16 offset to character offset
|
|
995
997
|
const char_end_offset = utf16_to_char_offset(nodeText, range.endOffset);
|
|
996
|
-
|
|
998
|
+
end_offset = current_offset + char_end_offset;
|
|
997
999
|
}
|
|
998
1000
|
current_offset += nodeCharLength;
|
|
999
1001
|
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
@@ -1001,7 +1003,7 @@ ${fallback_html}`;
|
|
|
1001
1003
|
processNode(childNode);
|
|
1002
1004
|
}
|
|
1003
1005
|
}
|
|
1004
|
-
return
|
|
1006
|
+
return end_offset !== 0;
|
|
1005
1007
|
}
|
|
1006
1008
|
|
|
1007
1009
|
// Process nodes to find offsets
|
|
@@ -1012,21 +1014,17 @@ ${fallback_html}`;
|
|
|
1012
1014
|
// Check if it's a backward selection
|
|
1013
1015
|
// When range is provided, we can't detect backward selection from the range alone
|
|
1014
1016
|
// since ranges are always normalized (start before end)
|
|
1015
|
-
const is_backward = dom_selection
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
// Swap offsets if it's a backward selection
|
|
1021
|
-
if (is_backward) {
|
|
1022
|
-
[anchor_offset, focus_offset] = [focus_offset, anchor_offset];
|
|
1023
|
-
}
|
|
1017
|
+
const is_backward = dom_selection ? __is_dom_selection_backwards() : false;
|
|
1018
|
+
|
|
1019
|
+
// Assign to anchor/focus based on direction
|
|
1020
|
+
const anchor_offset = is_backward ? end_offset : start_offset;
|
|
1021
|
+
const focus_offset = is_backward ? start_offset : end_offset;
|
|
1024
1022
|
|
|
1025
1023
|
return {
|
|
1026
1024
|
type: 'text',
|
|
1027
1025
|
path,
|
|
1028
|
-
anchor_offset
|
|
1029
|
-
focus_offset
|
|
1026
|
+
anchor_offset,
|
|
1027
|
+
focus_offset
|
|
1030
1028
|
};
|
|
1031
1029
|
}
|
|
1032
1030
|
|
|
@@ -1163,8 +1161,6 @@ ${fallback_html}`;
|
|
|
1163
1161
|
`[data-path="${selection.path.join('.')}"][data-type="text"]`
|
|
1164
1162
|
);
|
|
1165
1163
|
const empty_text = session.get(selection.path).text.length === 0;
|
|
1166
|
-
|
|
1167
|
-
const range = window.document.createRange();
|
|
1168
1164
|
const dom_selection = window.getSelection();
|
|
1169
1165
|
let current_offset = 0;
|
|
1170
1166
|
/** @type {HTMLElement | Text} */
|
|
@@ -1241,24 +1237,14 @@ ${fallback_html}`;
|
|
|
1241
1237
|
|
|
1242
1238
|
// Set the range if both start and end were found
|
|
1243
1239
|
if (anchor_node && focus_node) {
|
|
1244
|
-
// Always set range in document order (start to end)
|
|
1245
|
-
if (is_backward) {
|
|
1246
|
-
range.setStart(focus_node, focus_node_offset);
|
|
1247
|
-
range.setEnd(anchor_node, anchor_node_offset);
|
|
1248
|
-
} else {
|
|
1249
|
-
range.setStart(anchor_node, anchor_node_offset);
|
|
1250
|
-
range.setEnd(focus_node, focus_node_offset);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
1240
|
dom_selection.removeAllRanges();
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1241
|
+
// NOTE: Only using setBaseAndExtent() will preserve selection direction
|
|
1242
|
+
dom_selection.setBaseAndExtent(
|
|
1243
|
+
anchor_node,
|
|
1244
|
+
anchor_node_offset,
|
|
1245
|
+
focus_node,
|
|
1246
|
+
focus_node_offset
|
|
1247
|
+
);
|
|
1262
1248
|
el.focus(); // needed?
|
|
1263
1249
|
|
|
1264
1250
|
// Scroll the selection into view
|