@handlewithcare/react-prosemirror 2.5.2 → 2.5.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/README.md CHANGED
@@ -693,15 +693,14 @@ export function SelectionWidget() {
693
693
  ### `NodeViewComponentProps`
694
694
 
695
695
  ```tsx
696
- type NodeViewComponentProps = {
696
+ interface NodeViewComponentProps extends AllHTMLAttributes<HTMLElement> = {
697
697
  nodeProps: {
698
698
  decorations: readonly Decoration[];
699
699
  innerDecorations: DecorationSource;
700
700
  node: Node;
701
- children?: ReactNode | ReactNode[];
702
701
  getPos: () => number;
703
702
  };
704
- } & HTMLAttributes<HTMLElement>;
703
+ };
705
704
  ```
706
705
 
707
706
  The props that will be passed to all node view components. These props map
@@ -32,6 +32,7 @@ function changedNodeViews(a, b) {
32
32
  let ReactEditorView = class ReactEditorView extends _prosemirrorview.EditorView {
33
33
  nextProps;
34
34
  prevState;
35
+ _destroyed;
35
36
  constructor(place, props){
36
37
  // Prevent the base class from destroying the React-managed nodes.
37
38
  // Restore them below after invoking the base class constructor.
@@ -55,6 +56,16 @@ let ReactEditorView = class ReactEditorView extends _prosemirrorview.EditorView
55
56
  this.domObserver.stop();
56
57
  this.domObserver.observer = null;
57
58
  this.domObserver.queue = [];
59
+ const originalOnSelectionChange = this.domObserver.onSelectionChange;
60
+ this.domObserver.onSelectionChange = ()=>{
61
+ // During a composition, we completely pause React-driven
62
+ // selection and DOM updates. Compositions are "fragile";
63
+ // in Safari, even updating the selection to the same
64
+ // position it's already set to will end the current
65
+ // composition.
66
+ if (this.composing) return;
67
+ originalOnSelectionChange();
68
+ };
58
69
  } finally{
59
70
  place.mount.replaceChildren(...reactContent);
60
71
  for (const attr of place.mount.attributes){
@@ -73,10 +84,22 @@ let ReactEditorView = class ReactEditorView extends _prosemirrorview.EditorView
73
84
  this.docView.destroy();
74
85
  // @ts-expect-error this violates the typing but class does it, too.
75
86
  this.docView = null;
87
+ this._destroyed = false;
76
88
  }
77
89
  get props() {
78
90
  return this.nextProps;
79
91
  }
92
+ /**
93
+ * @privateremarks
94
+ *
95
+ * We override this getter because the base implementation
96
+ * relies on checking `docView === null`, but we unconditionally
97
+ * set view.docView in a layout effect in the DocNodeView.
98
+ * This has the effect of "un-destroying" the EditorView,
99
+ * making it impossible to determine whether it's been destroyed.
100
+ */ get isDestroyed() {
101
+ return this._destroyed;
102
+ }
80
103
  setProps(props) {
81
104
  this.update({
82
105
  ...this.props,
@@ -132,6 +155,19 @@ let ReactEditorView = class ReactEditorView extends _prosemirrorview.EditorView
132
155
  }
133
156
  return undefined;
134
157
  }
158
+ destroy() {
159
+ // Prevent the base class from destroying the React-managed nodes.
160
+ // Restore them below after invoking the base class method.
161
+ const reactContent = [
162
+ ...this.dom.childNodes
163
+ ];
164
+ try {
165
+ super.destroy();
166
+ } finally{
167
+ this.dom.replaceChildren(...reactContent);
168
+ this._destroyed = true;
169
+ }
170
+ }
135
171
  /**
136
172
  * Commit effects by appling the pending props and state.
137
173
  *
@@ -59,7 +59,6 @@ const CustomNodeView = /*#__PURE__*/ (0, _react.memo)(function CustomNodeView(pa
59
59
  let { constructor, node, getPos, innerDeco, outerDeco } = param;
60
60
  const ref = (0, _react.useRef)(null);
61
61
  const innerRef = (0, _react.useRef)(null);
62
- const [selected, setSelected] = (0, _react.useState)(false);
63
62
  const nodeProps = (0, _react.useMemo)(()=>({
64
63
  node,
65
64
  getPos,
@@ -89,7 +88,6 @@ const CustomNodeView = /*#__PURE__*/ (0, _react.memo)(function CustomNodeView(pa
89
88
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
90
89
  args[_key] = arguments[_key];
91
90
  }
92
- setSelected(false);
93
91
  const nodeView = createNodeView(...args);
94
92
  const contentDOM = nodeView.contentDOM;
95
93
  const nodeDOM = nodeView.dom;
@@ -99,6 +97,9 @@ const CustomNodeView = /*#__PURE__*/ (0, _react.memo)(function CustomNodeView(pa
99
97
  if (!nodeDOM.hasAttribute("contenteditable")) {
100
98
  nodeDOM.contentEditable = "false";
101
99
  }
100
+ if (node.type.spec.draggable) {
101
+ nodeDOM.draggable = true;
102
+ }
102
103
  }
103
104
  return {
104
105
  ...nodeView,
@@ -108,22 +109,16 @@ const CustomNodeView = /*#__PURE__*/ (0, _react.memo)(function CustomNodeView(pa
108
109
  }
109
110
  wrapperDOM.removeChild(nodeDOM);
110
111
  },
111
- selectNode: nodeView.selectNode?.bind(nodeView) ?? (()=>{
112
- if (nodeDOM instanceof HTMLElement) {
113
- nodeDOM.classList.add("ProseMirror-selectednode");
114
- }
115
- setSelected(true);
116
- }),
117
- deselectNode: nodeView.deselectNode?.bind(nodeView) ?? (()=>{
118
- if (nodeDOM instanceof HTMLElement) {
119
- nodeDOM.classList.remove("ProseMirror-selectednode");
120
- }
121
- setSelected(false);
122
- }),
112
+ selectNode: nodeView.selectNode?.bind(nodeView),
113
+ deselectNode: nodeView.deselectNode?.bind(nodeView),
123
114
  stopEvent: nodeView.stopEvent?.bind(nodeView),
124
115
  ignoreMutation: nodeView.ignoreMutation?.bind(nodeView)
125
116
  };
126
117
  }, nodeProps);
118
+ const Component = node.isInline ? "span" : "div";
119
+ const props = {
120
+ ref: innerRef
121
+ };
127
122
  const children = !node.isLeaf && contentDOM ? /*#__PURE__*/ (0, _reactdom.createPortal)(/*#__PURE__*/ _react.default.createElement(_ChildDescriptorsContext.ChildDescriptorsContext.Provider, {
128
123
  value: childContextValue
129
124
  }, /*#__PURE__*/ _react.default.createElement(_ChildNodeViews.ChildNodeViews, {
@@ -131,14 +126,7 @@ const CustomNodeView = /*#__PURE__*/ (0, _react.memo)(function CustomNodeView(pa
131
126
  node: node,
132
127
  innerDecorations: innerDeco
133
128
  })), contentDOM) : null;
134
- const innerElement = /*#__PURE__*/ (0, _react.createElement)(node.isInline ? "span" : "div", {
135
- ref: innerRef
136
- }, children);
137
- const props = {
138
- ...selected || node.type.spec.draggable ? {
139
- draggable: true
140
- } : null,
129
+ return /*#__PURE__*/ (0, _react.cloneElement)(outerDeco.reduce(_ChildNodeViews.wrapInDeco, /*#__PURE__*/ _react.default.createElement(Component, props, children)), {
141
130
  ref
142
- };
143
- return /*#__PURE__*/ (0, _react.cloneElement)(outerDeco.reduce(_ChildNodeViews.wrapInDeco, innerElement), props);
131
+ });
144
132
  });
@@ -58,7 +58,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
58
58
  }
59
59
  const ReactNodeView = /*#__PURE__*/ (0, _react.memo)(function ReactNodeView(param) {
60
60
  let { component: Component, outerDeco, getPos, node, innerDeco } = param;
61
- const [controlSelected, setControlSelected] = (0, _react.useState)(false);
61
+ const [hasCustomSelectNode, setHasCustomSelectNode] = (0, _react.useState)(false);
62
62
  const [selected, setSelected] = (0, _react.useState)(false);
63
63
  const ref = (0, _react.useRef)(null);
64
64
  const innerRef = (0, _react.useRef)(null);
@@ -69,11 +69,11 @@ const ReactNodeView = /*#__PURE__*/ (0, _react.memo)(function ReactNodeView(para
69
69
  const setSelectNode = (0, _react.useCallback)((selectHandler, deselectHandler)=>{
70
70
  selectNodeRef.current = selectHandler;
71
71
  deselectNodeRef.current = deselectHandler;
72
- setControlSelected(true);
72
+ setHasCustomSelectNode(true);
73
73
  return ()=>{
74
74
  selectNodeRef.current = null;
75
75
  deselectNodeRef.current = null;
76
- setControlSelected(false);
76
+ setHasCustomSelectNode(false);
77
77
  };
78
78
  }, []);
79
79
  const setStopEvent = (0, _react.useCallback)((handler)=>{
@@ -140,30 +140,28 @@ const ReactNodeView = /*#__PURE__*/ (0, _react.memo)(function ReactNodeView(para
140
140
  }
141
141
  };
142
142
  }, nodeProps);
143
- const children = !node.isLeaf ? /*#__PURE__*/ _react.default.createElement(_ChildNodeViews.ChildNodeViews, {
144
- getPos: getPos,
145
- node: node,
146
- innerDecorations: innerDeco
147
- }) : null;
148
- const innerProps = {
143
+ const props = {
149
144
  nodeProps,
150
145
  ...!contentDOM && !nodeProps.node.isText && nodeDOM?.nodeName !== "BR" ? {
151
146
  contentEditable: false,
152
147
  suppressContentEditableWarning: true
153
148
  } : null,
154
- ...controlSelected && selected ? {
149
+ ...!hasCustomSelectNode && selected ? {
155
150
  className: "ProseMirror-selectednode"
156
151
  } : null,
157
- ref: innerRef
158
- };
159
- const innerElement = /*#__PURE__*/ _react.default.createElement(Component, innerProps, children);
160
- const props = {
161
- ...controlSelected && selected || node.type.spec.draggable ? {
152
+ ...!hasCustomSelectNode && selected || node.type.spec.draggable ? {
162
153
  draggable: true
163
154
  } : null,
164
- ref
155
+ ref: innerRef
165
156
  };
166
- const decoratedElement = /*#__PURE__*/ (0, _react.cloneElement)(outerDeco.reduce(_ChildNodeViews.wrapInDeco, innerElement), props);
157
+ const children = !node.isLeaf ? /*#__PURE__*/ _react.default.createElement(_ChildNodeViews.ChildNodeViews, {
158
+ getPos: getPos,
159
+ node: node,
160
+ innerDecorations: innerDeco
161
+ }) : null;
162
+ const element = /*#__PURE__*/ (0, _react.cloneElement)(outerDeco.reduce(_ChildNodeViews.wrapInDeco, /*#__PURE__*/ _react.default.createElement(Component, props, children)), {
163
+ ref
164
+ });
167
165
  return /*#__PURE__*/ _react.default.createElement(_SelectNodeContext.SelectNodeContext.Provider, {
168
166
  value: setSelectNode
169
167
  }, /*#__PURE__*/ _react.default.createElement(_StopEventContext.StopEventContext.Provider, {
@@ -172,5 +170,5 @@ const ReactNodeView = /*#__PURE__*/ (0, _react.memo)(function ReactNodeView(para
172
170
  value: setIgnoreMutation
173
171
  }, /*#__PURE__*/ _react.default.createElement(_ChildDescriptorsContext.ChildDescriptorsContext.Provider, {
174
172
  value: childContextValue
175
- }, decoratedElement))));
173
+ }, element))));
176
174
  });
@@ -16,6 +16,7 @@ const _constants = require("../constants.js");
16
16
  const _beforeInputPlugin = require("../plugins/beforeInputPlugin.js");
17
17
  const _useClientLayoutEffect = require("./useClientLayoutEffect.js");
18
18
  const _useComponentEventListeners = require("./useComponentEventListeners.js");
19
+ const _useEffectEvent = require("./useEffectEvent.js");
19
20
  const _useForceUpdate = require("./useForceUpdate.js");
20
21
  let didWarnValueDefaultValue = false;
21
22
  function useEditor(mount, options) {
@@ -77,30 +78,31 @@ function useEditor(mount, options) {
77
78
  const [view, setView] = (0, _react.useState)(()=>{
78
79
  return new _StaticEditorView.StaticEditorView(directEditorProps);
79
80
  });
81
+ const createEditorView = (0, _useEffectEvent.useEffectEvent)((mount)=>{
82
+ if (mount) {
83
+ const view = new _ReactEditorView.ReactEditorView({
84
+ mount
85
+ }, directEditorProps);
86
+ view.dom.addEventListener("compositionend", forceUpdate);
87
+ return view;
88
+ }
89
+ return new _StaticEditorView.StaticEditorView(directEditorProps);
90
+ });
80
91
  (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
92
+ const view = createEditorView(mount);
93
+ setView(view);
81
94
  return ()=>{
82
95
  view.destroy();
83
96
  };
84
97
  }, [
85
- view
98
+ createEditorView,
99
+ mount
86
100
  ]);
87
- // This rule is concerned about infinite updates due to the
88
- // call to setView. These calls are deliberately conditional,
89
- // so this is not a concern.
90
- // eslint-disable-next-line react-hooks/exhaustive-deps
91
101
  (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
92
- if (mount !== view.dom) {
93
- if (mount) {
94
- const view = new _ReactEditorView.ReactEditorView({
95
- mount
96
- }, directEditorProps);
97
- view.dom.addEventListener("compositionend", forceUpdate);
98
- setView(view);
99
- } else {
100
- const view = new _StaticEditorView.StaticEditorView(directEditorProps);
101
- setView(view);
102
- }
103
- } else if (view instanceof _ReactEditorView.ReactEditorView) {
102
+ // Ensure that the EditorView hasn't been destroyed before
103
+ // running effects. Running effects will reattach selection
104
+ // change listeners if the EditorView has been destroyed.
105
+ if (view instanceof _ReactEditorView.ReactEditorView && !view.isDestroyed) {
104
106
  view.commitPendingEffects();
105
107
  }
106
108
  });
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useEffectEvent", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useEffectEvent;
9
+ }
10
+ });
11
+ const _react = require("react");
12
+ function useEffectEvent(fn) {
13
+ const ref = (0, _react.useRef)(fn);
14
+ // Ideally this would be a useInsertionEffect, but
15
+ // that was introduced in React 18 and we still
16
+ // support React 17. useLayoutEffect is safe
17
+ // here as long as the function returned by
18
+ // useEffectEvent isn't called in a layout effect
19
+ // that's defined _before_ the useEffectEvent
20
+ // call, and effect events are never passed
21
+ // to child components.
22
+ (0, _react.useLayoutEffect)(()=>{
23
+ ref.current = fn;
24
+ }, [
25
+ fn
26
+ ]);
27
+ return (0, _react.useCallback)(function() {
28
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
29
+ args[_key] = arguments[_key];
30
+ }
31
+ const f = ref.current;
32
+ return f(...args);
33
+ }, []);
34
+ }
@@ -14,6 +14,7 @@ const _ChildDescriptorsContext = require("../contexts/ChildDescriptorsContext.js
14
14
  const _EditorContext = require("../contexts/EditorContext.js");
15
15
  const _viewdesc = require("../viewdesc.js");
16
16
  const _useClientLayoutEffect = require("./useClientLayoutEffect.js");
17
+ const _useEffectEvent = require("./useEffectEvent.js");
17
18
  function findContentDOM(source, children) {
18
19
  return source?.contentDOM ?? children[0]?.dom?.parentElement ?? null;
19
20
  }
@@ -25,7 +26,7 @@ function useNodeViewDescriptor(ref, constructor, props) {
25
26
  const [contentDOM, setContentDOM] = (0, _react.useState)(null);
26
27
  const viewDescRef = (0, _react.useRef)();
27
28
  const childrenRef = (0, _react.useRef)([]);
28
- const create = (0, _react.useCallback)((props)=>{
29
+ const create = (0, _useEffectEvent.useEffectEvent)(()=>{
29
30
  if (!(view instanceof _ReactEditorView.ReactEditorView)) {
30
31
  return;
31
32
  }
@@ -47,13 +48,8 @@ function useNodeViewDescriptor(ref, constructor, props) {
47
48
  setContentDOM(contentDOM);
48
49
  setNodeDOM(nodeDOM);
49
50
  return viewDesc;
50
- }, [
51
- ref,
52
- parentRef,
53
- constructor,
54
- view
55
- ]);
56
- const update = (0, _react.useCallback)((props)=>{
51
+ });
52
+ const update = (0, _useEffectEvent.useEffectEvent)(()=>{
57
53
  if (!(view instanceof _ReactEditorView.ReactEditorView)) {
58
54
  return false;
59
55
  }
@@ -74,11 +70,8 @@ function useNodeViewDescriptor(ref, constructor, props) {
74
70
  }
75
71
  const { node, decorations, innerDecorations } = props;
76
72
  return viewDesc.matchesNode(node, decorations, innerDecorations) || viewDesc.update(node, decorations, innerDecorations, view);
77
- }, [
78
- ref,
79
- view
80
- ]);
81
- const destroy = (0, _react.useCallback)(()=>{
73
+ });
74
+ const destroy = (0, _useEffectEvent.useEffectEvent)(()=>{
82
75
  const viewDesc = viewDescRef.current;
83
76
  if (!viewDesc) {
84
77
  return;
@@ -92,13 +85,20 @@ function useNodeViewDescriptor(ref, constructor, props) {
92
85
  setDOM(null);
93
86
  setContentDOM(null);
94
87
  setNodeDOM(null);
88
+ });
89
+ (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
90
+ viewDescRef.current = create();
91
+ return ()=>{
92
+ destroy();
93
+ };
95
94
  }, [
96
- siblingsRef
95
+ create,
96
+ destroy
97
97
  ]);
98
98
  (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
99
- if (!update(props)) {
99
+ if (!update()) {
100
100
  destroy();
101
- viewDescRef.current = create(props);
101
+ viewDescRef.current = create();
102
102
  }
103
103
  const viewDesc = viewDescRef.current;
104
104
  if (!viewDesc) {
@@ -137,14 +137,6 @@ function useNodeViewDescriptor(ref, constructor, props) {
137
137
  }
138
138
  }
139
139
  });
140
- (0, _useClientLayoutEffect.useClientLayoutEffect)(()=>{
141
- return ()=>{
142
- destroy();
143
- viewDescRef.current = undefined;
144
- };
145
- }, [
146
- destroy
147
- ]);
148
140
  const childContextValue = (0, _react.useMemo)(()=>({
149
141
  parentRef: viewDescRef,
150
142
  siblingsRef: childrenRef
@@ -32,6 +32,7 @@ function changedNodeViews(a, b) {
32
32
  */ export class ReactEditorView extends EditorView {
33
33
  nextProps;
34
34
  prevState;
35
+ _destroyed;
35
36
  constructor(place, props){
36
37
  // Prevent the base class from destroying the React-managed nodes.
37
38
  // Restore them below after invoking the base class constructor.
@@ -55,6 +56,16 @@ function changedNodeViews(a, b) {
55
56
  this.domObserver.stop();
56
57
  this.domObserver.observer = null;
57
58
  this.domObserver.queue = [];
59
+ const originalOnSelectionChange = this.domObserver.onSelectionChange;
60
+ this.domObserver.onSelectionChange = ()=>{
61
+ // During a composition, we completely pause React-driven
62
+ // selection and DOM updates. Compositions are "fragile";
63
+ // in Safari, even updating the selection to the same
64
+ // position it's already set to will end the current
65
+ // composition.
66
+ if (this.composing) return;
67
+ originalOnSelectionChange();
68
+ };
58
69
  } finally{
59
70
  place.mount.replaceChildren(...reactContent);
60
71
  for (const attr of place.mount.attributes){
@@ -73,10 +84,22 @@ function changedNodeViews(a, b) {
73
84
  this.docView.destroy();
74
85
  // @ts-expect-error this violates the typing but class does it, too.
75
86
  this.docView = null;
87
+ this._destroyed = false;
76
88
  }
77
89
  get props() {
78
90
  return this.nextProps;
79
91
  }
92
+ /**
93
+ * @privateremarks
94
+ *
95
+ * We override this getter because the base implementation
96
+ * relies on checking `docView === null`, but we unconditionally
97
+ * set view.docView in a layout effect in the DocNodeView.
98
+ * This has the effect of "un-destroying" the EditorView,
99
+ * making it impossible to determine whether it's been destroyed.
100
+ */ get isDestroyed() {
101
+ return this._destroyed;
102
+ }
80
103
  setProps(props) {
81
104
  this.update({
82
105
  ...this.props,
@@ -132,6 +155,19 @@ function changedNodeViews(a, b) {
132
155
  }
133
156
  return undefined;
134
157
  }
158
+ destroy() {
159
+ // Prevent the base class from destroying the React-managed nodes.
160
+ // Restore them below after invoking the base class method.
161
+ const reactContent = [
162
+ ...this.dom.childNodes
163
+ ];
164
+ try {
165
+ super.destroy();
166
+ } finally{
167
+ this.dom.replaceChildren(...reactContent);
168
+ this._destroyed = true;
169
+ }
170
+ }
135
171
  /**
136
172
  * Commit effects by appling the pending props and state.
137
173
  *
@@ -1,5 +1,5 @@
1
1
  import { DOMSerializer } from "prosemirror-model";
2
- import React, { cloneElement, createElement, memo, useMemo, useRef, useState } from "react";
2
+ import React, { cloneElement, memo, useMemo, useRef } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
5
5
  import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js";
@@ -8,7 +8,6 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
8
8
  let { constructor, node, getPos, innerDeco, outerDeco } = param;
9
9
  const ref = useRef(null);
10
10
  const innerRef = useRef(null);
11
- const [selected, setSelected] = useState(false);
12
11
  const nodeProps = useMemo(()=>({
13
12
  node,
14
13
  getPos,
@@ -38,7 +37,6 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
38
37
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
39
38
  args[_key] = arguments[_key];
40
39
  }
41
- setSelected(false);
42
40
  const nodeView = createNodeView(...args);
43
41
  const contentDOM = nodeView.contentDOM;
44
42
  const nodeDOM = nodeView.dom;
@@ -48,6 +46,9 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
48
46
  if (!nodeDOM.hasAttribute("contenteditable")) {
49
47
  nodeDOM.contentEditable = "false";
50
48
  }
49
+ if (node.type.spec.draggable) {
50
+ nodeDOM.draggable = true;
51
+ }
51
52
  }
52
53
  return {
53
54
  ...nodeView,
@@ -57,22 +58,16 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
57
58
  }
58
59
  wrapperDOM.removeChild(nodeDOM);
59
60
  },
60
- selectNode: nodeView.selectNode?.bind(nodeView) ?? (()=>{
61
- if (nodeDOM instanceof HTMLElement) {
62
- nodeDOM.classList.add("ProseMirror-selectednode");
63
- }
64
- setSelected(true);
65
- }),
66
- deselectNode: nodeView.deselectNode?.bind(nodeView) ?? (()=>{
67
- if (nodeDOM instanceof HTMLElement) {
68
- nodeDOM.classList.remove("ProseMirror-selectednode");
69
- }
70
- setSelected(false);
71
- }),
61
+ selectNode: nodeView.selectNode?.bind(nodeView),
62
+ deselectNode: nodeView.deselectNode?.bind(nodeView),
72
63
  stopEvent: nodeView.stopEvent?.bind(nodeView),
73
64
  ignoreMutation: nodeView.ignoreMutation?.bind(nodeView)
74
65
  };
75
66
  }, nodeProps);
67
+ const Component = node.isInline ? "span" : "div";
68
+ const props = {
69
+ ref: innerRef
70
+ };
76
71
  const children = !node.isLeaf && contentDOM ? /*#__PURE__*/ createPortal(/*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, {
77
72
  value: childContextValue
78
73
  }, /*#__PURE__*/ React.createElement(ChildNodeViews, {
@@ -80,14 +75,7 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
80
75
  node: node,
81
76
  innerDecorations: innerDeco
82
77
  })), contentDOM) : null;
83
- const innerElement = /*#__PURE__*/ createElement(node.isInline ? "span" : "div", {
84
- ref: innerRef
85
- }, children);
86
- const props = {
87
- ...selected || node.type.spec.draggable ? {
88
- draggable: true
89
- } : null,
78
+ return /*#__PURE__*/ cloneElement(outerDeco.reduce(wrapInDeco, /*#__PURE__*/ React.createElement(Component, props, children)), {
90
79
  ref
91
- };
92
- return /*#__PURE__*/ cloneElement(outerDeco.reduce(wrapInDeco, innerElement), props);
80
+ });
93
81
  });
@@ -7,7 +7,7 @@ import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js";
7
7
  import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js";
8
8
  export const ReactNodeView = /*#__PURE__*/ memo(function ReactNodeView(param) {
9
9
  let { component: Component, outerDeco, getPos, node, innerDeco } = param;
10
- const [controlSelected, setControlSelected] = useState(false);
10
+ const [hasCustomSelectNode, setHasCustomSelectNode] = useState(false);
11
11
  const [selected, setSelected] = useState(false);
12
12
  const ref = useRef(null);
13
13
  const innerRef = useRef(null);
@@ -18,11 +18,11 @@ export const ReactNodeView = /*#__PURE__*/ memo(function ReactNodeView(param) {
18
18
  const setSelectNode = useCallback((selectHandler, deselectHandler)=>{
19
19
  selectNodeRef.current = selectHandler;
20
20
  deselectNodeRef.current = deselectHandler;
21
- setControlSelected(true);
21
+ setHasCustomSelectNode(true);
22
22
  return ()=>{
23
23
  selectNodeRef.current = null;
24
24
  deselectNodeRef.current = null;
25
- setControlSelected(false);
25
+ setHasCustomSelectNode(false);
26
26
  };
27
27
  }, []);
28
28
  const setStopEvent = useCallback((handler)=>{
@@ -89,30 +89,28 @@ export const ReactNodeView = /*#__PURE__*/ memo(function ReactNodeView(param) {
89
89
  }
90
90
  };
91
91
  }, nodeProps);
92
- const children = !node.isLeaf ? /*#__PURE__*/ React.createElement(ChildNodeViews, {
93
- getPos: getPos,
94
- node: node,
95
- innerDecorations: innerDeco
96
- }) : null;
97
- const innerProps = {
92
+ const props = {
98
93
  nodeProps,
99
94
  ...!contentDOM && !nodeProps.node.isText && nodeDOM?.nodeName !== "BR" ? {
100
95
  contentEditable: false,
101
96
  suppressContentEditableWarning: true
102
97
  } : null,
103
- ...controlSelected && selected ? {
98
+ ...!hasCustomSelectNode && selected ? {
104
99
  className: "ProseMirror-selectednode"
105
100
  } : null,
106
- ref: innerRef
107
- };
108
- const innerElement = /*#__PURE__*/ React.createElement(Component, innerProps, children);
109
- const props = {
110
- ...controlSelected && selected || node.type.spec.draggable ? {
101
+ ...!hasCustomSelectNode && selected || node.type.spec.draggable ? {
111
102
  draggable: true
112
103
  } : null,
113
- ref
104
+ ref: innerRef
114
105
  };
115
- const decoratedElement = /*#__PURE__*/ cloneElement(outerDeco.reduce(wrapInDeco, innerElement), props);
106
+ const children = !node.isLeaf ? /*#__PURE__*/ React.createElement(ChildNodeViews, {
107
+ getPos: getPos,
108
+ node: node,
109
+ innerDecorations: innerDeco
110
+ }) : null;
111
+ const element = /*#__PURE__*/ cloneElement(outerDeco.reduce(wrapInDeco, /*#__PURE__*/ React.createElement(Component, props, children)), {
112
+ ref
113
+ });
116
114
  return /*#__PURE__*/ React.createElement(SelectNodeContext.Provider, {
117
115
  value: setSelectNode
118
116
  }, /*#__PURE__*/ React.createElement(StopEventContext.Provider, {
@@ -121,5 +119,5 @@ export const ReactNodeView = /*#__PURE__*/ memo(function ReactNodeView(param) {
121
119
  value: setIgnoreMutation
122
120
  }, /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, {
123
121
  value: childContextValue
124
- }, decoratedElement))));
122
+ }, element))));
125
123
  });