@handlewithcare/react-prosemirror 3.1.0-tiptap.42 → 3.1.0-tiptap.44

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.
Files changed (143) hide show
  1. package/README.md +26 -0
  2. package/dist/cjs/ReactEditorView.js +74 -70
  3. package/dist/cjs/StaticEditorView.js +21 -18
  4. package/dist/cjs/browser.js +3 -1
  5. package/dist/cjs/commands/reorderSiblings.js +13 -9
  6. package/dist/cjs/components/ChildNodeViews.js +74 -69
  7. package/dist/cjs/components/CursorWrapper.js +20 -34
  8. package/dist/cjs/components/LayoutGroup.js +16 -12
  9. package/dist/cjs/components/NativeWidgetView.js +19 -15
  10. package/dist/cjs/components/OutputSpec.js +13 -9
  11. package/dist/cjs/components/ProseMirror.js +27 -37
  12. package/dist/cjs/components/ProseMirrorDoc.js +18 -25
  13. package/dist/cjs/components/SeparatorHackView.js +20 -17
  14. package/dist/cjs/components/TextNodeView.js +20 -22
  15. package/dist/cjs/components/TrailingHackView.js +17 -13
  16. package/dist/cjs/components/WidgetView.js +18 -14
  17. package/dist/cjs/components/marks/DefaultMarkView.js +15 -27
  18. package/dist/cjs/components/marks/MarkView.js +23 -32
  19. package/dist/cjs/components/marks/MarkViewConstructorView.js +22 -38
  20. package/dist/cjs/components/marks/ReactMarkView.js +16 -27
  21. package/dist/cjs/components/nodes/DefaultNodeView.js +15 -27
  22. package/dist/cjs/components/nodes/DocNodeView.js +16 -12
  23. package/dist/cjs/components/nodes/NodeView.js +26 -33
  24. package/dist/cjs/components/nodes/NodeViewConstructorView.js +29 -45
  25. package/dist/cjs/components/nodes/ReactNodeView.js +27 -39
  26. package/dist/cjs/constants.js +10 -6
  27. package/dist/cjs/contexts/ChildDescriptionsContext.js +3 -1
  28. package/dist/cjs/contexts/EditorContext.js +3 -1
  29. package/dist/cjs/contexts/EditorStateContext.js +3 -1
  30. package/dist/cjs/contexts/IgnoreMutationContext.js +3 -1
  31. package/dist/cjs/contexts/LayoutGroupContext.js +3 -1
  32. package/dist/cjs/contexts/NodeViewContext.js +3 -1
  33. package/dist/cjs/contexts/SelectNodeContext.js +3 -1
  34. package/dist/cjs/contexts/StopEventContext.js +3 -1
  35. package/dist/cjs/decorations/ReactWidgetType.js +19 -13
  36. package/dist/cjs/decorations/computeDocDeco.js +5 -3
  37. package/dist/cjs/decorations/iterDeco.js +19 -17
  38. package/dist/cjs/decorations/viewDecorations.js +15 -12
  39. package/dist/cjs/dom.js +34 -13
  40. package/dist/cjs/findDOMNode.js +9 -5
  41. package/dist/cjs/hooks/useClientLayoutEffect.js +3 -1
  42. package/dist/cjs/hooks/useComponentEventListeners.js +7 -6
  43. package/dist/cjs/hooks/useEditor.js +29 -32
  44. package/dist/cjs/hooks/useEditorEffect.js +9 -7
  45. package/dist/cjs/hooks/useEditorEventCallback.js +9 -7
  46. package/dist/cjs/hooks/useEditorEventListener.js +8 -6
  47. package/dist/cjs/hooks/useEditorState.js +5 -3
  48. package/dist/cjs/hooks/useEffectEvent.js +3 -1
  49. package/dist/cjs/hooks/useForceUpdate.js +3 -1
  50. package/dist/cjs/hooks/useIgnoreMutation.js +9 -7
  51. package/dist/cjs/hooks/useIsEditorStatic.js +5 -5
  52. package/dist/cjs/hooks/useIsNodeSelected.js +5 -3
  53. package/dist/cjs/hooks/useLayoutGroupEffect.js +7 -5
  54. package/dist/cjs/hooks/useMarkViewDescription.js +31 -25
  55. package/dist/cjs/hooks/useNodePos.js +7 -5
  56. package/dist/cjs/hooks/useNodeViewDescription.js +32 -28
  57. package/dist/cjs/hooks/useReactKeys.js +7 -5
  58. package/dist/cjs/hooks/useSelectNode.js +10 -8
  59. package/dist/cjs/hooks/useStopEvent.js +9 -7
  60. package/dist/cjs/index.js +66 -34
  61. package/dist/cjs/plugins/beforeInputPlugin.js +51 -24
  62. package/dist/cjs/plugins/componentEventListeners.js +8 -6
  63. package/dist/cjs/plugins/componentEventListenersPlugin.js +8 -6
  64. package/dist/cjs/plugins/reactKeys.js +15 -10
  65. package/dist/cjs/props.js +23 -19
  66. package/dist/cjs/refs.js +3 -1
  67. package/dist/cjs/testing/editorViewTestHelpers.js +40 -47
  68. package/dist/cjs/testing/setupProseMirrorView.js +7 -4
  69. package/dist/cjs/tiptap/ReactProseMirrorNodeView.js +10 -6
  70. package/dist/cjs/tiptap/TiptapEditor.js +15 -14
  71. package/dist/cjs/tiptap/TiptapEditorContent.js +18 -28
  72. package/dist/cjs/tiptap/TiptapEditorView.js +23 -34
  73. package/dist/cjs/tiptap/contexts/TiptapEditorContext.js +3 -1
  74. package/dist/cjs/tiptap/extensions/ReactProseMirror.js +8 -6
  75. package/dist/cjs/tiptap/extensions/ReactProseMirrorCommands.js +5 -3
  76. package/dist/cjs/tiptap/extensions/commands/updateAttributes.js +4 -2
  77. package/dist/cjs/tiptap/hooks/useIsInReactProseMirror.js +5 -3
  78. package/dist/cjs/tiptap/hooks/useTiptapEditor.js +12 -14
  79. package/dist/cjs/tiptap/hooks/useTiptapEditorEffect.js +12 -10
  80. package/dist/cjs/tiptap/hooks/useTiptapEditorEventCallback.js +6 -4
  81. package/dist/cjs/tiptap/index.js +36 -18
  82. package/dist/cjs/tiptap/tiptapNodeView.js +48 -62
  83. package/dist/cjs/viewdesc.js +119 -89
  84. package/dist/esm/ReactEditorView.js +68 -66
  85. package/dist/esm/StaticEditorView.js +18 -17
  86. package/dist/esm/commands/reorderSiblings.js +5 -5
  87. package/dist/esm/components/ChildNodeViews.js +36 -37
  88. package/dist/esm/components/CursorWrapper.js +10 -28
  89. package/dist/esm/components/LayoutGroup.js +1 -1
  90. package/dist/esm/components/NativeWidgetView.js +2 -2
  91. package/dist/esm/components/OutputSpec.js +1 -1
  92. package/dist/esm/components/ProseMirror.js +4 -18
  93. package/dist/esm/components/ProseMirrorDoc.js +6 -19
  94. package/dist/esm/components/SeparatorHackView.js +3 -4
  95. package/dist/esm/components/TextNodeView.js +6 -10
  96. package/dist/esm/components/TrailingHackView.js +2 -2
  97. package/dist/esm/components/WidgetView.js +3 -3
  98. package/dist/esm/components/marks/DefaultMarkView.js +6 -22
  99. package/dist/esm/components/marks/MarkView.js +11 -24
  100. package/dist/esm/components/marks/MarkViewConstructorView.js +7 -27
  101. package/dist/esm/components/marks/ReactMarkView.js +3 -18
  102. package/dist/esm/components/nodes/DefaultNodeView.js +6 -22
  103. package/dist/esm/components/nodes/DocNodeView.js +2 -2
  104. package/dist/esm/components/nodes/NodeView.js +11 -24
  105. package/dist/esm/components/nodes/NodeViewConstructorView.js +11 -31
  106. package/dist/esm/components/nodes/ReactNodeView.js +6 -22
  107. package/dist/esm/decorations/ReactWidgetType.js +10 -8
  108. package/dist/esm/decorations/iterDeco.js +13 -13
  109. package/dist/esm/decorations/viewDecorations.js +7 -6
  110. package/dist/esm/dom.js +1 -2
  111. package/dist/esm/findDOMNode.js +1 -1
  112. package/dist/esm/hooks/useComponentEventListeners.js +2 -3
  113. package/dist/esm/hooks/useEditor.js +6 -11
  114. package/dist/esm/hooks/useEditorEffect.js +1 -1
  115. package/dist/esm/hooks/useEditorEventCallback.js +1 -1
  116. package/dist/esm/hooks/useEditorEventListener.js +1 -1
  117. package/dist/esm/hooks/useIsEditorStatic.js +1 -3
  118. package/dist/esm/hooks/useMarkViewDescription.js +14 -10
  119. package/dist/esm/hooks/useNodeViewDescription.js +10 -8
  120. package/dist/esm/hooks/useReactKeys.js +1 -1
  121. package/dist/esm/plugins/beforeInputPlugin.js +44 -19
  122. package/dist/esm/plugins/reactKeys.js +3 -4
  123. package/dist/esm/props.js +15 -15
  124. package/dist/esm/testing/editorViewTestHelpers.js +20 -31
  125. package/dist/esm/testing/setupProseMirrorView.js +1 -2
  126. package/dist/esm/tiptap/ReactProseMirrorNodeView.js +7 -5
  127. package/dist/esm/tiptap/TiptapEditor.js +9 -10
  128. package/dist/esm/tiptap/TiptapEditorContent.js +4 -18
  129. package/dist/esm/tiptap/TiptapEditorView.js +8 -23
  130. package/dist/esm/tiptap/extensions/ReactProseMirror.js +1 -1
  131. package/dist/esm/tiptap/extensions/commands/updateAttributes.js +1 -1
  132. package/dist/esm/tiptap/hooks/useTiptapEditor.js +4 -8
  133. package/dist/esm/tiptap/hooks/useTiptapEditorEffect.js +4 -4
  134. package/dist/esm/tiptap/hooks/useTiptapEditorEventCallback.js +1 -1
  135. package/dist/esm/tiptap/tiptapNodeView.js +20 -38
  136. package/dist/esm/viewdesc.js +74 -66
  137. package/dist/tsconfig.tsbuildinfo +1 -1
  138. package/dist/types/constants.d.ts +1 -1
  139. package/dist/types/contexts/EditorContext.d.ts +1 -2
  140. package/dist/types/hooks/useEditor.d.ts +1 -1
  141. package/dist/types/props.d.ts +8 -8
  142. package/dist/types/testing/editorViewTestHelpers.d.ts +1 -0
  143. package/package.json +1 -2
@@ -43,41 +43,41 @@ onWidget, onNode) {
43
43
  if (widget) {
44
44
  if (widgets) {
45
45
  widgets.sort(compareSide);
46
- for(let i1 = 0; i1 < widgets.length; i1++)onWidget(widgets[i1], // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- !(widgets[i1].type instanceof ReactWidgetType), offset, parentIndex + i1, !!restNode);
46
+ for(let i = 0; i < widgets.length; i++)onWidget(widgets[i], // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ !(widgets[i].type instanceof ReactWidgetType), offset, parentIndex + i, !!restNode);
48
48
  } else {
49
49
  onWidget(widget, // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
50
  !(widget.type instanceof ReactWidgetType), offset, parentIndex, !!restNode);
51
51
  }
52
52
  }
53
53
  }
54
- let child1, index;
54
+ let child, index;
55
55
  if (restNode) {
56
56
  index = -1;
57
- child1 = restNode;
57
+ child = restNode;
58
58
  restNode = null;
59
59
  } else if (parentIndex < parent.childCount) {
60
60
  index = parentIndex;
61
- child1 = parent.child(parentIndex++);
61
+ child = parent.child(parentIndex++);
62
62
  } else {
63
63
  break;
64
64
  }
65
- for(let i2 = 0; i2 < active.length; i2++)if (active[i2].to <= offset) active.splice(i2--, 1);
65
+ for(let i = 0; i < active.length; i++)if (active[i].to <= offset) active.splice(i--, 1);
66
66
  while(decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset)active.push(locals[decoIndex++]);
67
- let end = offset + child1.nodeSize;
68
- if (child1.isText) {
67
+ let end = offset + child.nodeSize;
68
+ if (child.isText) {
69
69
  let cutAt = end;
70
70
  if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from;
71
- for(let i3 = 0; i3 < active.length; i3++)if (active[i3].to < cutAt) cutAt = active[i3].to;
71
+ for(let i = 0; i < active.length; i++)if (active[i].to < cutAt) cutAt = active[i].to;
72
72
  if (cutAt < end) {
73
- restNode = child1.cut(cutAt - offset);
74
- child1 = child1.cut(0, cutAt - offset);
73
+ restNode = child.cut(cutAt - offset);
74
+ child = child.cut(0, cutAt - offset);
75
75
  end = cutAt;
76
76
  index = -1;
77
77
  }
78
78
  }
79
- const outerDeco = child1.isInline && !child1.isLeaf ? active.filter((d)=>!d.inline) : active.slice();
80
- onNode(child1, outerDeco, deco.forChild(offset, child1), offset, index);
79
+ const outerDeco = child.isInline && !child.isLeaf ? active.filter((d)=>!d.inline) : active.slice();
80
+ onNode(child, outerDeco, deco.forChild(offset, child), offset, index);
81
81
  offset = end;
82
82
  }
83
83
  }
@@ -6,6 +6,10 @@ const empty = DecorationSet.empty;
6
6
  // treat multiple DecorationSet objects as if it were a single object
7
7
  // with (a subset of) the same interface.
8
8
  let DecorationGroup = class DecorationGroup {
9
+ members;
10
+ constructor(members){
11
+ this.members = members;
12
+ }
9
13
  map(mapping, doc) {
10
14
  const mappedDecos = this.members.map((member)=>member.map(mapping, doc, noSpec));
11
15
  return DecorationGroup.from(mappedDecos);
@@ -61,9 +65,6 @@ let DecorationGroup = class DecorationGroup {
61
65
  for(let i = 0; i < this.members.length; i++)// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
62
66
  this.members[i].forEachSet(f);
63
67
  }
64
- constructor(members){
65
- this.members = members;
66
- }
67
68
  };
68
69
  // Used to sort decorations so that ones with a low start position
69
70
  // come first, and within a set with the same start position, those
@@ -151,9 +152,9 @@ const ViewDecorationsCache = new WeakMap();
151
152
  areSetsEqual = false;
152
153
  }
153
154
  if (!areSetsEqual) {
154
- const result1 = DecorationGroup.from(found);
155
- ViewDecorationsCache.set(view, result1);
156
- return result1;
155
+ const result = DecorationGroup.from(found);
156
+ ViewDecorationsCache.set(view, result);
157
+ return result;
157
158
  }
158
159
  return previous;
159
160
  }
package/dist/esm/dom.js CHANGED
@@ -36,8 +36,7 @@ function scanFor(node, off, targetNode, targetOff, dir) {
36
36
  } else if (node.nodeType == 1) {
37
37
  const child = node.childNodes[off + (dir < 0 ? -1 : 0)];
38
38
  if (child.nodeType == 1 && child.contentEditable == "false") {
39
- var ref;
40
- if ((ref = child.pmViewDesc) === null || ref === void 0 ? void 0 : ref.ignoreForSelection) off += dir;
39
+ if (child.pmViewDesc?.ignoreForSelection) off += dir;
41
40
  else return false;
42
41
  } else {
43
42
  node = child;
@@ -16,7 +16,7 @@ function findHostInstance(component) {
16
16
  throw new Error("Unable to find node on an unmounted component.");
17
17
  } else {
18
18
  const keys = Object.keys(component).join(",");
19
- throw new Error("Argument appears to not be a ReactComponent. Keys: ".concat(keys));
19
+ throw new Error(`Argument appears to not be a ReactComponent. Keys: ${keys}`);
20
20
  }
21
21
  }
22
22
  const hostFiber = findCurrentHostFiber(fiber);
@@ -28,8 +28,7 @@ import { componentEventListeners } from "../plugins/componentEventListeners.js";
28
28
  */ export function useComponentEventListeners() {
29
29
  const [registry, setRegistry] = useState(new Map());
30
30
  const registerEventListener = useCallback((eventType, handler)=>{
31
- var ref;
32
- const handlers = (ref = registry.get(eventType)) !== null && ref !== void 0 ? ref : [];
31
+ const handlers = registry.get(eventType) ?? [];
33
32
  handlers.unshift(handler);
34
33
  if (!registry.has(eventType)) {
35
34
  registry.set(eventType, handlers);
@@ -40,7 +39,7 @@ import { componentEventListeners } from "../plugins/componentEventListeners.js";
40
39
  ]);
41
40
  const unregisterEventListener = useCallback((eventType, handler)=>{
42
41
  const handlers = registry.get(eventType);
43
- handlers === null || handlers === void 0 ? void 0 : handlers.splice(handlers.indexOf(handler), 1);
42
+ handlers?.splice(handlers.indexOf(handler), 1);
44
43
  }, [
45
44
  registry
46
45
  ]);
@@ -27,20 +27,17 @@ let didWarnValueDefaultValue = false;
27
27
  const flushSyncRef = useRef(true);
28
28
  const [cursorWrapper, _setCursorWrapper] = useState(null);
29
29
  const forceUpdate = useForceUpdate();
30
- var _defaultState;
31
- const defaultState = (_defaultState = options.defaultState) !== null && _defaultState !== void 0 ? _defaultState : EMPTY_STATE;
30
+ const defaultState = options.defaultState ?? EMPTY_STATE;
32
31
  const [_state, setState] = useState(defaultState);
33
- var _state1;
34
- const state = (_state1 = options.state) !== null && _state1 !== void 0 ? _state1 : _state;
35
- const { componentEventListenersPlugin , registerEventListener , unregisterEventListener } = useComponentEventListeners();
32
+ const state = options.state ?? _state;
33
+ const { componentEventListenersPlugin, registerEventListener, unregisterEventListener } = useComponentEventListeners();
36
34
  const setCursorWrapper = useCallback((deco)=>{
37
35
  flushSync(()=>{
38
36
  _setCursorWrapper(deco);
39
37
  });
40
38
  }, []);
41
- var _plugins;
42
39
  const plugins = useMemo(()=>[
43
- ...(_plugins = options.plugins) !== null && _plugins !== void 0 ? _plugins : [],
40
+ ...options.plugins ?? [],
44
41
  componentEventListenersPlugin,
45
42
  beforeInputPlugin(setCursorWrapper)
46
43
  ], [
@@ -112,16 +109,13 @@ let didWarnValueDefaultValue = false;
112
109
  }
113
110
  });
114
111
  view.update(directEditorProps);
115
- var _static;
116
112
  const editor = useMemo(()=>({
117
113
  view,
118
- cursorWrapper,
119
114
  flushSyncRef,
120
115
  registerEventListener,
121
116
  unregisterEventListener,
122
- isStatic: (_static = options.static) !== null && _static !== void 0 ? _static : false
117
+ isStatic: options.static ?? false
123
118
  }), [
124
- cursorWrapper,
125
119
  options.static,
126
120
  registerEventListener,
127
121
  unregisterEventListener,
@@ -129,6 +123,7 @@ let didWarnValueDefaultValue = false;
129
123
  ]);
130
124
  return {
131
125
  editor,
126
+ cursorWrapper,
132
127
  state
133
128
  };
134
129
  }
@@ -20,7 +20,7 @@ import { useLayoutGroupEffect } from "./useLayoutGroupEffect.js";
20
20
  * as a child of the TiptapEditorView component, including
21
21
  * React node view components.
22
22
  */ export function useEditorEffect(effect, dependencies) {
23
- const { view , flushSyncRef } = useContext(EditorContext);
23
+ const { view, flushSyncRef } = useContext(EditorContext);
24
24
  // The rules of hooks want `effect` to be included in the
25
25
  // dependency list, but dependency issues for `effect` will
26
26
  // be caught by the linter at the call-site for
@@ -20,7 +20,7 @@ function assertIsReactEditorView(view) {
20
20
  * React node view components.
21
21
  */ export function useEditorEventCallback(callback) {
22
22
  const ref = useRef(callback);
23
- const { view } = useContext(EditorContext);
23
+ const { view } = useContext(EditorContext);
24
24
  useEditorEffect(()=>{
25
25
  ref.current = callback;
26
26
  }, [
@@ -6,7 +6,7 @@ import { useEditorEffect } from "./useEditorEffect.js";
6
6
  * [the ProseMirror docs](https://prosemirror.net/docs/ref/#view.EditorProps.handleDOMEvents)
7
7
  * for more details.
8
8
  */ export function useEditorEventListener(eventType, handler) {
9
- const { registerEventListener , unregisterEventListener } = useContext(EditorContext);
9
+ const { registerEventListener, unregisterEventListener } = useContext(EditorContext);
10
10
  const ref = useRef(handler);
11
11
  useEditorEffect(()=>{
12
12
  ref.current = handler;
@@ -1,7 +1,5 @@
1
1
  import { useContext } from "react";
2
2
  import { EditorContext } from "../contexts/EditorContext.js";
3
3
  export function useIsEditorStatic() {
4
- var ref;
5
- var ref1;
6
- return (ref1 = (ref = useContext(EditorContext)) === null || ref === void 0 ? void 0 : ref.isStatic) !== null && ref1 !== void 0 ? ref1 : false;
4
+ return useContext(EditorContext)?.isStatic ?? false;
7
5
  }
@@ -6,9 +6,8 @@ import { ReactMarkViewDesc, sortViewDescs } from "../viewdesc.js";
6
6
  import { useClientLayoutEffect } from "./useClientLayoutEffect.js";
7
7
  import { useEffectEvent } from "./useEffectEvent.js";
8
8
  export function useMarkViewDescription(getDOM, getContentDOM, constructor, props) {
9
- var ref;
10
- const { view } = useContext(EditorContext);
11
- const { parentRef , siblingsRef } = useContext(ChildDescriptionsContext);
9
+ const { view } = useContext(EditorContext);
10
+ const { parentRef, siblingsRef } = useContext(ChildDescriptionsContext);
12
11
  const contentDOMRef = useRef(null);
13
12
  const viewDescRef = useRef();
14
13
  const childrenRef = useRef([]);
@@ -20,7 +19,7 @@ export function useMarkViewDescription(getDOM, getContentDOM, constructor, props
20
19
  if (!dom) {
21
20
  return;
22
21
  }
23
- const { mark , inline , getPos } = props;
22
+ const { mark, inline, getPos } = props;
24
23
  const markView = constructor(mark, view, inline);
25
24
  if (!markView) {
26
25
  return;
@@ -28,7 +27,14 @@ export function useMarkViewDescription(getDOM, getContentDOM, constructor, props
28
27
  const parent = parentRef.current;
29
28
  const children = childrenRef.current;
30
29
  const contentDOM = getContentDOM(markView);
31
- const viewDesc = new ReactMarkViewDesc(parent, children, getPos, mark, dom, contentDOM !== null && contentDOM !== void 0 ? contentDOM : markView.dom, markView);
30
+ const viewDesc = new ReactMarkViewDesc(parent, children, getPos, mark, dom, contentDOM ?? markView.dom, markView);
31
+ // When create() runs after a destroy() (either here in a layout
32
+ // effect or in refUpdated), the inherited children still reference
33
+ // the just-destroyed desc. Re-parent them onto this fresh desc
34
+ // before any other code can observe the stale pointer.
35
+ for (const child of children){
36
+ child.parent = viewDesc;
37
+ }
32
38
  contentDOMRef.current = contentDOM;
33
39
  return viewDesc;
34
40
  });
@@ -45,11 +51,10 @@ export function useMarkViewDescription(getDOM, getContentDOM, constructor, props
45
51
  return false;
46
52
  }
47
53
  const contentDOM = getContentDOM(viewDesc);
48
- var _contentDOM;
49
- if (contentDOM !== ((_contentDOM = viewDesc.contentDOM) !== null && _contentDOM !== void 0 ? _contentDOM : dom)) {
54
+ if (contentDOM !== (viewDesc.contentDOM ?? dom)) {
50
55
  return false;
51
56
  }
52
- const { mark } = props;
57
+ const { mark } = props;
53
58
  return viewDesc.matchesMark(mark);
54
59
  });
55
60
  const destroy = useEffectEvent(()=>{
@@ -112,10 +117,9 @@ export function useMarkViewDescription(getDOM, getContentDOM, constructor, props
112
117
  childrenRef,
113
118
  viewDescRef
114
119
  ]);
115
- var _current;
116
120
  return {
117
121
  childContextValue,
118
- contentDOM: (_current = contentDOMRef.current) !== null && _current !== void 0 ? _current : (ref = viewDescRef.current) === null || ref === void 0 ? void 0 : ref.dom,
122
+ contentDOM: contentDOMRef.current ?? viewDescRef.current?.dom,
119
123
  refUpdated
120
124
  };
121
125
  }
@@ -6,8 +6,8 @@ import { CompositionViewDesc, ReactNodeViewDesc, sortViewDescs } from "../viewde
6
6
  import { useClientLayoutEffect } from "./useClientLayoutEffect.js";
7
7
  import { useEffectEvent } from "./useEffectEvent.js";
8
8
  export function useNodeViewDescription(getDOM, getContentDOM, constructor, props) {
9
- const { view } = useContext(EditorContext);
10
- const { parentRef , siblingsRef } = useContext(ChildDescriptionsContext);
9
+ const { view } = useContext(EditorContext);
10
+ const { parentRef, siblingsRef } = useContext(ChildDescriptionsContext);
11
11
  const contentDOMRef = useRef(null);
12
12
  const viewDescRef = useRef();
13
13
  const childrenRef = useRef([]);
@@ -19,7 +19,7 @@ export function useNodeViewDescription(getDOM, getContentDOM, constructor, props
19
19
  if (!dom) {
20
20
  return;
21
21
  }
22
- const { node , getPos , decorations , innerDecorations } = props;
22
+ const { node, getPos, decorations, innerDecorations } = props;
23
23
  const nodeView = constructor(node, view, getPos, decorations, innerDecorations);
24
24
  if (!nodeView) {
25
25
  return;
@@ -29,6 +29,9 @@ export function useNodeViewDescription(getDOM, getContentDOM, constructor, props
29
29
  const contentDOM = getContentDOM(nodeView);
30
30
  const nodeDOM = nodeView.dom;
31
31
  const viewDesc = new ReactNodeViewDesc(parent, children, getPos, node, decorations, innerDecorations, dom, contentDOM, nodeDOM, nodeView);
32
+ for (const child of children){
33
+ child.parent = viewDesc;
34
+ }
32
35
  const siblings = siblingsRef.current;
33
36
  if (!siblings.includes(viewDesc)) {
34
37
  siblings.push(viewDesc);
@@ -56,7 +59,7 @@ export function useNodeViewDescription(getDOM, getContentDOM, constructor, props
56
59
  if (!dom.contains(viewDesc.nodeDOM)) {
57
60
  return false;
58
61
  }
59
- const { node , decorations , innerDecorations } = props;
62
+ const { node, decorations, innerDecorations } = props;
60
63
  return viewDesc.matchesNode(node, decorations, innerDecorations) || viewDesc.update(node, decorations, innerDecorations, view);
61
64
  });
62
65
  const destroy = useEffectEvent(()=>{
@@ -131,14 +134,13 @@ export function useNodeViewDescription(getDOM, getContentDOM, constructor, props
131
134
  // Because TextNodeViews can't locate the DOM nodes
132
135
  // for compositions, we need to override them here
133
136
  if (child instanceof CompositionViewDesc) {
134
- var ref;
135
- const compositionTopDOM = viewDesc === null || viewDesc === void 0 ? void 0 : (ref = viewDesc.contentDOM) === null || ref === void 0 ? void 0 : ref.firstChild;
136
- if (!compositionTopDOM) throw new Error("Started a composition but couldn't find the text node it belongs to.");
137
+ const compositionTopDOM = viewDesc?.contentDOM?.firstChild;
138
+ if (!compositionTopDOM) throw new Error(`Started a composition but couldn't find the text node it belongs to.`);
137
139
  let textDOM = compositionTopDOM;
138
140
  while(textDOM.firstChild){
139
141
  textDOM = textDOM.firstChild;
140
142
  }
141
- if (!textDOM || !(textDOM instanceof Text)) throw new Error("Started a composition but couldn't find the text node it belongs to.");
143
+ if (!textDOM || !(textDOM instanceof Text)) throw new Error(`Started a composition but couldn't find the text node it belongs to.`);
142
144
  child.dom = compositionTopDOM;
143
145
  child.textDOM = textDOM;
144
146
  child.text = textDOM.data;
@@ -2,6 +2,6 @@ import { useContext } from "react";
2
2
  import { EditorContext } from "../contexts/EditorContext.js";
3
3
  import { reactKeysPluginKey } from "../plugins/reactKeys.js";
4
4
  export function useReactKeys() {
5
- const { view } = useContext(EditorContext);
5
+ const { view } = useContext(EditorContext);
6
6
  return reactKeysPluginKey.getState(view.state);
7
7
  }
@@ -1,22 +1,49 @@
1
- import { Plugin } from "prosemirror-state";
1
+ import { Fragment, Slice } from "prosemirror-model";
2
+ import { Plugin, TextSelection } from "prosemirror-state";
2
3
  import { CursorWrapper } from "../components/CursorWrapper.js";
3
4
  import { widget } from "../decorations/ReactWidgetType.js";
4
5
  function insertText(view, eventData) {
5
6
  let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
6
7
  if (eventData === null) return false;
7
- var _from;
8
- const from = (_from = options.from) !== null && _from !== void 0 ? _from : view.state.selection.from;
9
- var _to;
10
- const to = (_to = options.to) !== null && _to !== void 0 ? _to : view.state.selection.to;
8
+ const from = options.from ?? view.state.selection.from;
9
+ const to = options.to ?? view.state.selection.to;
11
10
  if (view.someProp("handleTextInput", (f)=>f(view, from, to, eventData, ()=>view.state.tr.insertText(eventData, from, to)))) {
12
11
  return true;
13
12
  }
14
- const { tr } = view.state;
13
+ const { tr } = view.state;
15
14
  if (options.marks) tr.ensureMarks(options.marks);
16
15
  tr.insertText(eventData, from, to);
17
16
  view.dispatch(tr);
18
17
  return true;
19
18
  }
19
+ // Taken from https://github.com/ProseMirror/prosemirror-gapcursor/blob/master/src/index.ts#L67-L84
20
+ // This is a hack that, when a composition starts while a gap cursor
21
+ // is active, quickly creates an inline context for the composition to
22
+ // happen in, to avoid it being aborted by the DOM selection being
23
+ // moved into a valid position.
24
+ //
25
+ // We can't rely on the actual hack from prosemirror-gapcursor, because
26
+ // it happens too late. We snapshot the DOM during compositionstart, but
27
+ // the gapcursor hack runs in beforeinput (after compositionstart).
28
+ function handleGapCursorComposition(view) {
29
+ // @ts-expect-error Internal property - jsonID
30
+ if (!(view.state.selection.jsonID === "gapcursor")) {
31
+ return;
32
+ }
33
+ const { $from } = view.state.selection;
34
+ const insert = $from.parent.contentMatchAt($from.index())// All schemas _must_ have a text node type
35
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36
+ .findWrapping(view.state.schema.nodes.text);
37
+ if (!insert) return;
38
+ let fragment = Fragment.empty;
39
+ for(let i = insert.length - 1; i >= 0; i--){
40
+ fragment = Fragment.from(// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
41
+ insert[i].createAndFill(null, fragment));
42
+ }
43
+ const tr = view.state.tr.replace($from.pos, $from.pos, new Slice(fragment, 0, 0));
44
+ tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
45
+ view.dispatch(tr);
46
+ }
20
47
  export function beforeInputPlugin(setCursorWrapper) {
21
48
  let compositionMarks = null;
22
49
  let precompositionSnapshot = null;
@@ -24,11 +51,11 @@ export function beforeInputPlugin(setCursorWrapper) {
24
51
  props: {
25
52
  handleDOMEvents: {
26
53
  compositionstart (view) {
27
- const { state } = view;
28
- view.dispatch(state.tr.deleteSelection());
54
+ compositionMarks = view.state.storedMarks ?? view.state.selection.$from.marks();
55
+ view.dispatch(view.state.tr.deleteSelection());
56
+ handleGapCursorComposition(view);
57
+ const { state } = view;
29
58
  const $pos = state.selection.$from;
30
- var _storedMarks;
31
- compositionMarks = (_storedMarks = state.storedMarks) !== null && _storedMarks !== void 0 ? _storedMarks : $pos.marks();
32
59
  if (compositionMarks) {
33
60
  setCursorWrapper(widget(state.selection.from, CursorWrapper, {
34
61
  key: "cursor-wrapper",
@@ -38,7 +65,7 @@ export function beforeInputPlugin(setCursorWrapper) {
38
65
  // Snapshot the siblings of the node that contains the
39
66
  // current cursor. We'll restore this later, so that React
40
67
  // doesn't panic about unknown DOM nodes.
41
- const { node: parent } = view.domAtPos($pos.pos);
68
+ const { node: parent } = view.domAtPos($pos.pos);
42
69
  precompositionSnapshot = [];
43
70
  for (const node of parent.childNodes){
44
71
  precompositionSnapshot.push(node);
@@ -53,8 +80,8 @@ export function beforeInputPlugin(setCursorWrapper) {
53
80
  compositionend (view, event) {
54
81
  // @ts-expect-error Internal property - input
55
82
  view.input.composing = false;
56
- const { state } = view;
57
- const { node: parent } = view.domAtPos(state.selection.from);
83
+ const { state } = view;
84
+ const { node: parent } = view.domAtPos(state.selection.from);
58
85
  if (precompositionSnapshot) {
59
86
  // Restore the snapshot of the parent node's children
60
87
  // from before the composition started. This gives us a
@@ -106,15 +133,13 @@ export function beforeInputPlugin(setCursorWrapper) {
106
133
  keyCode: 13,
107
134
  shiftKey: event.inputType === "insertLineBreak"
108
135
  });
109
- var ref;
110
136
  // Use someProp to directly call ProseMirror handlers
111
- return (ref = view.someProp("handleKeyDown", (f)=>f(view, keyEvent))) !== null && ref !== void 0 ? ref : false;
137
+ return view.someProp("handleKeyDown", (f)=>f(view, keyEvent)) ?? false;
112
138
  }
113
139
  case "insertReplacementText":
114
140
  {
115
- var ref1, ref2;
116
141
  const ranges = event.getTargetRanges();
117
- (ref2 = (ref1 = event.dataTransfer) === null || ref1 === void 0 ? void 0 : ref1.items[0]) === null || ref2 === void 0 ? void 0 : ref2.getAsString((data)=>{
142
+ event.dataTransfer?.items[0]?.getAsString((data)=>{
118
143
  for (const range of ranges){
119
144
  const from = view.posAtDOM(range.startContainer, range.startOffset, 1);
120
145
  const to = view.posAtDOM(range.endContainer, range.endOffset, 1);
@@ -142,11 +167,11 @@ export function beforeInputPlugin(setCursorWrapper) {
142
167
  case "deleteContent":
143
168
  {
144
169
  const targetRanges = event.getTargetRanges();
145
- const { tr } = view.state;
170
+ const { tr } = view.state;
146
171
  for (const range of targetRanges){
147
172
  const start = view.posAtDOM(range.startContainer, range.startOffset);
148
173
  const end = view.posAtDOM(range.endContainer, range.endOffset);
149
- const { doc } = view.state;
174
+ const { doc } = view.state;
150
175
  const storedMarks = doc.resolve(start).marksAcross(doc.resolve(end));
151
176
  tr.delete(start, end).setStoredMarks(storedMarks);
152
177
  }
@@ -36,11 +36,10 @@ export const reactKeysPluginKey = new PluginKey("@handlewithcare/react-prosemirr
36
36
  * and assign its key to that new position, dropping it if the
37
37
  * node was deleted.
38
38
  */ apply (tr, value, _, newState) {
39
- var ref;
40
39
  if (!tr.docChanged || composing) {
41
40
  return value;
42
41
  }
43
- const overrides = (ref = tr.getMeta(reactKeysPluginKey)) === null || ref === void 0 ? void 0 : ref.overrides;
42
+ const overrides = tr.getMeta(reactKeysPluginKey)?.overrides;
44
43
  const next = {
45
44
  posToKey: new Map(),
46
45
  keyToPos: new Map()
@@ -50,8 +49,8 @@ export const reactKeysPluginKey = new PluginKey("@handlewithcare/react-prosemirr
50
49
  return a - b;
51
50
  });
52
51
  for (const [pos, key] of posToKeyEntries){
53
- const override = overrides === null || overrides === void 0 ? void 0 : overrides[pos];
54
- const { pos: newPos , deleted } = override === undefined ? tr.mapping.mapResult(pos) : {
52
+ const override = overrides?.[pos];
53
+ const { pos: newPos, deleted } = override === undefined ? tr.mapping.mapResult(pos) : {
55
54
  pos: override,
56
55
  deleted: false
57
56
  };
package/dist/esm/props.js CHANGED
@@ -25,7 +25,7 @@ function mergeStyleProps(a, b) {
25
25
  if (!("STYLE" in b) || typeof b.STYLE !== "string") {
26
26
  return a.STYLE;
27
27
  }
28
- return "".concat(a.STYLE.match(/;\s*$/) ? a.STYLE : "".concat(a.STYLE, ";"), " ").concat(b.STYLE);
28
+ return `${a.STYLE.match(/;\s*$/) ? a.STYLE : `${a.STYLE};`} ${b.STYLE}`;
29
29
  }
30
30
  /**
31
31
  * Merges two sets of React props. Class names
@@ -178,32 +178,32 @@ function mergeStyleProps(a, b) {
178
178
  }
179
179
  case "maxlength":
180
180
  {
181
- const numValue1 = parseInt(attrValue, 10);
182
- if (!Number.isNaN(numValue1)) {
181
+ const numValue = parseInt(attrValue, 10);
182
+ if (!Number.isNaN(numValue)) {
183
183
  props.maxLength = attrValue;
184
184
  }
185
185
  break;
186
186
  }
187
187
  case "minlength":
188
188
  {
189
- const numValue2 = parseInt(attrValue, 10);
190
- if (!Number.isNaN(numValue2)) {
189
+ const numValue = parseInt(attrValue, 10);
190
+ if (!Number.isNaN(numValue)) {
191
191
  props.minLength = attrValue;
192
192
  }
193
193
  break;
194
194
  }
195
195
  case "max":
196
196
  {
197
- const numValue3 = parseInt(attrValue, 10);
198
- if (!Number.isNaN(numValue3)) {
197
+ const numValue = parseInt(attrValue, 10);
198
+ if (!Number.isNaN(numValue)) {
199
199
  props.max = attrValue;
200
200
  }
201
201
  break;
202
202
  }
203
203
  case "min":
204
204
  {
205
- const numValue4 = parseInt(attrValue, 10);
206
- if (!Number.isNaN(numValue4)) {
205
+ const numValue = parseInt(attrValue, 10);
206
+ if (!Number.isNaN(numValue)) {
207
207
  props.min = attrValue;
208
208
  }
209
209
  break;
@@ -225,8 +225,8 @@ function mergeStyleProps(a, b) {
225
225
  }
226
226
  case "size":
227
227
  {
228
- const numValue5 = parseInt(attrValue, 10);
229
- if (!Number.isNaN(numValue5)) {
228
+ const numValue = parseInt(attrValue, 10);
229
+ if (!Number.isNaN(numValue)) {
230
230
  props.size = attrValue;
231
231
  }
232
232
  break;
@@ -237,8 +237,8 @@ function mergeStyleProps(a, b) {
237
237
  props.step = attrValue;
238
238
  break;
239
239
  }
240
- const numValue6 = parseInt(attrValue, 10);
241
- if (!Number.isNaN(numValue6) && numValue6 > 0) {
240
+ const numValue = parseInt(attrValue, 10);
241
+ if (!Number.isNaN(numValue) && numValue > 0) {
242
242
  props.step = attrValue;
243
243
  }
244
244
  break;
@@ -250,8 +250,8 @@ function mergeStyleProps(a, b) {
250
250
  }
251
251
  case "rows":
252
252
  {
253
- const numValue7 = parseInt(attrValue, 10);
254
- if (!Number.isNaN(numValue7)) {
253
+ const numValue = parseInt(attrValue, 10);
254
+ if (!Number.isNaN(numValue)) {
255
255
  props.rows = attrValue;
256
256
  }
257
257
  break;