slate-vue3 0.0.3 → 0.0.4

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/License.md CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Guan-Erjia
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Guan-Erjia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,108 +1,108 @@
1
- [<img src="https://raw.githubusercontent.com/ianstormtaylor/slate/main/docs/images/banner.png" />](https://github.com/ianstormtaylor/slate/raw/main/docs/images/banner.png)
2
-
3
- <p align="center">
4
- slate-<a style="color: #087ea4" href="https://react.dev/">react</a> library implemented with <a style="color: #42b883" href="https://vuejs.org/">vue</a>
5
- </p>
6
- <br/>
7
-
8
- # Why use it?
9
-
10
- 1. Use vue internal response implementation to reduce the number of re-renderings
11
- 2. You can easily use vue-devtools to debug in a vue project
12
- 3. This library provides the same usage as slate-react
13
-
14
- # Demo
15
-
16
- Check out the [**live demo**](https://guan-erjia.github.io/slate-vue3/) of all of the examples
17
-
18
- # Hooks
19
-
20
- ## [useComposing](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-composing.ts)
21
-
22
- ```
23
- const useFocused: () => Ref<boolean, boolean>
24
- ```
25
-
26
- Get the current composing state of the editor. It deals with compositionstart, compositionupdate, compositionend events.
27
-
28
- Composition events are triggered by typing (composing) with a language that uses a composition character (e.g. Chinese, Japanese, Korean, etc.) example.
29
- Some basic Git commands are:
30
-
31
- ## [useFocused](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-focus.ts)
32
-
33
- ```
34
- const useFocused: () => Ref<boolean, boolean>
35
- ```
36
-
37
- Get the current focused state of the editor.
38
-
39
- ## [useReadOnly](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-read-only.ts)
40
-
41
- ```
42
- const useReadOnly: () => Ref<boolean, boolean>
43
- ```
44
-
45
- Get the current readOnly state of the editor.
46
-
47
- ## [useSelected](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-selected.ts)
48
-
49
- ```
50
- const useSelected: () => ComputedRef<boolean>
51
- ```
52
-
53
- Get the current selected state of an element.
54
-
55
- ## [useEditor](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-editor.ts)
56
-
57
- ```
58
- const useSlate: () => Editor;
59
- ```
60
-
61
- Get the current editor object from the React context. Re-renders the context whenever changes occur in the editor.
62
-
63
- ## [useSelection](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-selection.ts)
64
-
65
- ```
66
- const useSelection: () => ComputedRef<boolean>
67
- ```
68
-
69
- Get the current editor selection from the React context.
70
-
71
- # Packages
72
-
73
- **slate's codebase is monorepo managed with pnpm workspace**
74
-
75
- - [slate](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/slate)
76
- slate core logic, update synchronously with slate
77
- - [slate-dom](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/slate-dom)
78
- Implementation of slate on dom, update synchronously with slate-dom
79
- - [slate-vue](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/slate-vue)
80
- Vue components for rendering slate editors
81
- - [un-proxy-weakmap](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/un-proxy-weakmap)
82
- for special processing of proxy type data, obtain the raw pointer
83
-
84
- # compact files of slate
85
-
86
- **reactive implement**
87
-
88
- 1. packages/slate/src/interfaces/text.ts 115:115
89
- 2. packages/slate/src/create-editor.ts 94:94
90
- 3. packages/slate/src/transforms-node/set-nodes.ts 18:18
91
-
92
- **remove immer**
93
-
94
- 1. packages/slate/src/interfaces/node.ts 365:365
95
- 2. packages/slate/src/interfaces/point.ts 103:103
96
- 3. packages/slate/src/interfaces/range.ts 224:224
97
- 4. packages/slate/src/interfaces/transforms/general.ts 322:333
98
-
99
- **rewrite implement for WeakMap**
100
-
101
- 1. packages/un-proxy-weakmap/src/index.ts
102
- 2. packages/slate-dom/src/utils/weak-maps.ts
103
-
104
- **import types from globalThis in slate-dom**
105
- 1. packages/slate-dom/src/index.ts
106
- 2. packages/slate-dom/src/plugin/dom-editor.ts
107
- 3. packages/slate-dom/src/utils/dom.ts
108
-
1
+ [<img src="https://raw.githubusercontent.com/ianstormtaylor/slate/main/docs/images/banner.png" />](https://github.com/ianstormtaylor/slate/raw/main/docs/images/banner.png)
2
+
3
+ <p align="center">
4
+ slate-<a style="color: #087ea4" href="https://react.dev/">react</a> library implemented with <a style="color: #42b883" href="https://vuejs.org/">vue</a>
5
+ </p>
6
+ <br/>
7
+
8
+ # Why use it?
9
+
10
+ 1. Use vue internal response implementation to reduce the number of re-renderings
11
+ 2. You can easily use vue-devtools to debug in a vue project
12
+ 3. This library provides the same usage as slate-react
13
+
14
+ # Demo
15
+
16
+ Check out the [**live demo**](https://guan-erjia.github.io/slate-vue3/) of all of the examples
17
+
18
+ # Hooks
19
+
20
+ ## [useComposing](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-composing.ts)
21
+
22
+ ```
23
+ const useFocused: () => Ref<boolean, boolean>
24
+ ```
25
+
26
+ Get the current composing state of the editor. It deals with compositionstart, compositionupdate, compositionend events.
27
+
28
+ Composition events are triggered by typing (composing) with a language that uses a composition character (e.g. Chinese, Japanese, Korean, etc.) example.
29
+ Some basic Git commands are:
30
+
31
+ ## [useFocused](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-focus.ts)
32
+
33
+ ```
34
+ const useFocused: () => Ref<boolean, boolean>
35
+ ```
36
+
37
+ Get the current focused state of the editor.
38
+
39
+ ## [useReadOnly](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-read-only.ts)
40
+
41
+ ```
42
+ const useReadOnly: () => Ref<boolean, boolean>
43
+ ```
44
+
45
+ Get the current readOnly state of the editor.
46
+
47
+ ## [useSelected](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-selected.ts)
48
+
49
+ ```
50
+ const useSelected: () => ComputedRef<boolean>
51
+ ```
52
+
53
+ Get the current selected state of an element.
54
+
55
+ ## [useEditor](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-editor.ts)
56
+
57
+ ```
58
+ const useSlate: () => Editor;
59
+ ```
60
+
61
+ Get the current editor object from the React context. Re-renders the context whenever changes occur in the editor.
62
+
63
+ ## [useSelection](https://github.com/Guan-Erjia/slate-vue3/blob/master/packages/slate-vue/src/hooks/use-selection.ts)
64
+
65
+ ```
66
+ const useSelection: () => ComputedRef<boolean>
67
+ ```
68
+
69
+ Get the current editor selection from the React context.
70
+
71
+ # Packages
72
+
73
+ **slate's codebase is monorepo managed with pnpm workspace**
74
+
75
+ - [slate](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/slate)
76
+ slate core logic, update synchronously with slate
77
+ - [slate-dom](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/slate-dom)
78
+ Implementation of slate on dom, update synchronously with slate-dom
79
+ - [slate-vue](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/slate-vue)
80
+ Vue components for rendering slate editors
81
+ - [share-tools](https://github.com/Guan-Erjia/slate-vue3/tree/master/packages/share-tools)
82
+ for special processing of proxy type data, obtain the raw pointer, isPlainObject declare
83
+
84
+ # compact files of slate
85
+
86
+ **reactive implement**
87
+
88
+ 1. packages/slate/src/interfaces/text.ts 115:115
89
+ 2. packages/slate/src/create-editor.ts 94:94
90
+ 3. packages/slate/src/transforms-node/set-nodes.ts 18:18
91
+
92
+ **remove immer**
93
+
94
+ 1. packages/slate/src/interfaces/node.ts 365:365
95
+ 2. packages/slate/src/interfaces/point.ts 103:103
96
+ 3. packages/slate/src/interfaces/range.ts 224:224
97
+ 4. packages/slate/src/interfaces/transforms/general.ts 322:333
98
+
99
+ **rewrite implement for WeakMap**
100
+
101
+ 1. packages/un-proxy-weakmap/src/index.ts
102
+ 2. packages/slate-dom/src/utils/weak-maps.ts
103
+
104
+ **import types from globalThis in slate-dom**
105
+ 1. packages/slate-dom/src/index.ts
106
+ 2. packages/slate-dom/src/plugin/dom-editor.ts
107
+ 3. packages/slate-dom/src/utils/dom.ts
108
+
package/dist/index.d.ts CHANGED
@@ -2506,7 +2506,7 @@ editor: DOMEditor;
2506
2506
  decorate: (entry: NodeEntry) => DecoratedRange[];
2507
2507
  renderElement: (props: RenderElementProps) => VNode;
2508
2508
  renderLeaf: (props: RenderLeafProps) => VNode;
2509
- renderPlaceholder: (props: RenderPlaceholderProps) => JSX.Element;
2509
+ renderPlaceholder: (props: RenderPlaceholderProps) => VNode;
2510
2510
  }, () => VNode<RendererNode, RendererElement, {
2511
2511
  [key: string]: any;
2512
2512
  }>, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ("change" | "selectionchange" | "valuechange")[], "change" | "selectionchange" | "valuechange", PublicProps, Readonly<{
@@ -2514,7 +2514,7 @@ editor: DOMEditor;
2514
2514
  decorate: (entry: NodeEntry) => DecoratedRange[];
2515
2515
  renderElement: (props: RenderElementProps) => VNode;
2516
2516
  renderLeaf: (props: RenderLeafProps) => VNode;
2517
- renderPlaceholder: (props: RenderPlaceholderProps) => JSX.Element;
2517
+ renderPlaceholder: (props: RenderPlaceholderProps) => VNode;
2518
2518
  }> & Readonly<{
2519
2519
  onChange?: ((...args: any[]) => any) | undefined;
2520
2520
  onSelectionchange?: ((...args: any[]) => any) | undefined;
@@ -3404,7 +3404,6 @@ if (!!(process.env.NODE_ENV !== "production")) {
3404
3404
  const SLATE_USE_EDITOR = Symbol("SLATE_USE_EDITOR");
3405
3405
  const SLATE_USE_DECORATE = Symbol("SLATE_USE_DECORATE");
3406
3406
  const SLATE_USE_SELECTED = Symbol("SLATE_USE_SELECTED");
3407
- const SLATE_CHANGE_EFFECT_INJECT = Symbol("SLATE_CHANGE_EFFECT_INJECT");
3408
3407
  const SLATE_STATE_FOCUS = Symbol("SLATE_STATE_FOCUS");
3409
3408
  const SLATE_STATE_COMPOSING = Symbol("SLATE_STATE_COMPOSING");
3410
3409
  const SLATE_STATE_READ_ONLY = Symbol("SLATE_STATE_READ_ONLY");
@@ -3413,6 +3412,7 @@ const SLATE_INNER_RENDER_ELEMENT = Symbol("SLATE_INNER_RENDER_ELEMENT");
3413
3412
  const SLATE_INNER_RENDER_LEAF = Symbol("SLATE_INNER_RENDER_LEAF");
3414
3413
  const SLATE_INNER_RENDER_PLACEHOLDER = Symbol("SLATE_INNER_RENDER_PLACEHOLDER");
3415
3414
  const SLATE_INNER_PLACEHOLDER_CONTEXT = Symbol("SLATE_INNER_PLACEHOLDER_CONTEXT");
3415
+ const SLATE_INNER_CHANGE_EFFECT_INJECT = Symbol("SLATE_INNER_CHANGE_EFFECT_INJECT");
3416
3416
  const PathRef = {
3417
3417
  transform(ref2, op) {
3418
3418
  const { current, affinity } = ref2;
@@ -10056,24 +10056,21 @@ const Slate = /* @__PURE__ */ defineComponent({
10056
10056
  provide(SLATE_INNER_RENDER_LEAF, renderLeaf);
10057
10057
  provide(SLATE_INNER_RENDER_PLACEHOLDER, renderPlaceholder);
10058
10058
  const isFocus = ref(DOMEditor.isFocused(editor));
10059
- const isComposing = ref(false);
10060
- const isReadOnly = ref(false);
10061
10059
  const selection = computed(() => editor.selection);
10062
10060
  provide(SLATE_STATE_FOCUS, isFocus);
10063
- provide(SLATE_STATE_COMPOSING, isComposing);
10064
- provide(SLATE_STATE_READ_ONLY, isReadOnly);
10061
+ provide(SLATE_STATE_COMPOSING, ref(false));
10062
+ provide(SLATE_STATE_READ_ONLY, ref(false));
10065
10063
  provide(SLATE_STATE_SELECTION, selection);
10066
10064
  const focusCb = () => isFocus.value = DOMEditor.isFocused(editor);
10067
- let changeEffect = () => {
10068
- };
10069
- provide(SLATE_CHANGE_EFFECT_INJECT, (fn) => changeEffect = fn);
10065
+ const changeEffect = ref(0);
10066
+ provide(SLATE_INNER_CHANGE_EFFECT_INJECT, changeEffect);
10070
10067
  onMounted(() => {
10071
10068
  document.addEventListener("focusin", focusCb);
10072
10069
  document.addEventListener("focusout", focusCb);
10073
10070
  EDITOR_TO_ON_CHANGE.set(editor, (options) => {
10074
10071
  var _a2;
10075
10072
  emit("change", editor.children);
10076
- changeEffect();
10073
+ changeEffect.value++;
10077
10074
  switch ((_a2 = options == null ? void 0 : options.operation) == null ? void 0 : _a2.type) {
10078
10075
  case "set_selection":
10079
10076
  emit("selectionchange", editor.selection);
@@ -10680,37 +10677,36 @@ const useEditor = () => {
10680
10677
  };
10681
10678
  const StringComp = /* @__PURE__ */ defineComponent({
10682
10679
  name: "slate-string",
10683
- props: ["leaf", "parent", "text", "isLastIndex"],
10680
+ props: ["isLast", "leaf", "parent", "text"],
10684
10681
  setup(props) {
10685
10682
  const {
10686
- text,
10683
+ isLast,
10687
10684
  leaf: leaf2,
10688
10685
  parent: parent2,
10689
- isLastIndex
10686
+ text
10690
10687
  } = props;
10691
10688
  const editor = useEditor();
10692
- const getTextContent = computed(() => {
10693
- const isLast = !Editor.isVoid(editor, parent2) && Element.isElement(parent2) && !editor.isInline(parent2) && Editor.hasInlines(editor, parent2) && NODE_TO_INDEX.get(text) === parent2.children.length - 1 && isLastIndex;
10694
- return (leaf2.text ?? "") + (isLast && leaf2.text.slice(-1) === "\n" ? "\n" : "");
10695
- });
10689
+ const getTextContent = computed(() => (leaf2.value.text ?? "") + (isLast.value && leaf2.value.text.slice(-1) === "\n" ? "\n" : ""));
10696
10690
  const isVoidParent = computed(() => editor.isVoid(parent2));
10697
10691
  const isInlineBreak = computed(() => {
10698
10692
  const pathParent = Path.parent(DOMEditor.findPath(editor, text));
10699
- return leaf2.text === "" && parent2.children[parent2.children.length - 1] === text && !editor.isInline(parent2) && Editor.string(editor, pathParent) === "";
10693
+ return leaf2.value.text === "" && parent2.children[parent2.children.length - 1] === text && !editor.isInline(parent2) && Editor.string(editor, pathParent) === "";
10700
10694
  });
10701
10695
  return () => isVoidParent.value ? h(ZeroWidthString, {
10702
10696
  length: Node.string(parent2).length
10703
10697
  }) : isInlineBreak.value ? h(ZeroWidthString, {
10704
10698
  isLineBreak: true,
10705
- isMarkPlaceholder: Boolean(leaf2[MARK_PLACEHOLDER_SYMBOL])
10706
- }) : leaf2.text === "" ? h(ZeroWidthString, {
10699
+ isMarkPlaceholder: Boolean(leaf2.value[MARK_PLACEHOLDER_SYMBOL])
10700
+ }) : (
10707
10701
  // COMPAT: If the text is empty, it's because it's on the edge of an inline
10708
10702
  // node, so we render a zero-width space so that the selection can be
10709
10703
  // inserted next to it still.
10710
- isMarkPlaceholder: Boolean(leaf2[MARK_PLACEHOLDER_SYMBOL])
10711
- }) : h("span", {
10712
- "data-slate-string": true
10713
- }, getTextContent.value);
10704
+ leaf2.value.text === "" ? h(ZeroWidthString, {
10705
+ isMarkPlaceholder: Boolean(leaf2.value[MARK_PLACEHOLDER_SYMBOL])
10706
+ }) : h("span", {
10707
+ "data-slate-string": true
10708
+ }, getTextContent.value)
10709
+ );
10714
10710
  }
10715
10711
  });
10716
10712
  const ZeroWidthString = /* @__PURE__ */ defineComponent({
@@ -10771,6 +10767,18 @@ const usePlaceholderContext = () => {
10771
10767
  }
10772
10768
  return PLACEHOLDER_CONTEXT;
10773
10769
  };
10770
+ const useChangeEffect = (fn) => {
10771
+ const CHANGE_EFFECT_INJECT = inject(
10772
+ SLATE_INNER_CHANGE_EFFECT_INJECT
10773
+ );
10774
+ if (CHANGE_EFFECT_INJECT === void 0) {
10775
+ throw new Error(
10776
+ `The \`useChangeEffect\` hook must be used inside the <Slate> component's context.`
10777
+ );
10778
+ }
10779
+ watch(() => CHANGE_EFFECT_INJECT.value, fn);
10780
+ return CHANGE_EFFECT_INJECT;
10781
+ };
10774
10782
  const style = {
10775
10783
  position: "absolute",
10776
10784
  top: 0,
@@ -10786,15 +10794,21 @@ const style = {
10786
10794
  };
10787
10795
  const LeafComp = /* @__PURE__ */ defineComponent({
10788
10796
  name: "slate-leaf",
10789
- props: ["text", "parent", "leaf", "isLastIndex"],
10797
+ props: ["text", "parent", "leaves", "leafIndex"],
10790
10798
  setup(props) {
10791
10799
  const {
10792
10800
  text,
10793
10801
  parent: parent2,
10794
- leaf: leaf2,
10795
- isLastIndex
10802
+ leaves,
10803
+ leafIndex
10796
10804
  } = props;
10797
10805
  const editor = useEditor();
10806
+ const leaf2 = computed(() => leaves.value[leafIndex]);
10807
+ const isLast = computed(() => {
10808
+ const isVoid = Editor.isVoid(editor, parent2);
10809
+ const isLeafBlock = Element.isElement(parent2) && !editor.isInline(parent2) && Editor.hasInlines(editor, parent2);
10810
+ return !isVoid && isLeafBlock && NODE_TO_INDEX.get(text) === parent2.children.length - 1 && leafIndex === leaves.value.length - 1;
10811
+ });
10798
10812
  const placeholderResizeObserver = ref(null);
10799
10813
  const placeholderRef = ref(null);
10800
10814
  const placeholderContext = usePlaceholderContext();
@@ -10829,12 +10843,12 @@ const LeafComp = /* @__PURE__ */ defineComponent({
10829
10843
  ref: placeholderRef
10830
10844
  }
10831
10845
  }), h(StringComp, {
10846
+ isLast,
10832
10847
  leaf: leaf2,
10833
10848
  parent: parent2,
10834
- text,
10835
- isLastIndex
10849
+ text
10836
10850
  })]),
10837
- leaf: leaf2,
10851
+ leaf: leaf2.value,
10838
10852
  text
10839
10853
  });
10840
10854
  }
@@ -10859,7 +10873,7 @@ const TextComp = /* @__PURE__ */ defineComponent({
10859
10873
  const editor = useEditor();
10860
10874
  const spanRef = ref();
10861
10875
  const decorate = useDecorate();
10862
- const parentDecorations = computed(() => {
10876
+ const decorations = computed(() => {
10863
10877
  const path2 = DOMEditor.findPath(editor, props.parent);
10864
10878
  const range2 = Editor.range(editor, path2);
10865
10879
  const ds = decorate([props.parent, path2]);
@@ -10897,7 +10911,7 @@ const TextComp = /* @__PURE__ */ defineComponent({
10897
10911
  const path2 = DOMEditor.findPath(editor, text);
10898
10912
  const range2 = Editor.range(editor, path2);
10899
10913
  const ds = decorate([text, path2]);
10900
- parentDecorations.value.forEach((dec) => {
10914
+ decorations.value.forEach((dec) => {
10901
10915
  ds.push(Range.intersection(dec, range2));
10902
10916
  });
10903
10917
  return Text.decorations(text, ds.filter(Boolean).length ? ds : []);
@@ -10928,8 +10942,8 @@ const TextComp = /* @__PURE__ */ defineComponent({
10928
10942
  }, leaves.value.map((leaf2, i) => h(LeafComp, {
10929
10943
  text,
10930
10944
  parent: parent2,
10931
- leaf: leaf2,
10932
- isLastIndex: i === leaves.value.length - 1,
10945
+ leafIndex: i,
10946
+ leaves,
10933
10947
  key: `${key.id}-${i}-${text.text}`
10934
10948
  })));
10935
10949
  };
@@ -10946,21 +10960,32 @@ const useReadOnly = () => {
10946
10960
  };
10947
10961
  const ElementComp = /* @__PURE__ */ defineComponent({
10948
10962
  name: "slate-element",
10949
- props: ["element", "childSelection"],
10963
+ props: ["element"],
10950
10964
  setup(props) {
10951
10965
  const {
10952
- element,
10953
- childSelection
10966
+ element
10954
10967
  } = props;
10955
10968
  const editor = useEditor();
10956
10969
  const selection = computed(() => {
10957
10970
  const path2 = DOMEditor.findPath(editor, element);
10958
- const range2 = Editor.range(editor, path2);
10959
- return childSelection.value && Range.intersection(range2, childSelection.value);
10971
+ const elemList = [[element, path2]];
10972
+ let parent2 = Editor.parent(editor, path2);
10973
+ while (parent2[1].length) {
10974
+ elemList.unshift(parent2);
10975
+ parent2 = Editor.parent(editor, parent2[1]);
10976
+ }
10977
+ let sel = editor.selection;
10978
+ for (const item of elemList) {
10979
+ if (sel) {
10980
+ sel = Range.intersection(Editor.range(editor, item[1]), sel);
10981
+ } else {
10982
+ break;
10983
+ }
10984
+ }
10985
+ return sel;
10960
10986
  });
10961
10987
  const selected = computed(() => !!selection.value);
10962
10988
  provide(SLATE_USE_SELECTED, selected);
10963
- const readOnly = useReadOnly();
10964
10989
  const elementRef = ref(null);
10965
10990
  onMounted(() => {
10966
10991
  const key = DOMEditor.findKey(editor, element);
@@ -10978,6 +11003,7 @@ const ElementComp = /* @__PURE__ */ defineComponent({
10978
11003
  NODE_TO_ELEMENT.delete(element);
10979
11004
  });
10980
11005
  const isInline = computed(() => editor.isInline(element));
11006
+ const readOnly = useReadOnly();
10981
11007
  const attributes = computed(() => {
10982
11008
  const attr = {
10983
11009
  "data-slate-node": "element",
@@ -11001,61 +11027,54 @@ const ElementComp = /* @__PURE__ */ defineComponent({
11001
11027
  }
11002
11028
  return attr;
11003
11029
  });
11004
- let children = createVNode(Children, {
11005
- "node": element,
11006
- "selection": selection
11007
- }, null);
11008
- if (Editor.isVoid(editor, element)) {
11009
- const Tag = isInline.value ? "span" : "div";
11010
- const [[text]] = Node.texts(element);
11011
- children = createVNode(Tag, {
11012
- "data-slate-spacer": true,
11013
- "style": {
11014
- height: "0",
11015
- color: "transparent",
11016
- outline: "none",
11017
- position: "absolute"
11018
- }
11019
- }, {
11020
- default: () => [createVNode(TextComp, {
11021
- "parent": element,
11022
- "text": text
11023
- }, null)]
11030
+ const children = computed(() => {
11031
+ if (Editor.isVoid(editor, element)) {
11032
+ const [[text]] = Node.texts(element);
11033
+ NODE_TO_INDEX.set(text, 0);
11034
+ NODE_TO_PARENT.set(text, element);
11035
+ return h(isInline.value ? "span" : "div", {
11036
+ "data-slate-spacer": true,
11037
+ style: {
11038
+ height: "0",
11039
+ color: "transparent",
11040
+ outline: "none",
11041
+ position: "absolute"
11042
+ }
11043
+ }, h(TextComp, {
11044
+ parent: element,
11045
+ text
11046
+ }));
11047
+ }
11048
+ return h(Children, {
11049
+ node: element
11024
11050
  });
11025
- NODE_TO_INDEX.set(text, 0);
11026
- NODE_TO_PARENT.set(text, element);
11027
- }
11051
+ });
11028
11052
  const renderElement = useRenderElement();
11029
11053
  return () => renderElement({
11030
11054
  attributes: attributes.value,
11031
- children,
11055
+ children: children.value,
11032
11056
  element
11033
11057
  });
11034
11058
  }
11035
11059
  });
11036
11060
  const Children = /* @__PURE__ */ defineComponent({
11037
11061
  name: "Children",
11038
- props: ["node", "decorations", "selection"],
11062
+ props: ["node"],
11039
11063
  setup(props) {
11040
- const {
11041
- node: node2,
11042
- selection
11043
- } = props;
11044
11064
  const editor = useEditor();
11045
11065
  onUpdated(() => {
11046
11066
  IS_NODE_MAP_DIRTY.set(editor, false);
11047
11067
  });
11048
- return () => node2.children.map((child, i) => {
11068
+ return () => props.node.children.map((child, i) => {
11049
11069
  const key = DOMEditor.findKey(editor, child);
11050
11070
  NODE_TO_INDEX.set(child, i);
11051
- NODE_TO_PARENT.set(child, node2);
11071
+ NODE_TO_PARENT.set(child, props.node);
11052
11072
  return Element.isElement(child) ? createVNode(ElementComp, {
11053
11073
  "element": child,
11054
- "childSelection": selection,
11055
11074
  "key": key.id
11056
11075
  }, null) : createVNode(TextComp, {
11057
11076
  "text": child,
11058
- "parent": node2,
11077
+ "parent": props.node,
11059
11078
  "key": key.id
11060
11079
  }, null);
11061
11080
  });
@@ -11315,7 +11334,6 @@ const Editable = /* @__PURE__ */ defineComponent({
11315
11334
  }
11316
11335
  },
11317
11336
  setup(props) {
11318
- var _a2;
11319
11337
  const {
11320
11338
  placeholder,
11321
11339
  readOnly,
@@ -11340,8 +11358,8 @@ const Editable = /* @__PURE__ */ defineComponent({
11340
11358
  });
11341
11359
  const placeholderHeight = ref();
11342
11360
  const placeholderContext = computed(() => {
11343
- var _a3;
11344
- const showPlaceholder = placeholder && ((_a3 = editor.children) == null ? void 0 : _a3.length) === 1 && Array.from(Node.texts(editor)).length === 1 && Node.string(editor) === "" && !isComposing.value;
11361
+ var _a2;
11362
+ const showPlaceholder = placeholder && ((_a2 = editor.children) == null ? void 0 : _a2.length) === 1 && Array.from(Node.texts(editor)).length === 1 && Node.string(editor) === "" && !isComposing.value;
11345
11363
  if (!showPlaceholder) {
11346
11364
  placeholderHeight.value = void 0;
11347
11365
  return null;
@@ -11349,9 +11367,9 @@ const Editable = /* @__PURE__ */ defineComponent({
11349
11367
  return {
11350
11368
  placeholder,
11351
11369
  onPlaceholderResize: (placeholderEl) => {
11352
- var _a4;
11370
+ var _a3;
11353
11371
  if (placeholderEl && showPlaceholder) {
11354
- placeholderHeight.value = (_a4 = placeholderEl.getBoundingClientRect()) == null ? void 0 : _a4.height;
11372
+ placeholderHeight.value = (_a3 = placeholderEl.getBoundingClientRect()) == null ? void 0 : _a3.height;
11355
11373
  } else {
11356
11374
  placeholderHeight.value = void 0;
11357
11375
  }
@@ -11460,7 +11478,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11460
11478
  }
11461
11479
  });
11462
11480
  const setDomSelection = (forceChange) => {
11463
- var _a3;
11481
+ var _a2;
11464
11482
  const root2 = DOMEditor.findDocumentOrShadowRoot(editor);
11465
11483
  const domSelection = getSelection(root2);
11466
11484
  if (!domSelection) {
@@ -11499,7 +11517,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11499
11517
  if (!hasMarkPlaceholder.value) {
11500
11518
  return;
11501
11519
  }
11502
- if ((_a3 = anchorNode == null ? void 0 : anchorNode.parentElement) == null ? void 0 : _a3.hasAttribute("data-slate-mark-placeholder")) {
11520
+ if ((_a2 = anchorNode == null ? void 0 : anchorNode.parentElement) == null ? void 0 : _a2.hasAttribute("data-slate-mark-placeholder")) {
11503
11521
  return;
11504
11522
  }
11505
11523
  }
@@ -11541,10 +11559,10 @@ const Editable = /* @__PURE__ */ defineComponent({
11541
11559
  };
11542
11560
  const animationFrameId = ref();
11543
11561
  const changeEffect = () => {
11544
- var _a3, _b2;
11562
+ var _a2, _b2;
11545
11563
  const root2 = DOMEditor.findDocumentOrShadowRoot(editor);
11546
11564
  const domSelection = getSelection(root2);
11547
- if (!domSelection || !DOMEditor.isFocused(editor) || ((_a3 = androidInputManagerRef.value) == null ? void 0 : _a3.hasPendingAction())) {
11565
+ if (!domSelection || !DOMEditor.isFocused(editor) || ((_a2 = androidInputManagerRef.value) == null ? void 0 : _a2.hasPendingAction())) {
11548
11566
  return;
11549
11567
  }
11550
11568
  if (domSelection.rangeCount <= 1) {
@@ -11567,7 +11585,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11567
11585
  }
11568
11586
  });
11569
11587
  };
11570
- (_a2 = inject(SLATE_CHANGE_EFFECT_INJECT)) == null ? void 0 : _a2(changeEffect);
11588
+ useChangeEffect(changeEffect);
11571
11589
  onUnmounted(() => {
11572
11590
  animationFrameId.value && cancelAnimationFrame(animationFrameId.value);
11573
11591
  if (timeoutId) {
@@ -11588,7 +11606,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11588
11606
  window2.document.removeEventListener("drop", stoppedDragging);
11589
11607
  });
11590
11608
  const onBeforeinput = (event) => {
11591
- var _a3, _b2, _c, _d;
11609
+ var _a2, _b2, _c, _d;
11592
11610
  const isInputEvent = event instanceof InputEvent;
11593
11611
  if (!isInputEvent) {
11594
11612
  return;
@@ -11646,7 +11664,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11646
11664
  anchor
11647
11665
  } = selection;
11648
11666
  const [node2, offset] = DOMEditor.toDOMPoint(editor, anchor);
11649
- const anchorNode = (_a3 = node2.parentElement) == null ? void 0 : _a3.closest("a");
11667
+ const anchorNode = (_a2 = node2.parentElement) == null ? void 0 : _a2.closest("a");
11650
11668
  const window2 = DOMEditor.getWindow(editor);
11651
11669
  if (native && anchorNode && DOMEditor.hasDOMNode(editor, anchorNode)) {
11652
11670
  const lastText = window2 == null ? void 0 : window2.document.createTreeWalker(anchorNode, NodeFilter.SHOW_TEXT).lastChild();
@@ -11893,7 +11911,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11893
11911
  }
11894
11912
  };
11895
11913
  const onCompositionend = (event) => {
11896
- var _a3;
11914
+ var _a2;
11897
11915
  if (DOMEditor.hasSelectableTarget(editor, event.target)) {
11898
11916
  if (DOMEditor.isComposing(editor)) {
11899
11917
  Promise.resolve().then(() => {
@@ -11901,7 +11919,7 @@ const Editable = /* @__PURE__ */ defineComponent({
11901
11919
  IS_COMPOSING.set(editor, false);
11902
11920
  });
11903
11921
  }
11904
- (_a3 = androidInputManagerRef.value) == null ? void 0 : _a3.handleCompositionEnd(event);
11922
+ (_a2 = androidInputManagerRef.value) == null ? void 0 : _a2.handleCompositionEnd(event);
11905
11923
  if (isEventHandled(event, attributes.onCompositionend) || IS_ANDROID) {
11906
11924
  return;
11907
11925
  }
@@ -11930,9 +11948,9 @@ const Editable = /* @__PURE__ */ defineComponent({
11930
11948
  }
11931
11949
  };
11932
11950
  const onCompositionstart = (event) => {
11933
- var _a3;
11951
+ var _a2;
11934
11952
  if (DOMEditor.hasSelectableTarget(editor, event.target)) {
11935
- (_a3 = androidInputManagerRef.value) == null ? void 0 : _a3.handleCompositionStart(event);
11953
+ (_a2 = androidInputManagerRef.value) == null ? void 0 : _a2.handleCompositionStart(event);
11936
11954
  if (isEventHandled(event, attributes.onCompositionstart) || IS_ANDROID) {
11937
11955
  return;
11938
11956
  }
@@ -12034,9 +12052,9 @@ const Editable = /* @__PURE__ */ defineComponent({
12034
12052
  }
12035
12053
  };
12036
12054
  const onKeydown = (event) => {
12037
- var _a3;
12055
+ var _a2;
12038
12056
  if (!readOnly && DOMEditor.hasEditableTarget(editor, event.target)) {
12039
- (_a3 = androidInputManagerRef.value) == null ? void 0 : _a3.handleKeyDown(event);
12057
+ (_a2 = androidInputManagerRef.value) == null ? void 0 : _a2.handleKeyDown(event);
12040
12058
  if (DOMEditor.isComposing(editor) && event.isComposing === false) {
12041
12059
  IS_COMPOSING.set(editor, false);
12042
12060
  isComposing.value = false;
@@ -12286,7 +12304,6 @@ const Editable = /* @__PURE__ */ defineComponent({
12286
12304
  const spellcheck = computed(() => HAS_BEFORE_INPUT_SUPPORT || !CAN_USE_DOM ? attributes.spellcheck : false);
12287
12305
  const autocorrect = computed(() => HAS_BEFORE_INPUT_SUPPORT || !CAN_USE_DOM ? attributes.autocorrect : void 0);
12288
12306
  const autocapitalize = computed(() => HAS_BEFORE_INPUT_SUPPORT || !CAN_USE_DOM ? attributes.autocapitalize : void 0);
12289
- const editorSelection = computed(() => editor.selection);
12290
12307
  return () => createVNode("div", mergeProps({
12291
12308
  "is": is,
12292
12309
  "role": readOnly ? void 0 : "textbox",
@@ -12317,8 +12334,7 @@ const Editable = /* @__PURE__ */ defineComponent({
12317
12334
  "onKeydown": onKeydown,
12318
12335
  "onPaste": onPaste
12319
12336
  }), [createVNode(Children, {
12320
- "node": editor,
12321
- "selection": editorSelection
12337
+ "node": editor
12322
12338
  }, null)]);
12323
12339
  }
12324
12340
  });
package/package.json CHANGED
@@ -1,77 +1,77 @@
1
- {
2
- "name": "slate-vue3",
3
- "version": "0.0.3",
4
- "type": "module",
5
- "workspaces": [
6
- "packages/*"
7
- ],
8
- "main": "dist/index.js",
9
- "module": "dist/index.js",
10
- "types": "dist/index.d.ts",
11
- "files": [
12
- "dist/"
13
- ],
14
- "scripts": {
15
- "dev": "vite",
16
- "build": "vite build",
17
- "preview": "vite preview",
18
- "build-all": "vite build --mode=lib"
19
- },
20
- "dependencies": {
21
- "direction": "^2.0.1",
22
- "is-hotkey": "^0.2.0",
23
- "lodash-es": "^4.17.21",
24
- "scroll-into-view-if-needed": "^3.1.0",
25
- "slate": "workspace:*",
26
- "slate-dom": "workspace:*",
27
- "slate-history": "^0.110.3",
28
- "slate-hyperscript": "^0.100.0",
29
- "slate-vue": "workspace:*",
30
- "vue": "^3.5.13",
31
- "vue-router": "^4.5.0"
32
- },
33
- "devDependencies": {
34
- "@faker-js/faker": "^9.4.0",
35
- "@types/is-hotkey": "^0.1.10",
36
- "@types/is-url": "^1.2.32",
37
- "@types/lodash-es": "^4.17.12",
38
- "@types/prismjs": "^1.26.5",
39
- "@vitejs/plugin-vue": "^5.2.1",
40
- "@vitejs/plugin-vue-jsx": "^4.1.1",
41
- "@vue/tsconfig": "^0.7.0",
42
- "image-extensions": "^1.1.0",
43
- "is-url": "^1.2.4",
44
- "prismjs": "^1.29.0",
45
- "typescript": "~5.7.2",
46
- "vite": "^6.0.11",
47
- "vite-plugin-dts": "^4.5.0",
48
- "vue-tsc": "^2.2.0"
49
- },
50
- "keywords": [
51
- "canvas",
52
- "contenteditable",
53
- "docs",
54
- "document",
55
- "edit",
56
- "editor",
57
- "editable",
58
- "html",
59
- "immutable",
60
- "markdown",
61
- "medium",
62
- "paper",
63
- "react",
64
- "rich",
65
- "richtext",
66
- "richtext",
67
- "slate",
68
- "slate-vue3",
69
- "text",
70
- "wysiwyg",
71
- "wysiwym"
72
- ],
73
- "repository": {
74
- "type": "git",
75
- "url": "https://github.com/Guan-Erjia/slate-vue3"
76
- }
77
- }
1
+ {
2
+ "name": "slate-vue3",
3
+ "version": "0.0.4",
4
+ "type": "module",
5
+ "workspaces": [
6
+ "packages/*"
7
+ ],
8
+ "main": "dist/index.js",
9
+ "module": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "files": [
12
+ "dist/"
13
+ ],
14
+ "scripts": {
15
+ "dev": "vite",
16
+ "build": "vite build",
17
+ "preview": "vite preview",
18
+ "build-all": "vite build --mode=lib"
19
+ },
20
+ "dependencies": {
21
+ "direction": "^2.0.1",
22
+ "is-hotkey": "^0.2.0",
23
+ "lodash-es": "^4.17.21",
24
+ "scroll-into-view-if-needed": "^3.1.0",
25
+ "slate": "workspace:*",
26
+ "slate-dom": "workspace:*",
27
+ "slate-history": "^0.110.3",
28
+ "slate-hyperscript": "^0.100.0",
29
+ "slate-vue": "workspace:*",
30
+ "vue": "^3.5.13",
31
+ "vue-router": "^4.5.0"
32
+ },
33
+ "devDependencies": {
34
+ "@faker-js/faker": "^9.4.0",
35
+ "@types/is-hotkey": "^0.1.10",
36
+ "@types/is-url": "^1.2.32",
37
+ "@types/lodash-es": "^4.17.12",
38
+ "@types/prismjs": "^1.26.5",
39
+ "@vitejs/plugin-vue": "^5.2.1",
40
+ "@vitejs/plugin-vue-jsx": "^4.1.1",
41
+ "@vue/tsconfig": "^0.7.0",
42
+ "image-extensions": "^1.1.0",
43
+ "is-url": "^1.2.4",
44
+ "prismjs": "^1.29.0",
45
+ "typescript": "~5.7.2",
46
+ "vite": "^6.0.11",
47
+ "vite-plugin-dts": "^4.5.0",
48
+ "vue-tsc": "^2.2.0"
49
+ },
50
+ "keywords": [
51
+ "canvas",
52
+ "contenteditable",
53
+ "docs",
54
+ "document",
55
+ "edit",
56
+ "editor",
57
+ "editable",
58
+ "html",
59
+ "immutable",
60
+ "markdown",
61
+ "medium",
62
+ "paper",
63
+ "react",
64
+ "rich",
65
+ "richtext",
66
+ "richtext",
67
+ "slate",
68
+ "slate-vue3",
69
+ "text",
70
+ "wysiwyg",
71
+ "wysiwym"
72
+ ],
73
+ "repository": {
74
+ "type": "git",
75
+ "url": "https://github.com/Guan-Erjia/slate-vue3"
76
+ }
77
+ }