@handlewithcare/react-prosemirror 2.4.12 → 2.5.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.
Files changed (149) hide show
  1. package/dist/cjs/AbstractEditorView.js +4 -0
  2. package/dist/cjs/ReactEditorView.js +156 -0
  3. package/dist/cjs/StaticEditorView.js +86 -0
  4. package/dist/cjs/components/ChildNodeViews.js +58 -29
  5. package/dist/cjs/components/CustomNodeView.js +77 -137
  6. package/dist/cjs/{hooks/useNodePos.js → components/DefaultNodeView.js} +24 -26
  7. package/dist/cjs/components/DocNodeView.js +33 -41
  8. package/dist/cjs/components/MarkView.js +1 -2
  9. package/dist/cjs/components/NativeWidgetView.js +2 -3
  10. package/dist/cjs/components/NodeView.js +31 -21
  11. package/dist/cjs/components/ProseMirror.js +25 -17
  12. package/dist/cjs/components/ProseMirrorDoc.js +7 -27
  13. package/dist/cjs/components/ReactNodeView.js +98 -61
  14. package/dist/cjs/components/SeparatorHackView.js +1 -2
  15. package/dist/cjs/components/TextNodeView.js +4 -5
  16. package/dist/cjs/components/TrailingHackView.js +1 -2
  17. package/dist/cjs/components/WidgetView.js +2 -4
  18. package/dist/cjs/constants.js +33 -0
  19. package/dist/cjs/hooks/useEditor.js +33 -229
  20. package/dist/cjs/hooks/useEditorEffect.js +2 -2
  21. package/dist/cjs/hooks/useEditorEventCallback.js +8 -5
  22. package/dist/cjs/hooks/useIgnoreMutation.js +1 -1
  23. package/dist/cjs/hooks/useNodeViewDescriptor.js +123 -80
  24. package/dist/cjs/hooks/useReactKeys.js +1 -1
  25. package/dist/cjs/hooks/useSelectNode.js +9 -7
  26. package/dist/cjs/hooks/useStopEvent.js +1 -1
  27. package/dist/cjs/plugins/beforeInputPlugin.js +12 -0
  28. package/dist/cjs/testing/editorViewTestHelpers.js +0 -2
  29. package/dist/cjs/viewdesc.js +104 -25
  30. package/dist/esm/AbstractEditorView.js +1 -0
  31. package/dist/esm/ReactEditorView.js +156 -0
  32. package/dist/esm/StaticEditorView.js +76 -0
  33. package/dist/esm/components/ChildNodeViews.js +59 -31
  34. package/dist/esm/components/CustomNodeView.js +78 -138
  35. package/dist/esm/components/DefaultNodeView.js +16 -0
  36. package/dist/esm/components/DocNodeView.js +33 -41
  37. package/dist/esm/components/MarkView.js +1 -2
  38. package/dist/esm/components/NativeWidgetView.js +2 -3
  39. package/dist/esm/components/NodeView.js +32 -22
  40. package/dist/esm/components/ProseMirror.js +25 -17
  41. package/dist/esm/components/ProseMirrorDoc.js +7 -28
  42. package/dist/esm/components/ReactNodeView.js +99 -62
  43. package/dist/esm/components/SeparatorHackView.js +1 -2
  44. package/dist/esm/components/TextNodeView.js +4 -5
  45. package/dist/esm/components/TrailingHackView.js +1 -2
  46. package/dist/esm/components/WidgetView.js +2 -4
  47. package/dist/esm/constants.js +15 -0
  48. package/dist/esm/hooks/useEditor.js +29 -218
  49. package/dist/esm/hooks/useEditorEffect.js +2 -2
  50. package/dist/esm/hooks/useEditorEventCallback.js +8 -5
  51. package/dist/esm/hooks/useIgnoreMutation.js +1 -1
  52. package/dist/esm/hooks/useNodeViewDescriptor.js +125 -82
  53. package/dist/esm/hooks/useReactKeys.js +1 -1
  54. package/dist/esm/hooks/useSelectNode.js +9 -7
  55. package/dist/esm/hooks/useStopEvent.js +1 -1
  56. package/dist/esm/plugins/beforeInputPlugin.js +12 -0
  57. package/dist/esm/testing/editorViewTestHelpers.js +0 -2
  58. package/dist/esm/viewdesc.js +94 -18
  59. package/dist/tsconfig.tsbuildinfo +1 -1
  60. package/dist/types/AbstractEditorView.d.ts +27 -0
  61. package/dist/types/ReactEditorView.d.ts +80 -0
  62. package/dist/types/StaticEditorView.d.ts +24 -0
  63. package/dist/types/components/ChildNodeViews.d.ts +2 -2
  64. package/dist/types/components/CustomNodeView.d.ts +3 -3
  65. package/dist/types/components/DefaultNodeView.d.ts +3 -0
  66. package/dist/types/components/DocNodeView.d.ts +9 -17
  67. package/dist/types/components/MarkView.d.ts +2 -2
  68. package/dist/types/components/NativeWidgetView.d.ts +2 -2
  69. package/dist/types/components/NodeView.d.ts +5 -5
  70. package/dist/types/components/NodeViewComponentProps.d.ts +3 -4
  71. package/dist/types/components/ProseMirrorDoc.d.ts +14 -8
  72. package/dist/types/components/ReactNodeView.d.ts +4 -2
  73. package/dist/types/components/SeparatorHackView.d.ts +2 -2
  74. package/dist/types/components/TextNodeView.d.ts +4 -3
  75. package/dist/types/components/TrailingHackView.d.ts +2 -2
  76. package/dist/types/components/WidgetView.d.ts +2 -2
  77. package/dist/types/constants.d.ts +4 -0
  78. package/dist/types/contexts/EditorContext.d.ts +6 -4
  79. package/dist/types/contexts/IgnoreMutationContext.d.ts +2 -1
  80. package/dist/types/contexts/NodeViewContext.d.ts +3 -1
  81. package/dist/types/contexts/SelectNodeContext.d.ts +3 -1
  82. package/dist/types/contexts/StopEventContext.d.ts +2 -1
  83. package/dist/types/decorations/computeDocDeco.d.ts +3 -2
  84. package/dist/types/decorations/viewDecorations.d.ts +3 -2
  85. package/dist/types/hooks/useEditor.d.ts +5 -46
  86. package/dist/types/hooks/useNodeViewDescriptor.d.ts +18 -10
  87. package/dist/types/hooks/useReactKeys.d.ts +1 -1
  88. package/dist/types/hooks/useSelectNode.d.ts +2 -1
  89. package/dist/types/props.d.ts +3 -3
  90. package/dist/types/viewdesc.d.ts +29 -11
  91. package/package.json +7 -3
  92. package/dist/cjs/components/Editor.js +0 -28
  93. package/dist/cjs/components/NodeViews.js +0 -73
  94. package/dist/cjs/components/__tests__/LayoutGroup.test.js +0 -141
  95. package/dist/cjs/components/__tests__/ProseMirror.test.js +0 -255
  96. package/dist/cjs/contexts/NodeViewsContext.js +0 -10
  97. package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -107
  98. package/dist/cjs/hooks/__tests__/useNodeViews.test.js +0 -159
  99. package/dist/cjs/hooks/useClientOnly.js +0 -19
  100. package/dist/cjs/hooks/useEditorView.js +0 -100
  101. package/dist/cjs/hooks/useNodeViews.js +0 -100
  102. package/dist/cjs/nodeViews/createReactNodeViewConstructor.js +0 -244
  103. package/dist/cjs/nodeViews/phrasingContentTags.js +0 -57
  104. package/dist/cjs/plugins/__tests__/react.test.js +0 -139
  105. package/dist/cjs/plugins/react.js +0 -71
  106. package/dist/cjs/selection/SelectionDOMObserver.js +0 -171
  107. package/dist/cjs/selection/hasFocusAndSelection.js +0 -35
  108. package/dist/cjs/selection/selectionFromDOM.js +0 -77
  109. package/dist/cjs/selection/selectionToDOM.js +0 -226
  110. package/dist/cjs/ssr.js +0 -85
  111. package/dist/esm/components/Editor.js +0 -15
  112. package/dist/esm/components/NodeViews.js +0 -26
  113. package/dist/esm/components/__tests__/LayoutGroup.test.js +0 -98
  114. package/dist/esm/components/__tests__/ProseMirror.test.js +0 -207
  115. package/dist/esm/contexts/NodeViewsContext.js +0 -9
  116. package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -98
  117. package/dist/esm/hooks/__tests__/useNodeViews.test.js +0 -116
  118. package/dist/esm/hooks/useClientOnly.js +0 -9
  119. package/dist/esm/hooks/useEditorView.js +0 -99
  120. package/dist/esm/hooks/useNodePos.js +0 -16
  121. package/dist/esm/hooks/useNodeViews.js +0 -53
  122. package/dist/esm/nodeViews/createReactNodeViewConstructor.js +0 -214
  123. package/dist/esm/nodeViews/phrasingContentTags.js +0 -49
  124. package/dist/esm/plugins/__tests__/react.test.js +0 -135
  125. package/dist/esm/plugins/react.js +0 -64
  126. package/dist/esm/selection/SelectionDOMObserver.js +0 -161
  127. package/dist/esm/selection/hasFocusAndSelection.js +0 -17
  128. package/dist/esm/selection/selectionFromDOM.js +0 -59
  129. package/dist/esm/selection/selectionToDOM.js +0 -196
  130. package/dist/esm/ssr.js +0 -82
  131. package/dist/types/components/Editor.d.ts +0 -7
  132. package/dist/types/components/NodeViews.d.ts +0 -6
  133. package/dist/types/components/__tests__/LayoutGroup.test.d.ts +0 -1
  134. package/dist/types/contexts/NodeViewsContext.d.ts +0 -19
  135. package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +0 -1
  136. package/dist/types/hooks/__tests__/useNodeViews.test.d.ts +0 -1
  137. package/dist/types/hooks/useClientOnly.d.ts +0 -1
  138. package/dist/types/hooks/useEditorView.d.ts +0 -23
  139. package/dist/types/hooks/useNodePos.d.ts +0 -9
  140. package/dist/types/hooks/useNodeViews.d.ts +0 -5
  141. package/dist/types/nodeViews/createReactNodeViewConstructor.d.ts +0 -48
  142. package/dist/types/nodeViews/phrasingContentTags.d.ts +0 -1
  143. package/dist/types/plugins/__tests__/react.test.d.ts +0 -1
  144. package/dist/types/plugins/react.d.ts +0 -21
  145. package/dist/types/selection/SelectionDOMObserver.d.ts +0 -33
  146. package/dist/types/selection/hasFocusAndSelection.d.ts +0 -3
  147. package/dist/types/selection/selectionFromDOM.d.ts +0 -4
  148. package/dist/types/selection/selectionToDOM.d.ts +0 -9
  149. package/dist/types/ssr.d.ts +0 -19
@@ -9,8 +9,15 @@ Object.defineProperty(exports, "useEditorEventCallback", {
9
9
  }
10
10
  });
11
11
  const _react = require("react");
12
+ const _ReactEditorView = require("../ReactEditorView.js");
12
13
  const _EditorContext = require("../contexts/EditorContext.js");
13
14
  const _useEditorEffect = require("./useEditorEffect.js");
15
+ function assertIsReactEditorView(view) {
16
+ if (view instanceof _ReactEditorView.ReactEditorView) {
17
+ return;
18
+ }
19
+ throw new DOMException("ProseMirror document is not mounted", "InvalidStateError");
20
+ }
14
21
  function useEditorEventCallback(callback) {
15
22
  const ref = (0, _react.useRef)(callback);
16
23
  const { view } = (0, _react.useContext)(_EditorContext.EditorContext);
@@ -23,11 +30,7 @@ function useEditorEventCallback(callback) {
23
30
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
24
31
  args[_key] = arguments[_key];
25
32
  }
26
- // It's not actually possible for an event handler to run
27
- // while view is null, since view is only ever set to
28
- // null in a layout effect that then immediately triggers
29
- // a re-render which sets view to a new EditorView
30
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
33
+ assertIsReactEditorView(view);
31
34
  return ref.current(view, ...args);
32
35
  }, [
33
36
  view
@@ -16,7 +16,7 @@ function useIgnoreMutation(ignoreMutation) {
16
16
  const register = (0, _react.useContext)(_IgnoreMutationContext.IgnoreMutationContext);
17
17
  const ignoreMutationMemo = (0, _useEditorEventCallback.useEditorEventCallback)(ignoreMutation);
18
18
  (0, _useEditorEffect.useEditorEffect)(()=>{
19
- register(ignoreMutationMemo);
19
+ return register(ignoreMutationMemo);
20
20
  }, [
21
21
  register,
22
22
  ignoreMutationMemo
@@ -9,111 +9,154 @@ Object.defineProperty(exports, "useNodeViewDescriptor", {
9
9
  }
10
10
  });
11
11
  const _react = require("react");
12
+ const _ReactEditorView = require("../ReactEditorView.js");
12
13
  const _ChildDescriptorsContext = require("../contexts/ChildDescriptorsContext.js");
13
14
  const _EditorContext = require("../contexts/EditorContext.js");
14
15
  const _viewdesc = require("../viewdesc.js");
15
16
  const _useClientLayoutEffect = require("./useClientLayoutEffect.js");
16
- function useNodeViewDescriptor(node, getPos, domRef, nodeDomRef, innerDecorations, outerDecorations, viewDesc, contentDOMRef) {
17
+ function findContentDOM(source, children) {
18
+ return source?.contentDOM ?? children[0]?.dom?.parentElement ?? null;
19
+ }
20
+ function useNodeViewDescriptor(ref, constructor, props) {
17
21
  const { view } = (0, _react.useContext)(_EditorContext.EditorContext);
18
- const [hasContentDOM, setHasContentDOM] = (0, _react.useState)(true);
19
- const nodeViewDescRef = (0, _react.useRef)(viewDesc);
20
- const stopEvent = (0, _react.useRef)(()=>false);
21
- const setStopEvent = (0, _react.useCallback)((newStopEvent)=>{
22
- stopEvent.current = newStopEvent;
23
- }, []);
24
- const ignoreMutation = (0, _react.useRef)(()=>false);
25
- const setIgnoreMutation = (0, _react.useCallback)((newIgnoreMutation)=>{
26
- ignoreMutation.current = newIgnoreMutation;
27
- }, []);
28
- const selectNode = (0, _react.useRef)(()=>{
29
- if (!nodeDomRef.current || !node) return;
30
- if (nodeDomRef.current.nodeType == 1) nodeDomRef.current.classList.add("ProseMirror-selectednode");
31
- if (contentDOMRef?.current || !node.type.spec.draggable) (domRef?.current ?? nodeDomRef.current).draggable = true;
32
- });
33
- const deselectNode = (0, _react.useRef)(()=>{
34
- if (!nodeDomRef.current || !node) return;
35
- if (nodeDomRef.current.nodeType == 1) {
36
- nodeDomRef.current.classList.remove("ProseMirror-selectednode");
37
- if (contentDOMRef?.current || !node.type.spec.draggable) (domRef?.current ?? nodeDomRef.current).removeAttribute("draggable");
22
+ const { parentRef, siblingsRef } = (0, _react.useContext)(_ChildDescriptorsContext.ChildDescriptorsContext);
23
+ const [dom, setDOM] = (0, _react.useState)(null);
24
+ const [nodeDOM, setNodeDOM] = (0, _react.useState)(null);
25
+ const [contentDOM, setContentDOM] = (0, _react.useState)(null);
26
+ const viewDescRef = (0, _react.useRef)();
27
+ const childrenRef = (0, _react.useRef)([]);
28
+ const create = (0, _react.useCallback)((props)=>{
29
+ if (!(view instanceof _ReactEditorView.ReactEditorView)) {
30
+ return;
38
31
  }
39
- });
40
- const setSelectNode = (0, _react.useCallback)((newSelectNode, newDeselectNode)=>{
41
- selectNode.current = newSelectNode;
42
- deselectNode.current = newDeselectNode;
43
- }, []);
44
- const { siblingsRef, parentRef } = (0, _react.useContext)(_ChildDescriptorsContext.ChildDescriptorsContext);
45
- const childDescriptors = (0, _react.useRef)([]);
46
- (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
32
+ const dom = ref.current;
33
+ if (!dom) {
34
+ return;
35
+ }
36
+ const { node, getPos, decorations, innerDecorations } = props;
37
+ const nodeView = constructor(node, view, getPos, decorations, innerDecorations);
38
+ if (!nodeView) {
39
+ return;
40
+ }
41
+ const parent = parentRef.current;
42
+ const children = childrenRef.current;
43
+ const contentDOM = findContentDOM(nodeView, children);
44
+ const nodeDOM = nodeView.dom;
45
+ const viewDesc = new _viewdesc.ReactNodeViewDesc(parent, children, getPos, node, decorations, innerDecorations, dom, contentDOM, nodeDOM, nodeView);
46
+ setDOM(dom);
47
+ setContentDOM(contentDOM);
48
+ setNodeDOM(nodeDOM);
49
+ return viewDesc;
50
+ }, [
51
+ ref,
52
+ parentRef,
53
+ constructor,
54
+ view
55
+ ]);
56
+ const update = (0, _react.useCallback)((props)=>{
57
+ if (!(view instanceof _ReactEditorView.ReactEditorView)) {
58
+ return false;
59
+ }
60
+ const viewDesc = viewDescRef.current;
61
+ if (!viewDesc) {
62
+ return false;
63
+ }
64
+ const dom = ref.current;
65
+ if (!dom || dom !== viewDesc.dom) {
66
+ return false;
67
+ }
68
+ const contentDOM = findContentDOM(viewDesc, viewDesc.children);
69
+ if (contentDOM !== viewDesc.contentDOM) {
70
+ return false;
71
+ }
72
+ if (!dom.contains(viewDesc.nodeDOM)) {
73
+ return false;
74
+ }
75
+ const { node, decorations, innerDecorations } = props;
76
+ return viewDesc.matchesNode(node, decorations, innerDecorations) || viewDesc.update(node, decorations, innerDecorations, view);
77
+ }, [
78
+ ref,
79
+ view
80
+ ]);
81
+ const destroy = (0, _react.useCallback)(()=>{
82
+ const viewDesc = viewDescRef.current;
83
+ if (!viewDesc) {
84
+ return;
85
+ }
86
+ viewDesc.destroy();
47
87
  const siblings = siblingsRef.current;
48
- return ()=>{
49
- if (!nodeViewDescRef.current) return;
50
- if (siblings.includes(nodeViewDescRef.current)) {
51
- const index = siblings.indexOf(nodeViewDescRef.current);
52
- siblings.splice(index, 1);
53
- }
54
- };
88
+ if (siblings.includes(viewDesc)) {
89
+ const index = siblings.indexOf(viewDesc);
90
+ siblings.splice(index, 1);
91
+ }
92
+ setDOM(null);
93
+ setContentDOM(null);
94
+ setNodeDOM(null);
55
95
  }, [
56
96
  siblingsRef
57
97
  ]);
58
- // eslint-disable-next-line react-hooks/exhaustive-deps
59
98
  (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
60
- if (!node || !nodeDomRef.current) return;
61
- const firstChildDesc = childDescriptors.current[0];
62
- if (!nodeViewDescRef.current) {
63
- nodeViewDescRef.current = new _viewdesc.NodeViewDesc(parentRef.current, childDescriptors.current, getPos, node, outerDecorations, innerDecorations, domRef?.current ?? nodeDomRef.current, firstChildDesc?.dom.parentElement ?? null, nodeDomRef.current, (event)=>!!stopEvent.current(event), ()=>selectNode.current(), ()=>deselectNode.current(), (mutation)=>ignoreMutation.current(mutation));
64
- } else {
65
- nodeViewDescRef.current.parent = parentRef.current;
66
- nodeViewDescRef.current.children = childDescriptors.current;
67
- nodeViewDescRef.current.node = node;
68
- nodeViewDescRef.current.getPos = getPos;
69
- nodeViewDescRef.current.outerDeco = outerDecorations;
70
- nodeViewDescRef.current.innerDeco = innerDecorations;
71
- nodeViewDescRef.current.dom = domRef?.current ?? nodeDomRef.current;
72
- nodeViewDescRef.current.dom.pmViewDesc = nodeViewDescRef.current;
73
- nodeViewDescRef.current.contentDOM = // If there's already a contentDOM, we can just
74
- // keep it; it won't have changed. This is especially
75
- // important during compositions, where the
76
- // firstChildDesc might not have a correct dom node set yet.
77
- contentDOMRef?.current ?? nodeViewDescRef.current.contentDOM ?? firstChildDesc?.dom.parentElement ?? null;
78
- nodeViewDescRef.current.nodeDOM = nodeDomRef.current;
99
+ if (!update(props)) {
100
+ destroy();
101
+ viewDescRef.current = create(props);
102
+ }
103
+ const viewDesc = viewDescRef.current;
104
+ if (!viewDesc) {
105
+ return;
79
106
  }
80
- setHasContentDOM(nodeViewDescRef.current.contentDOM !== null);
81
- if (!siblingsRef.current.includes(nodeViewDescRef.current)) {
82
- siblingsRef.current.push(nodeViewDescRef.current);
107
+ if (view.dom === viewDesc.dom && view instanceof _ReactEditorView.ReactEditorView) {
108
+ view.docView = viewDesc;
109
+ }
110
+ const parent = parentRef.current;
111
+ const siblings = siblingsRef.current;
112
+ const children = childrenRef.current;
113
+ viewDesc.parent = parent;
114
+ if (!siblings.includes(viewDesc)) {
115
+ siblings.push(viewDesc);
83
116
  }
84
- siblingsRef.current.sort(_viewdesc.sortViewDescs);
85
- for (const childDesc of childDescriptors.current){
86
- childDesc.parent = nodeViewDescRef.current;
117
+ siblings.sort(_viewdesc.sortViewDescs);
118
+ for (const child of children){
119
+ child.parent = viewDesc;
87
120
  // Because TextNodeViews can't locate the DOM nodes
88
121
  // for compositions, we need to override them here
89
- if (childDesc instanceof _viewdesc.CompositionViewDesc) {
90
- const compositionTopDOM = nodeViewDescRef.current.contentDOM?.firstChild;
122
+ if (child instanceof _viewdesc.CompositionViewDesc) {
123
+ const compositionTopDOM = viewDesc?.contentDOM?.firstChild;
91
124
  if (!compositionTopDOM) throw new Error(`Started a composition but couldn't find the text node it belongs to.`);
92
125
  let textDOM = compositionTopDOM;
93
126
  while(textDOM.firstChild){
94
127
  textDOM = textDOM.firstChild;
95
128
  }
96
129
  if (!textDOM || !(textDOM instanceof Text)) throw new Error(`Started a composition but couldn't find the text node it belongs to.`);
97
- childDesc.dom = compositionTopDOM;
98
- childDesc.textDOM = textDOM;
99
- childDesc.text = textDOM.data;
100
- childDesc.textDOM.pmViewDesc = childDesc;
101
- // @ts-expect-error Internal property -- input
102
- view?.input.compositionNodes.push(childDesc);
130
+ child.dom = compositionTopDOM;
131
+ child.textDOM = textDOM;
132
+ child.text = textDOM.data;
133
+ child.textDOM.pmViewDesc = child;
134
+ // It should not be possible to be in a composition because one could
135
+ // not start between the renders that switch the view type.
136
+ view.input.compositionNodes.push(child);
103
137
  }
104
138
  }
139
+ });
140
+ (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
105
141
  return ()=>{
106
- if (nodeViewDescRef.current?.children[0] instanceof _viewdesc.CompositionViewDesc && !view?.composing) {
107
- nodeViewDescRef.current?.children[0].dom.parentNode?.removeChild(nodeViewDescRef.current?.children[0].dom);
108
- }
142
+ destroy();
143
+ viewDescRef.current = undefined;
109
144
  };
110
- });
145
+ }, [
146
+ destroy
147
+ ]);
148
+ const childContextValue = (0, _react.useMemo)(()=>({
149
+ parentRef: viewDescRef,
150
+ siblingsRef: childrenRef
151
+ }), [
152
+ childrenRef,
153
+ viewDescRef
154
+ ]);
111
155
  return {
112
- hasContentDOM,
113
- childDescriptors,
114
- nodeViewDescRef,
115
- setStopEvent,
116
- setSelectNode,
117
- setIgnoreMutation
156
+ childContextValue,
157
+ dom,
158
+ contentDOM,
159
+ nodeDOM,
160
+ ref
118
161
  };
119
162
  }
@@ -13,5 +13,5 @@ const _EditorContext = require("../contexts/EditorContext.js");
13
13
  const _reactKeys = require("../plugins/reactKeys.js");
14
14
  function useReactKeys() {
15
15
  const { view } = (0, _react.useContext)(_EditorContext.EditorContext);
16
- return view && _reactKeys.reactKeysPluginKey.getState(view.state);
16
+ return _reactKeys.reactKeysPluginKey.getState(view.state);
17
17
  }
@@ -12,17 +12,19 @@ const _react = require("react");
12
12
  const _SelectNodeContext = require("../contexts/SelectNodeContext.js");
13
13
  const _useEditorEffect = require("./useEditorEffect.js");
14
14
  const _useEditorEventCallback = require("./useEditorEventCallback.js");
15
- function useSelectNode(selectNode, deselectNode) {
15
+ function noop() {
16
+ // empty
17
+ }
18
+ function useSelectNode(selectNode) {
19
+ let deselectNode = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
16
20
  const register = (0, _react.useContext)(_SelectNodeContext.SelectNodeContext);
17
21
  const selectNodeMemo = (0, _useEditorEventCallback.useEditorEventCallback)(selectNode);
18
- const deselectNodeMemo = (0, _useEditorEventCallback.useEditorEventCallback)(deselectNode ?? (()=>{
19
- // empty
20
- }));
22
+ const deselectNodeMemo = (0, _useEditorEventCallback.useEditorEventCallback)(deselectNode);
21
23
  return (0, _useEditorEffect.useEditorEffect)(()=>{
22
- register(selectNodeMemo, deselectNodeMemo);
24
+ return register(selectNodeMemo, deselectNodeMemo);
23
25
  }, [
24
- deselectNodeMemo,
25
26
  register,
26
- selectNodeMemo
27
+ selectNodeMemo,
28
+ deselectNodeMemo
27
29
  ]);
28
30
  }
@@ -16,7 +16,7 @@ function useStopEvent(stopEvent) {
16
16
  const register = (0, _react.useContext)(_StopEventContext.StopEventContext);
17
17
  const stopEventMemo = (0, _useEditorEventCallback.useEditorEventCallback)(stopEvent);
18
18
  (0, _useEditorEffect.useEditorEffect)(()=>{
19
- register(stopEventMemo);
19
+ return register(stopEventMemo);
20
20
  }, [
21
21
  register,
22
22
  stopEventMemo
@@ -96,6 +96,14 @@ function beforeInputPlugin(setCursorWrapper) {
96
96
  case "insertParagraph":
97
97
  case "insertLineBreak":
98
98
  {
99
+ // ProseMirror-view has a hack that runs the Enter event handlers
100
+ // on iOS, to avoid a bug in Safari with calling event.preventDefault() on
101
+ // Enter events.
102
+ //
103
+ // We want to prevent that hack, because we run the Enter event handlers
104
+ // here, where there is no such bug. So we set this flag, which prosemirror-view
105
+ // uses to check whether it should run the deferred event handlers.
106
+ view.input.lastIOSEnter = 0;
99
107
  // Fire a synthetic keydown event to trigger ProseMirror's keymap
100
108
  const keyEvent = new KeyboardEvent("keydown", {
101
109
  bubbles: true,
@@ -129,8 +137,12 @@ function beforeInputPlugin(setCursorWrapper) {
129
137
  break;
130
138
  }
131
139
  case "deleteWordBackward":
140
+ case "deleteHardLineBackward":
141
+ case "deleteSoftLineBackward":
132
142
  case "deleteContentBackward":
133
143
  case "deleteWordForward":
144
+ case "deleteHardLineForward":
145
+ case "deleteSoftLineForward":
134
146
  case "deleteContentForward":
135
147
  case "deleteContent":
136
148
  {
@@ -85,8 +85,6 @@ function tempEditor(param) {
85
85
  }, /*#__PURE__*/ _react1.default.createElement(Test, null), /*#__PURE__*/ _react1.default.createElement(_ProseMirrorDoc.ProseMirrorDoc, null)));
86
86
  return view;
87
87
  }
88
- // We need two renders for the hasContentDOM state to settle
89
- rerenderEditor();
90
88
  return {
91
89
  view: view,
92
90
  rerender: rerenderEditor,
@@ -18,6 +18,9 @@ _export(exports, {
18
18
  NodeViewDesc: function() {
19
19
  return NodeViewDesc;
20
20
  },
21
+ ReactNodeViewDesc: function() {
22
+ return ReactNodeViewDesc;
23
+ },
21
24
  TextViewDesc: function() {
22
25
  return TextViewDesc;
23
26
  },
@@ -36,7 +39,7 @@ _export(exports, {
36
39
  });
37
40
  const _prosemirrormodel = require("prosemirror-model");
38
41
  const _browser = require("./browser.js");
39
- const _selectionToDOM = require("./selection/selectionToDOM.js");
42
+ const _dom = require("./dom.js");
40
43
  function sortViewDescs(a, b) {
41
44
  if (a instanceof TrailingHackViewDesc) return 1;
42
45
  if (b instanceof TrailingHackViewDesc) return -1;
@@ -104,7 +107,9 @@ let ViewDesc = class ViewDesc {
104
107
  return 0;
105
108
  }
106
109
  destroy() {
107
- // pass
110
+ this.parent = undefined;
111
+ if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = undefined;
112
+ for(let i = 0; i < this.children.length; i++)this.children[i].destroy();
108
113
  }
109
114
  posBeforeChild(child) {
110
115
  for(let i = 0, pos = this.posAtStart;; i++){
@@ -157,7 +162,7 @@ let ViewDesc = class ViewDesc {
157
162
  // start or at the end of this view desc.
158
163
  let atEnd;
159
164
  if (dom == this.dom && this.contentDOM) {
160
- atEnd = offset > (0, _selectionToDOM.domIndex)(this.contentDOM);
165
+ atEnd = offset > (0, _dom.domIndex)(this.contentDOM);
161
166
  } else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
162
167
  atEnd = dom.compareDocumentPosition(this.contentDOM) & 2;
163
168
  } else if (this.dom.firstChild) {
@@ -258,7 +263,7 @@ let ViewDesc = class ViewDesc {
258
263
  if (prev && side && enter && !prev.border && !prev.domAtom) return prev.domFromPos(prev.size, side);
259
264
  return {
260
265
  node: this.contentDOM,
261
- offset: prev ? (0, _selectionToDOM.domIndex)(prev.dom) + 1 : 0
266
+ offset: prev ? (0, _dom.domIndex)(prev.dom) + 1 : 0
262
267
  };
263
268
  } else {
264
269
  let next, enter = true;
@@ -269,7 +274,7 @@ let ViewDesc = class ViewDesc {
269
274
  if (next && enter && !next.border && !next.domAtom) return next.domFromPos(0, side);
270
275
  return {
271
276
  node: this.contentDOM,
272
- offset: next ? (0, _selectionToDOM.domIndex)(next.dom) : this.contentDOM.childNodes.length
277
+ offset: next ? (0, _dom.domIndex)(next.dom) : this.contentDOM.childNodes.length
273
278
  };
274
279
  }
275
280
  }
@@ -295,7 +300,7 @@ let ViewDesc = class ViewDesc {
295
300
  for(let j = i; j > 0; j--){
296
301
  const prev = this.children[j - 1];
297
302
  if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {
298
- fromOffset = (0, _selectionToDOM.domIndex)(prev.dom) + 1;
303
+ fromOffset = (0, _dom.domIndex)(prev.dom) + 1;
299
304
  break;
300
305
  }
301
306
  from -= prev.size;
@@ -307,7 +312,7 @@ let ViewDesc = class ViewDesc {
307
312
  for(let j = i + 1; j < this.children.length; j++){
308
313
  const next = this.children[j];
309
314
  if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {
310
- toOffset = (0, _selectionToDOM.domIndex)(next.dom);
315
+ toOffset = (0, _dom.domIndex)(next.dom);
311
316
  break;
312
317
  }
313
318
  to += next.size;
@@ -354,7 +359,6 @@ let ViewDesc = class ViewDesc {
354
359
  let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1);
355
360
  let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1);
356
361
  const domSel = view.root.getSelection();
357
- // @ts-expect-error - Internal method domSelectionRange
358
362
  const selRange = view.domSelectionRange();
359
363
  let brKludge = false;
360
364
  // On Firefox, using Selection.collapse to put the cursor after a
@@ -371,7 +375,7 @@ let ViewDesc = class ViewDesc {
371
375
  if (after = scan.nextSibling) {
372
376
  if (after.nodeName == "BR") anchorDOM = headDOM = {
373
377
  node: after.parentNode,
374
- offset: (0, _selectionToDOM.domIndex)(after) + 1
378
+ offset: (0, _dom.domIndex)(after) + 1
375
379
  };
376
380
  break;
377
381
  }
@@ -391,7 +395,7 @@ let ViewDesc = class ViewDesc {
391
395
  const after = selRange.focusNode.childNodes[selRange.focusOffset];
392
396
  if (after && after.contentEditable == "false") force = true;
393
397
  }
394
- if (!(force || brKludge && _browser.browser.safari) && (0, _selectionToDOM.isEquivalentPosition)(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && (0, _selectionToDOM.isEquivalentPosition)(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) return;
398
+ if (!(force || brKludge && _browser.browser.safari) && (0, _dom.isEquivalentPosition)(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && (0, _dom.isEquivalentPosition)(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) return;
395
399
  // Selection.extend can be used to create an 'inverted' selection
396
400
  // (one where the focus is before the anchor), but not all
397
401
  // browsers support it yet.
@@ -554,15 +558,8 @@ let NodeViewDesc = class NodeViewDesc extends ViewDesc {
554
558
  outerDeco;
555
559
  innerDeco;
556
560
  nodeDOM;
557
- stopEvent;
558
- selectNode;
559
- deselectNode;
560
- ignoreMutation;
561
- constructor(parent, children, getPos, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, stopEvent, selectNode, deselectNode, ignoreMutation){
562
- super(parent, children, getPos, dom, contentDOM), this.node = node, this.outerDeco = outerDeco, this.innerDeco = innerDeco, this.nodeDOM = nodeDOM, this.stopEvent = stopEvent, this.selectNode = selectNode, this.deselectNode = deselectNode, this.ignoreMutation = ignoreMutation;
563
- }
564
- updateOuterDeco() {
565
- // pass
561
+ constructor(parent, children, getPos, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM){
562
+ super(parent, children, getPos, dom, contentDOM), this.node = node, this.outerDeco = outerDeco, this.innerDeco = innerDeco, this.nodeDOM = nodeDOM;
566
563
  }
567
564
  parseRule() {
568
565
  // Experimental kludge to allow opt-in re-parsing of nodes
@@ -606,22 +603,46 @@ let NodeViewDesc = class NodeViewDesc extends ViewDesc {
606
603
  get border() {
607
604
  return this.node.isLeaf ? 0 : 1;
608
605
  }
606
+ updateChildren(_view, _pos) {
607
+ // Omitted to avoid reproducing lots of unused code.
608
+ // Overidden elsewhere in case this is ever vendored.
609
+ }
609
610
  // If this desc must be updated to match the given node decoration,
610
611
  // do so and return true.
611
- update(_node, _outerDeco, _innerDeco, _view) {
612
+ update(node, outerDeco, innerDeco, view) {
613
+ if (this.dirty == NODE_DIRTY || !node.sameMarkup(this.node)) return false;
614
+ this.updateInner(node, outerDeco, innerDeco, view);
612
615
  return true;
613
616
  }
617
+ updateInner(node, outerDeco, innerDeco, view) {
618
+ this.updateOuterDeco(outerDeco);
619
+ this.node = node;
620
+ this.innerDeco = innerDeco;
621
+ if (this.contentDOM) this.updateChildren(view, this.posAtStart);
622
+ this.dirty = NOT_DIRTY;
623
+ }
624
+ updateOuterDeco(outerDeco) {
625
+ this.outerDeco = outerDeco;
626
+ }
627
+ // Mark this node as being the selected node.
628
+ selectNode() {
629
+ if (this.nodeDOM.nodeType == 1) this.nodeDOM.classList.add("ProseMirror-selectednode");
630
+ if (this.contentDOM || !this.node.type.spec.draggable) this.dom.draggable = true;
631
+ }
632
+ // Remove selected node marking from this node.
633
+ deselectNode() {
634
+ if (this.nodeDOM.nodeType == 1) {
635
+ this.nodeDOM.classList.remove("ProseMirror-selectednode");
636
+ if (this.contentDOM || !this.node.type.spec.draggable) this.dom.removeAttribute("draggable");
637
+ }
638
+ }
614
639
  get domAtom() {
615
640
  return this.node.isAtom;
616
641
  }
617
642
  };
618
643
  let TextViewDesc = class TextViewDesc extends NodeViewDesc {
619
644
  constructor(parent, children, getPos, node, outerDeco, innerDeco, dom, nodeDOM){
620
- super(parent, children, getPos, node, outerDeco, innerDeco, dom, null, nodeDOM, ()=>false, ()=>{
621
- /* Text nodes can't have node selections */ }, ()=>{
622
- /* Text nodes can't have node selections */ }, (mutation)=>{
623
- return mutation.type != "characterData" && mutation.type != "selection";
624
- });
645
+ super(parent, children, getPos, node, outerDeco, innerDeco, dom, null, nodeDOM);
625
646
  }
626
647
  parseRule() {
627
648
  let skip = this.nodeDOM.parentNode;
@@ -631,6 +652,7 @@ let TextViewDesc = class TextViewDesc extends NodeViewDesc {
631
652
  };
632
653
  }
633
654
  update(_node, _outerDeco, _innerDeco, _view) {
655
+ this.dirty = NOT_DIRTY;
634
656
  return true;
635
657
  }
636
658
  inParent() {
@@ -672,6 +694,63 @@ let TrailingHackViewDesc = class TrailingHackViewDesc extends ViewDesc {
672
694
  return this.dom.nodeName == "IMG";
673
695
  }
674
696
  };
697
+ // A separate subclass is used for customized node views, so that the
698
+ // extra checks only have to be made for nodes that are actually
699
+ // customized.
700
+ let CustomNodeViewDesc = class CustomNodeViewDesc extends NodeViewDesc {
701
+ spec;
702
+ constructor(parent, children, getPos, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec){
703
+ super(parent, children, getPos, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM), this.spec = spec;
704
+ }
705
+ // A custom `update` method gets to decide whether the update goes
706
+ // through. If it does, and there's a `contentDOM` node, our logic
707
+ // updates the children.
708
+ update(node, outerDeco, innerDeco, view) {
709
+ if (this.dirty == NODE_DIRTY) return false;
710
+ if (this.spec.update && (this.node.type == node.type || this.spec.multiType)) {
711
+ const result = this.spec.update(node, outerDeco, innerDeco);
712
+ if (result) this.updateInner(node, outerDeco, innerDeco, view);
713
+ return result;
714
+ } else if (!this.contentDOM && !node.isLeaf) {
715
+ return false;
716
+ } else {
717
+ return super.update(node, outerDeco, innerDeco, view);
718
+ }
719
+ }
720
+ selectNode() {
721
+ this.spec.selectNode ? this.spec.selectNode() : super.selectNode();
722
+ }
723
+ deselectNode() {
724
+ this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode();
725
+ }
726
+ setSelection(anchor, head, view, force) {
727
+ this.spec.setSelection ? this.spec.setSelection(anchor, head, view.root) : super.setSelection(anchor, head, view, force);
728
+ }
729
+ destroy() {
730
+ if (this.spec.destroy) this.spec.destroy();
731
+ super.destroy();
732
+ }
733
+ stopEvent(event) {
734
+ return this.spec.stopEvent ? this.spec.stopEvent(event) : false;
735
+ }
736
+ ignoreMutation(mutation) {
737
+ return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation);
738
+ }
739
+ };
740
+ let ReactNodeViewDesc = class ReactNodeViewDesc extends CustomNodeViewDesc {
741
+ updateChildren(_view, _pos) {
742
+ // React has already updated the children.
743
+ }
744
+ updateOuterDeco(outerDeco) {
745
+ // React has already updated the decorations.
746
+ this.outerDeco = outerDeco;
747
+ }
748
+ destroy() {
749
+ // React has already destroyed the children (if needed).
750
+ this.children = [];
751
+ super.destroy();
752
+ }
753
+ };
675
754
  function sameOuterDeco(a, b) {
676
755
  if (a.length != b.length) return false;
677
756
  // @ts-expect-error ...
@@ -0,0 +1 @@
1
+ export { };