@handlewithcare/react-prosemirror 2.5.2 → 2.6.0-tiptap.0

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 (73) hide show
  1. package/README.md +2 -3
  2. package/dist/cjs/ReactEditorView.js +12 -0
  3. package/dist/cjs/components/CustomNodeView.js +11 -23
  4. package/dist/cjs/components/ReactNodeView.js +16 -18
  5. package/dist/cjs/components/__tests__/ProseMirror.composition.test.js +398 -0
  6. package/dist/cjs/components/__tests__/ProseMirror.domchange.test.js +270 -0
  7. package/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js +1010 -0
  8. package/dist/cjs/components/__tests__/ProseMirror.draw.test.js +337 -0
  9. package/dist/cjs/components/__tests__/ProseMirror.node-view.test.js +315 -0
  10. package/dist/cjs/components/__tests__/ProseMirror.selection.test.js +444 -0
  11. package/dist/cjs/components/__tests__/ProseMirror.test.js +382 -0
  12. package/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js +141 -0
  13. package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +108 -0
  14. package/dist/cjs/hooks/useClientOnly.js +19 -0
  15. package/dist/cjs/plugins/__tests__/reactKeys.test.js +81 -0
  16. package/dist/cjs/selection/SelectionDOMObserver.js +171 -0
  17. package/dist/cjs/selection/hasFocusAndSelection.js +35 -0
  18. package/dist/cjs/selection/selectionFromDOM.js +77 -0
  19. package/dist/cjs/selection/selectionToDOM.js +226 -0
  20. package/dist/cjs/ssr.js +85 -0
  21. package/dist/cjs/tiptap/TiptapEditorContent.js +93 -0
  22. package/dist/cjs/tiptap/TiptapEditorView.js +84 -0
  23. package/dist/cjs/tiptap/hooks/useTiptapEditorEffect.js +27 -0
  24. package/dist/cjs/tiptap/hooks/useTiptapEditorEventCallback.js +26 -0
  25. package/dist/cjs/tiptap/index.js +32 -0
  26. package/dist/cjs/tiptap/tiptapNodeView.js +181 -0
  27. package/dist/esm/ReactEditorView.js +12 -0
  28. package/dist/esm/components/CustomNodeView.js +12 -24
  29. package/dist/esm/components/ReactNodeView.js +16 -18
  30. package/dist/esm/components/__tests__/ProseMirror.composition.test.js +395 -0
  31. package/dist/esm/components/__tests__/ProseMirror.domchange.test.js +266 -0
  32. package/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js +967 -0
  33. package/dist/esm/components/__tests__/ProseMirror.draw.test.js +294 -0
  34. package/dist/esm/components/__tests__/ProseMirror.node-view.test.js +272 -0
  35. package/dist/esm/components/__tests__/ProseMirror.selection.test.js +440 -0
  36. package/dist/esm/components/__tests__/ProseMirror.test.js +339 -0
  37. package/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js +98 -0
  38. package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +99 -0
  39. package/dist/esm/hooks/useClientOnly.js +9 -0
  40. package/dist/esm/hooks/useEditorEffect.js +4 -0
  41. package/dist/esm/hooks/useEditorEventCallback.js +3 -5
  42. package/dist/esm/plugins/__tests__/reactKeys.test.js +77 -0
  43. package/dist/esm/selection/SelectionDOMObserver.js +161 -0
  44. package/dist/esm/selection/hasFocusAndSelection.js +17 -0
  45. package/dist/esm/selection/selectionFromDOM.js +59 -0
  46. package/dist/esm/selection/selectionToDOM.js +196 -0
  47. package/dist/esm/ssr.js +82 -0
  48. package/dist/esm/tiptap/TiptapEditorContent.js +42 -0
  49. package/dist/esm/tiptap/TiptapEditorView.js +35 -0
  50. package/dist/esm/tiptap/hooks/useTiptapEditorEffect.js +34 -0
  51. package/dist/esm/tiptap/hooks/useTiptapEditorEventCallback.js +26 -0
  52. package/dist/esm/tiptap/index.js +5 -0
  53. package/dist/esm/tiptap/tiptapNodeView.js +149 -0
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist/types/ReactEditorView.d.ts +1 -0
  56. package/dist/types/constants.d.ts +1 -1
  57. package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +1 -0
  58. package/dist/types/hooks/useClientOnly.d.ts +1 -0
  59. package/dist/types/hooks/useEditorEffect.d.ts +4 -0
  60. package/dist/types/hooks/useEditorEventCallback.d.ts +3 -5
  61. package/dist/types/props.d.ts +26 -26
  62. package/dist/types/selection/SelectionDOMObserver.d.ts +33 -0
  63. package/dist/types/selection/hasFocusAndSelection.d.ts +3 -0
  64. package/dist/types/selection/selectionFromDOM.d.ts +4 -0
  65. package/dist/types/selection/selectionToDOM.d.ts +9 -0
  66. package/dist/types/ssr.d.ts +19 -0
  67. package/dist/types/tiptap/TiptapEditorContent.d.ts +7 -0
  68. package/dist/types/tiptap/TiptapEditorView.d.ts +13 -0
  69. package/dist/types/tiptap/hooks/useTiptapEditorEffect.d.ts +21 -0
  70. package/dist/types/tiptap/hooks/useTiptapEditorEventCallback.d.ts +13 -0
  71. package/dist/types/tiptap/index.d.ts +5 -0
  72. package/dist/types/tiptap/tiptapNodeView.d.ts +48 -0
  73. package/package.json +8 -1
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "TiptapEditorContent", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return TiptapEditorContent;
9
+ }
10
+ });
11
+ const _react = require("@tiptap/react");
12
+ const _react1 = /*#__PURE__*/ _interop_require_wildcard(require("react"));
13
+ const _ProseMirrorDoc = require("../components/ProseMirrorDoc.js");
14
+ const _useEditorEffect = require("../hooks/useEditorEffect.js");
15
+ function _getRequireWildcardCache(nodeInterop) {
16
+ if (typeof WeakMap !== "function") return null;
17
+ var cacheBabelInterop = new WeakMap();
18
+ var cacheNodeInterop = new WeakMap();
19
+ return (_getRequireWildcardCache = function(nodeInterop) {
20
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
21
+ })(nodeInterop);
22
+ }
23
+ function _interop_require_wildcard(obj, nodeInterop) {
24
+ if (!nodeInterop && obj && obj.__esModule) {
25
+ return obj;
26
+ }
27
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
28
+ return {
29
+ default: obj
30
+ };
31
+ }
32
+ var cache = _getRequireWildcardCache(nodeInterop);
33
+ if (cache && cache.has(obj)) {
34
+ return cache.get(obj);
35
+ }
36
+ var newObj = {
37
+ __proto__: null
38
+ };
39
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
40
+ for(var key in obj){
41
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
42
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
43
+ if (desc && (desc.get || desc.set)) {
44
+ Object.defineProperty(newObj, key, desc);
45
+ } else {
46
+ newObj[key] = obj[key];
47
+ }
48
+ }
49
+ }
50
+ newObj.default = obj;
51
+ if (cache) {
52
+ cache.set(obj, newObj);
53
+ }
54
+ return newObj;
55
+ }
56
+ function TiptapEditorContent(param) {
57
+ let { editor, ...props } = param;
58
+ (0, _useEditorEffect.useEditorEffect)((view)=>{
59
+ if (editor.view === view) {
60
+ return;
61
+ }
62
+ Object.defineProperty(editor, "editorView", {
63
+ value: view,
64
+ configurable: true,
65
+ enumerable: true,
66
+ writable: true
67
+ });
68
+ // @ts-expect-error private method
69
+ editor.injectCSS();
70
+ const dom = view.dom;
71
+ dom.editor = editor;
72
+ setTimeout(()=>{
73
+ if (editor.isDestroyed) {
74
+ return;
75
+ }
76
+ editor.commands.focus(editor.options.autofocus);
77
+ editor.emit("create", {
78
+ editor
79
+ });
80
+ editor.isInitialized = true;
81
+ });
82
+ }, [
83
+ editor
84
+ ]);
85
+ const contextValue = (0, _react1.useMemo)(()=>({
86
+ editor
87
+ }), [
88
+ editor
89
+ ]);
90
+ return /*#__PURE__*/ _react1.default.createElement(_react.EditorContext.Provider, {
91
+ value: contextValue
92
+ }, /*#__PURE__*/ _react1.default.createElement(_ProseMirrorDoc.ProseMirrorDoc, props));
93
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "TiptapEditorView", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return TiptapEditorView;
9
+ }
10
+ });
11
+ const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
12
+ const _ProseMirror = require("../components/ProseMirror.js");
13
+ function _getRequireWildcardCache(nodeInterop) {
14
+ if (typeof WeakMap !== "function") return null;
15
+ var cacheBabelInterop = new WeakMap();
16
+ var cacheNodeInterop = new WeakMap();
17
+ return (_getRequireWildcardCache = function(nodeInterop) {
18
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
19
+ })(nodeInterop);
20
+ }
21
+ function _interop_require_wildcard(obj, nodeInterop) {
22
+ if (!nodeInterop && obj && obj.__esModule) {
23
+ return obj;
24
+ }
25
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
26
+ return {
27
+ default: obj
28
+ };
29
+ }
30
+ var cache = _getRequireWildcardCache(nodeInterop);
31
+ if (cache && cache.has(obj)) {
32
+ return cache.get(obj);
33
+ }
34
+ var newObj = {
35
+ __proto__: null
36
+ };
37
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
38
+ for(var key in obj){
39
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
40
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
41
+ if (desc && (desc.get || desc.set)) {
42
+ Object.defineProperty(newObj, key, desc);
43
+ } else {
44
+ newObj[key] = obj[key];
45
+ }
46
+ }
47
+ }
48
+ newObj.default = obj;
49
+ if (cache) {
50
+ cache.set(obj, newObj);
51
+ }
52
+ return newObj;
53
+ }
54
+ function TiptapEditorView(param) {
55
+ let { editor, nodeViews, children } = param;
56
+ const dispatchTransaction = (0, _react.useCallback)((tr)=>{
57
+ // @ts-expect-error calling private method
58
+ editor.dispatchTransaction(tr);
59
+ }, [
60
+ editor
61
+ ]);
62
+ const initialEditorProps = {
63
+ ...editor.options.editorProps,
64
+ attributes: {
65
+ role: "textbox",
66
+ ...editor.options.editorProps?.attributes
67
+ }
68
+ };
69
+ const { nodeViews: customNodeViews, markViews } = editor.isDestroyed ? {
70
+ nodeViews: undefined,
71
+ markViews: undefined
72
+ } : editor.view.props;
73
+ return /*#__PURE__*/ _react.default.createElement(_ProseMirror.ProseMirror, {
74
+ className: "tiptap",
75
+ ...initialEditorProps,
76
+ markViews: markViews,
77
+ nodeViews: nodeViews,
78
+ customNodeViews: customNodeViews,
79
+ state: editor.isDestroyed || editor.state.plugins.length ? editor.state : editor.state.reconfigure({
80
+ plugins: editor.extensionManager.plugins
81
+ }),
82
+ dispatchTransaction: dispatchTransaction
83
+ }, children);
84
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useTiptapEditorEffect", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useTiptapEditorEffect;
9
+ }
10
+ });
11
+ const _react = require("@tiptap/react");
12
+ const _useEditorEffect = require("../../hooks/useEditorEffect.js");
13
+ function useTiptapEditorEffect(effect, dependencies) {
14
+ const { editor } = (0, _react.useCurrentEditor)();
15
+ (0, _useEditorEffect.useEditorEffect)(()=>{
16
+ if (editor) {
17
+ return effect(editor);
18
+ }
19
+ // The rules of hooks want to be able to statically
20
+ // verify the dependencies for the effect, but this will
21
+ // have already happened at the call-site.
22
+ // eslint-disable-next-line react-hooks/exhaustive-deps
23
+ }, dependencies && [
24
+ editor,
25
+ ...dependencies
26
+ ]);
27
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useTiptapEditorEventCallback", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useTiptapEditorEventCallback;
9
+ }
10
+ });
11
+ const _react = require("@tiptap/react");
12
+ const _useEditorEventCallback = require("../../hooks/useEditorEventCallback.js");
13
+ function assertEditor(editor) {
14
+ if (editor) return;
15
+ throw new DOMException("Tiptap Editor is not initialized", "InvalidStateError");
16
+ }
17
+ function useTiptapEditorEventCallback(callback) {
18
+ const { editor } = (0, _react.useCurrentEditor)();
19
+ return (0, _useEditorEventCallback.useEditorEventCallback)(function(_) {
20
+ for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
21
+ args[_key - 1] = arguments[_key];
22
+ }
23
+ assertEditor(editor);
24
+ return callback(editor, ...args);
25
+ });
26
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ TiptapEditorContent: function() {
13
+ return _TiptapEditorContent.TiptapEditorContent;
14
+ },
15
+ TiptapEditorView: function() {
16
+ return _TiptapEditorView.TiptapEditorView;
17
+ },
18
+ tiptapNodeView: function() {
19
+ return _tiptapNodeView.tiptapNodeView;
20
+ },
21
+ useTiptapEditorEffect: function() {
22
+ return _useTiptapEditorEffect.useTiptapEditorEffect;
23
+ },
24
+ useTiptapEditorEventCallback: function() {
25
+ return _useTiptapEditorEventCallback.useTiptapEditorEventCallback;
26
+ }
27
+ });
28
+ const _tiptapNodeView = require("./tiptapNodeView.js");
29
+ const _TiptapEditorView = require("./TiptapEditorView.js");
30
+ const _TiptapEditorContent = require("./TiptapEditorContent.js");
31
+ const _useTiptapEditorEffect = require("./hooks/useTiptapEditorEffect.js");
32
+ const _useTiptapEditorEventCallback = require("./hooks/useTiptapEditorEventCallback.js");
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "tiptapNodeView", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return tiptapNodeView;
9
+ }
10
+ });
11
+ const _core = require("@tiptap/core");
12
+ const _react = require("@tiptap/react");
13
+ const _classnames = /*#__PURE__*/ _interop_require_default(require("classnames"));
14
+ const _react1 = /*#__PURE__*/ _interop_require_wildcard(require("react"));
15
+ const _useEditorEventCallback = require("../hooks/useEditorEventCallback.js");
16
+ const _useIgnoreMutation = require("../hooks/useIgnoreMutation.js");
17
+ const _useIsNodeSelected = require("../hooks/useIsNodeSelected.js");
18
+ const _useStopEvent = require("../hooks/useStopEvent.js");
19
+ const _props = require("../props.js");
20
+ function _interop_require_default(obj) {
21
+ return obj && obj.__esModule ? obj : {
22
+ default: obj
23
+ };
24
+ }
25
+ function _getRequireWildcardCache(nodeInterop) {
26
+ if (typeof WeakMap !== "function") return null;
27
+ var cacheBabelInterop = new WeakMap();
28
+ var cacheNodeInterop = new WeakMap();
29
+ return (_getRequireWildcardCache = function(nodeInterop) {
30
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
31
+ })(nodeInterop);
32
+ }
33
+ function _interop_require_wildcard(obj, nodeInterop) {
34
+ if (!nodeInterop && obj && obj.__esModule) {
35
+ return obj;
36
+ }
37
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
38
+ return {
39
+ default: obj
40
+ };
41
+ }
42
+ var cache = _getRequireWildcardCache(nodeInterop);
43
+ if (cache && cache.has(obj)) {
44
+ return cache.get(obj);
45
+ }
46
+ var newObj = {
47
+ __proto__: null
48
+ };
49
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
50
+ for(var key in obj){
51
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
52
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
53
+ if (desc && (desc.get || desc.set)) {
54
+ Object.defineProperty(newObj, key, desc);
55
+ } else {
56
+ newObj[key] = obj[key];
57
+ }
58
+ }
59
+ }
60
+ newObj.default = obj;
61
+ if (cache) {
62
+ cache.set(obj, newObj);
63
+ }
64
+ return newObj;
65
+ }
66
+ function tiptapNodeView(param) {
67
+ let { component: WrappedComponent, extension, as: OuterTag = "div", className = "", attrs, contentDOMElementTag: InnerTag = "div", stopEvent, ignoreMutation } = param;
68
+ const TiptapNodeView = /*#__PURE__*/ (0, _react1.memo)(/*#__PURE__*/ (0, _react1.forwardRef)(function TiptapNodeView(param, ref) {
69
+ let { children, nodeProps, ...props } = param;
70
+ const { node, getPos, decorations, innerDecorations } = nodeProps;
71
+ const { editor } = (0, _react.useCurrentEditor)();
72
+ const extensionManager = editor?.extensionManager ?? null;
73
+ const extensions = extensionManager?.extensions ?? null;
74
+ const selected = (0, _useIsNodeSelected.useIsNodeSelected)();
75
+ (0, _useStopEvent.useStopEvent)((_, event)=>{
76
+ if (stopEvent) {
77
+ return stopEvent({
78
+ event
79
+ });
80
+ }
81
+ return false;
82
+ });
83
+ (0, _useIgnoreMutation.useIgnoreMutation)((_, mutation)=>{
84
+ if (ignoreMutation) {
85
+ return ignoreMutation({
86
+ mutation
87
+ });
88
+ }
89
+ return false;
90
+ });
91
+ // This is just a dummy ref to satisfy Tiptap's types
92
+ const innerRef = (0, _react1.useRef)(null);
93
+ const htmlAttributes = (0, _react1.useMemo)(()=>{
94
+ if (!extensions) return {};
95
+ const attributes = (0, _core.getAttributesFromExtensions)(extensions);
96
+ const extensionAttributes = attributes.filter((attribute)=>attribute.type === extension.name);
97
+ return (0, _core.getRenderedAttributes)(node, extensionAttributes);
98
+ }, [
99
+ extensions,
100
+ node
101
+ ]);
102
+ const { extraClassName, htmlProps } = (0, _react1.useMemo)(()=>{
103
+ if (!attrs) return {};
104
+ const resolvedAttrs = typeof attrs === "function" ? attrs({
105
+ node,
106
+ HTMLAttributes: htmlAttributes
107
+ }) : attrs;
108
+ const { className: extraClassName, ...htmlProps } = (0, _props.htmlAttrsToReactProps)(resolvedAttrs);
109
+ return {
110
+ extraClassName,
111
+ htmlProps
112
+ };
113
+ }, [
114
+ htmlAttributes,
115
+ node
116
+ ]);
117
+ const finalClassName = (0, _classnames.default)("react-renderer", `node-${node.type.name}`, className, extraClassName, {
118
+ "ProseMirror-selectednode": selected
119
+ });
120
+ const updateAttributes = (0, _useEditorEventCallback.useEditorEventCallback)((_, attributes)=>{
121
+ if (!editor) {
122
+ return;
123
+ }
124
+ editor.commands.command((param)=>{
125
+ let { tr } = param;
126
+ const pos = getPos();
127
+ tr.setNodeMarkup(pos, undefined, {
128
+ ...node.attrs,
129
+ ...attributes
130
+ });
131
+ return true;
132
+ });
133
+ });
134
+ const deleteNode = (0, _useEditorEventCallback.useEditorEventCallback)(()=>{
135
+ if (!editor) {
136
+ return;
137
+ }
138
+ const from = getPos();
139
+ const to = from + node.nodeSize;
140
+ editor.commands.deleteRange({
141
+ from,
142
+ to
143
+ });
144
+ });
145
+ const nodeViewContext = (0, _react1.useMemo)(()=>({
146
+ nodeViewContentChildren: /*#__PURE__*/ _react1.default.createElement(InnerTag, {
147
+ "data-node-view-content-inner": node.type.name,
148
+ style: {
149
+ whitespace: "inherit"
150
+ }
151
+ }, children)
152
+ }), [
153
+ children,
154
+ node.type.name
155
+ ]);
156
+ if (!editor) return null;
157
+ return /*#__PURE__*/ _react1.default.createElement(_react.ReactNodeViewContext.Provider, {
158
+ value: nodeViewContext
159
+ }, /*#__PURE__*/ _react1.default.createElement(OuterTag, {
160
+ ref: ref,
161
+ className: finalClassName,
162
+ ...props,
163
+ ...htmlProps
164
+ }, /*#__PURE__*/ _react1.default.createElement(WrappedComponent, {
165
+ ref: innerRef,
166
+ node: node,
167
+ getPos: getPos,
168
+ view: editor.view,
169
+ editor: editor,
170
+ decorations: decorations,
171
+ innerDecorations: innerDecorations,
172
+ extension: extension,
173
+ HTMLAttributes: htmlAttributes,
174
+ selected: selected,
175
+ updateAttributes: updateAttributes,
176
+ deleteNode: deleteNode
177
+ })));
178
+ }));
179
+ TiptapNodeView.displayName = `TiptapNodeView(${WrappedComponent.displayName ?? "Anonymous"})`;
180
+ return TiptapNodeView;
181
+ }
@@ -132,6 +132,18 @@ function changedNodeViews(a, b) {
132
132
  }
133
133
  return undefined;
134
134
  }
135
+ destroy() {
136
+ // Prevent the base class from destroying the React-managed nodes.
137
+ // Restore them below after invoking the base class method.
138
+ const reactContent = [
139
+ ...this.dom.childNodes
140
+ ];
141
+ try {
142
+ super.destroy();
143
+ } finally{
144
+ this.dom.replaceChildren(...reactContent);
145
+ }
146
+ }
135
147
  /**
136
148
  * Commit effects by appling the pending props and state.
137
149
  *
@@ -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
  });