svedit 0.6.1 → 0.6.3
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/Node.svelte +1 -0
- package/dist/Svedit.svelte +32 -24
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/lib/Node.svelte +1 -0
- package/src/lib/Svedit.svelte +32 -24
package/dist/Node.svelte
CHANGED
package/dist/Svedit.svelte
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
snake_to_pascal,
|
|
5
5
|
get_char_length,
|
|
6
6
|
utf16_to_char_offset,
|
|
7
|
-
char_to_utf16_offset
|
|
8
|
-
get_char_at
|
|
7
|
+
char_to_utf16_offset
|
|
9
8
|
} from './utils.js';
|
|
10
9
|
|
|
11
10
|
/** @import {
|
|
@@ -951,31 +950,39 @@ ${fallback_html}`;
|
|
|
951
950
|
if (!path) return null;
|
|
952
951
|
|
|
953
952
|
// EDGE CASE 1B: Cursor after trailing <br> at end of text
|
|
953
|
+
//
|
|
954
|
+
// AnnotatedTextProperty renders a trailing <br> for non-empty or non-focused text.
|
|
955
|
+
// When the user places their cursor after this <br>, focusNode is the container
|
|
956
|
+
// element (not a text node), and normal processing would return position 0.
|
|
957
|
+
// We detect this and return text_length instead.
|
|
954
958
|
const text_content = session.get(path).text;
|
|
955
959
|
const text_length = get_char_length(text_content);
|
|
956
|
-
|
|
957
|
-
|
|
960
|
+
const child_nodes = focus_root.childNodes;
|
|
961
|
+
|
|
962
|
+
if (
|
|
963
|
+
focus_node === anchor_node &&
|
|
964
|
+
focus_node === focus_root &&
|
|
965
|
+
focus_root.dataset?.type === 'text' &&
|
|
966
|
+
!focus_root.classList.contains('empty')
|
|
967
|
+
) {
|
|
968
|
+
// Find the last non-comment child node (comments are inserted by Svelte)
|
|
969
|
+
let last_element_index = child_nodes.length - 1;
|
|
970
|
+
while (last_element_index >= 0 && child_nodes[last_element_index].nodeType === Node.COMMENT_NODE) {
|
|
971
|
+
last_element_index--;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// Check if cursor is at or after the trailing <br>
|
|
958
975
|
if (
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
!focus_root.classList.contains('empty') &&
|
|
963
|
-
last_char === '\n'
|
|
976
|
+
last_element_index >= 0 &&
|
|
977
|
+
child_nodes[last_element_index].nodeName === 'BR' &&
|
|
978
|
+
focus_offset_in_node >= last_element_index
|
|
964
979
|
) {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
) {
|
|
972
|
-
return {
|
|
973
|
-
type: 'text',
|
|
974
|
-
path,
|
|
975
|
-
anchor_offset: text_length,
|
|
976
|
-
focus_offset: text_length
|
|
977
|
-
};
|
|
978
|
-
}
|
|
980
|
+
return {
|
|
981
|
+
type: 'text',
|
|
982
|
+
path,
|
|
983
|
+
anchor_offset: text_length,
|
|
984
|
+
focus_offset: text_length
|
|
985
|
+
};
|
|
979
986
|
}
|
|
980
987
|
}
|
|
981
988
|
|
|
@@ -1309,6 +1316,7 @@ ${fallback_html}`;
|
|
|
1309
1316
|
onfocus={handle_canvas_focus}
|
|
1310
1317
|
onblur={handle_canvas_blur}
|
|
1311
1318
|
contenteditable={editable ? 'true' : 'false'}
|
|
1319
|
+
tabindex="-1"
|
|
1312
1320
|
{autocapitalize}
|
|
1313
1321
|
{spellcheck}
|
|
1314
1322
|
{...{
|
|
@@ -1330,7 +1338,7 @@ ${fallback_html}`;
|
|
|
1330
1338
|
.svedit-canvas {
|
|
1331
1339
|
--layout-orientation: vertical;
|
|
1332
1340
|
caret-color: var(--editing-stroke-color);
|
|
1333
|
-
caret-shape:
|
|
1341
|
+
caret-shape: bar;
|
|
1334
1342
|
&:focus {
|
|
1335
1343
|
outline: none;
|
|
1336
1344
|
}
|
|
@@ -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":";;;;;;;AA+yCA;;eAAqD;iCAxxC1C,cAAc"}
|
package/package.json
CHANGED
package/src/lib/Node.svelte
CHANGED
package/src/lib/Svedit.svelte
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
snake_to_pascal,
|
|
5
5
|
get_char_length,
|
|
6
6
|
utf16_to_char_offset,
|
|
7
|
-
char_to_utf16_offset
|
|
8
|
-
get_char_at
|
|
7
|
+
char_to_utf16_offset
|
|
9
8
|
} from './utils.js';
|
|
10
9
|
|
|
11
10
|
/** @import {
|
|
@@ -951,31 +950,39 @@ ${fallback_html}`;
|
|
|
951
950
|
if (!path) return null;
|
|
952
951
|
|
|
953
952
|
// EDGE CASE 1B: Cursor after trailing <br> at end of text
|
|
953
|
+
//
|
|
954
|
+
// AnnotatedTextProperty renders a trailing <br> for non-empty or non-focused text.
|
|
955
|
+
// When the user places their cursor after this <br>, focusNode is the container
|
|
956
|
+
// element (not a text node), and normal processing would return position 0.
|
|
957
|
+
// We detect this and return text_length instead.
|
|
954
958
|
const text_content = session.get(path).text;
|
|
955
959
|
const text_length = get_char_length(text_content);
|
|
956
|
-
|
|
957
|
-
|
|
960
|
+
const child_nodes = focus_root.childNodes;
|
|
961
|
+
|
|
962
|
+
if (
|
|
963
|
+
focus_node === anchor_node &&
|
|
964
|
+
focus_node === focus_root &&
|
|
965
|
+
focus_root.dataset?.type === 'text' &&
|
|
966
|
+
!focus_root.classList.contains('empty')
|
|
967
|
+
) {
|
|
968
|
+
// Find the last non-comment child node (comments are inserted by Svelte)
|
|
969
|
+
let last_element_index = child_nodes.length - 1;
|
|
970
|
+
while (last_element_index >= 0 && child_nodes[last_element_index].nodeType === Node.COMMENT_NODE) {
|
|
971
|
+
last_element_index--;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// Check if cursor is at or after the trailing <br>
|
|
958
975
|
if (
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
!focus_root.classList.contains('empty') &&
|
|
963
|
-
last_char === '\n'
|
|
976
|
+
last_element_index >= 0 &&
|
|
977
|
+
child_nodes[last_element_index].nodeName === 'BR' &&
|
|
978
|
+
focus_offset_in_node >= last_element_index
|
|
964
979
|
) {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
) {
|
|
972
|
-
return {
|
|
973
|
-
type: 'text',
|
|
974
|
-
path,
|
|
975
|
-
anchor_offset: text_length,
|
|
976
|
-
focus_offset: text_length
|
|
977
|
-
};
|
|
978
|
-
}
|
|
980
|
+
return {
|
|
981
|
+
type: 'text',
|
|
982
|
+
path,
|
|
983
|
+
anchor_offset: text_length,
|
|
984
|
+
focus_offset: text_length
|
|
985
|
+
};
|
|
979
986
|
}
|
|
980
987
|
}
|
|
981
988
|
|
|
@@ -1309,6 +1316,7 @@ ${fallback_html}`;
|
|
|
1309
1316
|
onfocus={handle_canvas_focus}
|
|
1310
1317
|
onblur={handle_canvas_blur}
|
|
1311
1318
|
contenteditable={editable ? 'true' : 'false'}
|
|
1319
|
+
tabindex="-1"
|
|
1312
1320
|
{autocapitalize}
|
|
1313
1321
|
{spellcheck}
|
|
1314
1322
|
{...{
|
|
@@ -1330,7 +1338,7 @@ ${fallback_html}`;
|
|
|
1330
1338
|
.svedit-canvas {
|
|
1331
1339
|
--layout-orientation: vertical;
|
|
1332
1340
|
caret-color: var(--editing-stroke-color);
|
|
1333
|
-
caret-shape:
|
|
1341
|
+
caret-shape: bar;
|
|
1334
1342
|
&:focus {
|
|
1335
1343
|
outline: none;
|
|
1336
1344
|
}
|