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 CHANGED
@@ -20,6 +20,7 @@
20
20
  </script>
21
21
 
22
22
  <svelte:element
23
+ id={node.id}
23
24
  this={tag}
24
25
  class={css_class}
25
26
  data-node-id={node.id}
@@ -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
- if (text_length > 0) {
957
- const last_char = get_char_at(text_content, text_length - 1);
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
- focus_node === anchor_node &&
960
- focus_node === focus_root &&
961
- focus_root.dataset?.type === 'text' &&
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
- const child_nodes = focus_root.childNodes;
966
-
967
- if (
968
- child_nodes.length > 0 &&
969
- child_nodes[child_nodes.length - 1].nodeName === 'BR' &&
970
- focus_offset_in_node >= child_nodes.length - 2
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: block;
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":";;;;;;;AAwyCA;;eAAqD;iCAhxC1C,cAAc"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svedit",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -20,6 +20,7 @@
20
20
  </script>
21
21
 
22
22
  <svelte:element
23
+ id={node.id}
23
24
  this={tag}
24
25
  class={css_class}
25
26
  data-node-id={node.id}
@@ -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
- if (text_length > 0) {
957
- const last_char = get_char_at(text_content, text_length - 1);
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
- focus_node === anchor_node &&
960
- focus_node === focus_root &&
961
- focus_root.dataset?.type === 'text' &&
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
- const child_nodes = focus_root.childNodes;
966
-
967
- if (
968
- child_nodes.length > 0 &&
969
- child_nodes[child_nodes.length - 1].nodeName === 'BR' &&
970
- focus_offset_in_node >= child_nodes.length - 2
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: block;
1341
+ caret-shape: bar;
1334
1342
  &:focus {
1335
1343
  outline: none;
1336
1344
  }