@handlewithcare/react-prosemirror 2.4.12 → 2.5.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.
- package/dist/cjs/AbstractEditorView.js +4 -0
- package/dist/cjs/ReactEditorView.js +156 -0
- package/dist/cjs/StaticEditorView.js +86 -0
- package/dist/cjs/components/ChildNodeViews.js +59 -30
- package/dist/cjs/components/CustomNodeView.js +9 -25
- package/dist/cjs/components/DocNodeView.js +6 -15
- package/dist/cjs/components/MarkView.js +1 -2
- package/dist/cjs/components/NativeWidgetView.js +2 -3
- package/dist/cjs/components/NodeView.js +1 -1
- package/dist/cjs/components/ProseMirror.js +11 -14
- package/dist/cjs/components/ReactNodeView.js +3 -4
- package/dist/cjs/components/SeparatorHackView.js +1 -2
- package/dist/cjs/components/TextNodeView.js +4 -5
- package/dist/cjs/components/TrailingHackView.js +1 -2
- package/dist/cjs/components/WidgetView.js +2 -4
- package/dist/cjs/constants.js +33 -0
- package/dist/cjs/hooks/useEditor.js +32 -228
- package/dist/cjs/hooks/useEditorEffect.js +2 -2
- package/dist/cjs/hooks/useEditorEventCallback.js +8 -5
- package/dist/cjs/hooks/useNodeViewDescriptor.js +10 -10
- package/dist/cjs/hooks/useReactKeys.js +1 -1
- package/dist/cjs/testing/editorViewTestHelpers.js +0 -2
- package/dist/cjs/viewdesc.js +10 -9
- package/dist/esm/AbstractEditorView.js +1 -0
- package/dist/esm/ReactEditorView.js +156 -0
- package/dist/esm/StaticEditorView.js +76 -0
- package/dist/esm/components/ChildNodeViews.js +60 -32
- package/dist/esm/components/CustomNodeView.js +9 -25
- package/dist/esm/components/DocNodeView.js +6 -15
- package/dist/esm/components/MarkView.js +1 -2
- package/dist/esm/components/NativeWidgetView.js +2 -3
- package/dist/esm/components/NodeView.js +1 -1
- package/dist/esm/components/ProseMirror.js +11 -14
- package/dist/esm/components/ReactNodeView.js +3 -4
- package/dist/esm/components/SeparatorHackView.js +1 -2
- package/dist/esm/components/TextNodeView.js +4 -5
- package/dist/esm/components/TrailingHackView.js +1 -2
- package/dist/esm/components/WidgetView.js +2 -4
- package/dist/esm/constants.js +15 -0
- package/dist/esm/hooks/useEditor.js +28 -217
- package/dist/esm/hooks/useEditorEffect.js +2 -2
- package/dist/esm/hooks/useEditorEventCallback.js +8 -5
- package/dist/esm/hooks/useNodeViewDescriptor.js +10 -10
- package/dist/esm/hooks/useReactKeys.js +1 -1
- package/dist/esm/testing/editorViewTestHelpers.js +0 -2
- package/dist/esm/viewdesc.js +3 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/AbstractEditorView.d.ts +27 -0
- package/dist/types/ReactEditorView.d.ts +79 -0
- package/dist/types/StaticEditorView.d.ts +24 -0
- package/dist/types/components/ChildNodeViews.d.ts +2 -2
- package/dist/types/components/CustomNodeView.d.ts +2 -2
- package/dist/types/components/DocNodeView.d.ts +2 -5
- package/dist/types/components/MarkView.d.ts +2 -2
- package/dist/types/components/NativeWidgetView.d.ts +2 -2
- package/dist/types/components/NodeView.d.ts +2 -2
- package/dist/types/components/ReactNodeView.d.ts +2 -2
- package/dist/types/components/SeparatorHackView.d.ts +2 -2
- package/dist/types/components/TextNodeView.d.ts +4 -3
- package/dist/types/components/TrailingHackView.d.ts +2 -2
- package/dist/types/components/WidgetView.d.ts +2 -2
- package/dist/types/constants.d.ts +4 -0
- package/dist/types/contexts/EditorContext.d.ts +6 -4
- package/dist/types/decorations/computeDocDeco.d.ts +3 -2
- package/dist/types/decorations/viewDecorations.d.ts +3 -2
- package/dist/types/hooks/useEditor.d.ts +5 -46
- package/dist/types/hooks/useNodeViewDescriptor.d.ts +1 -1
- package/dist/types/hooks/useReactKeys.d.ts +1 -1
- package/dist/types/props.d.ts +3 -3
- package/dist/types/viewdesc.d.ts +6 -5
- package/package.json +6 -2
- package/dist/cjs/components/Editor.js +0 -28
- package/dist/cjs/components/NodeViews.js +0 -73
- package/dist/cjs/components/__tests__/LayoutGroup.test.js +0 -141
- package/dist/cjs/components/__tests__/ProseMirror.test.js +0 -255
- package/dist/cjs/contexts/NodeViewsContext.js +0 -10
- package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -107
- package/dist/cjs/hooks/__tests__/useNodeViews.test.js +0 -159
- package/dist/cjs/hooks/useEditorView.js +0 -100
- package/dist/cjs/hooks/useNodePos.js +0 -69
- package/dist/cjs/hooks/useNodeViews.js +0 -100
- package/dist/cjs/nodeViews/createReactNodeViewConstructor.js +0 -244
- package/dist/cjs/nodeViews/phrasingContentTags.js +0 -57
- package/dist/cjs/plugins/__tests__/react.test.js +0 -139
- package/dist/cjs/plugins/react.js +0 -71
- package/dist/cjs/selection/SelectionDOMObserver.js +0 -171
- package/dist/cjs/selection/hasFocusAndSelection.js +0 -35
- package/dist/cjs/selection/selectionFromDOM.js +0 -77
- package/dist/cjs/selection/selectionToDOM.js +0 -226
- package/dist/cjs/ssr.js +0 -85
- package/dist/esm/components/Editor.js +0 -15
- package/dist/esm/components/NodeViews.js +0 -26
- package/dist/esm/components/__tests__/LayoutGroup.test.js +0 -98
- package/dist/esm/components/__tests__/ProseMirror.test.js +0 -207
- package/dist/esm/contexts/NodeViewsContext.js +0 -9
- package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -98
- package/dist/esm/hooks/__tests__/useNodeViews.test.js +0 -116
- package/dist/esm/hooks/useEditorView.js +0 -99
- package/dist/esm/hooks/useNodePos.js +0 -16
- package/dist/esm/hooks/useNodeViews.js +0 -53
- package/dist/esm/nodeViews/createReactNodeViewConstructor.js +0 -214
- package/dist/esm/nodeViews/phrasingContentTags.js +0 -49
- package/dist/esm/plugins/__tests__/react.test.js +0 -135
- package/dist/esm/plugins/react.js +0 -64
- package/dist/esm/selection/SelectionDOMObserver.js +0 -161
- package/dist/esm/selection/hasFocusAndSelection.js +0 -17
- package/dist/esm/selection/selectionFromDOM.js +0 -59
- package/dist/esm/selection/selectionToDOM.js +0 -196
- package/dist/esm/ssr.js +0 -82
- package/dist/types/components/Editor.d.ts +0 -7
- package/dist/types/components/NodeViews.d.ts +0 -6
- package/dist/types/components/__tests__/LayoutGroup.test.d.ts +0 -1
- package/dist/types/contexts/NodeViewsContext.d.ts +0 -19
- package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +0 -1
- package/dist/types/hooks/__tests__/useNodeViews.test.d.ts +0 -1
- package/dist/types/hooks/useEditorView.d.ts +0 -23
- package/dist/types/hooks/useNodePos.d.ts +0 -9
- package/dist/types/hooks/useNodeViews.d.ts +0 -5
- package/dist/types/nodeViews/createReactNodeViewConstructor.d.ts +0 -48
- package/dist/types/nodeViews/phrasingContentTags.d.ts +0 -1
- package/dist/types/plugins/__tests__/react.test.d.ts +0 -1
- package/dist/types/plugins/react.d.ts +0 -21
- package/dist/types/selection/SelectionDOMObserver.d.ts +0 -33
- package/dist/types/selection/hasFocusAndSelection.d.ts +0 -3
- package/dist/types/selection/selectionFromDOM.d.ts +0 -4
- package/dist/types/selection/selectionToDOM.d.ts +0 -9
- package/dist/types/ssr.d.ts +0 -19
package/dist/cjs/viewdesc.js
CHANGED
|
@@ -36,7 +36,7 @@ _export(exports, {
|
|
|
36
36
|
});
|
|
37
37
|
const _prosemirrormodel = require("prosemirror-model");
|
|
38
38
|
const _browser = require("./browser.js");
|
|
39
|
-
const
|
|
39
|
+
const _dom = require("./dom.js");
|
|
40
40
|
function sortViewDescs(a, b) {
|
|
41
41
|
if (a instanceof TrailingHackViewDesc) return 1;
|
|
42
42
|
if (b instanceof TrailingHackViewDesc) return -1;
|
|
@@ -157,7 +157,7 @@ let ViewDesc = class ViewDesc {
|
|
|
157
157
|
// start or at the end of this view desc.
|
|
158
158
|
let atEnd;
|
|
159
159
|
if (dom == this.dom && this.contentDOM) {
|
|
160
|
-
atEnd = offset > (0,
|
|
160
|
+
atEnd = offset > (0, _dom.domIndex)(this.contentDOM);
|
|
161
161
|
} else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
162
162
|
atEnd = dom.compareDocumentPosition(this.contentDOM) & 2;
|
|
163
163
|
} else if (this.dom.firstChild) {
|
|
@@ -258,7 +258,7 @@ let ViewDesc = class ViewDesc {
|
|
|
258
258
|
if (prev && side && enter && !prev.border && !prev.domAtom) return prev.domFromPos(prev.size, side);
|
|
259
259
|
return {
|
|
260
260
|
node: this.contentDOM,
|
|
261
|
-
offset: prev ? (0,
|
|
261
|
+
offset: prev ? (0, _dom.domIndex)(prev.dom) + 1 : 0
|
|
262
262
|
};
|
|
263
263
|
} else {
|
|
264
264
|
let next, enter = true;
|
|
@@ -269,7 +269,7 @@ let ViewDesc = class ViewDesc {
|
|
|
269
269
|
if (next && enter && !next.border && !next.domAtom) return next.domFromPos(0, side);
|
|
270
270
|
return {
|
|
271
271
|
node: this.contentDOM,
|
|
272
|
-
offset: next ? (0,
|
|
272
|
+
offset: next ? (0, _dom.domIndex)(next.dom) : this.contentDOM.childNodes.length
|
|
273
273
|
};
|
|
274
274
|
}
|
|
275
275
|
}
|
|
@@ -295,7 +295,7 @@ let ViewDesc = class ViewDesc {
|
|
|
295
295
|
for(let j = i; j > 0; j--){
|
|
296
296
|
const prev = this.children[j - 1];
|
|
297
297
|
if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {
|
|
298
|
-
fromOffset = (0,
|
|
298
|
+
fromOffset = (0, _dom.domIndex)(prev.dom) + 1;
|
|
299
299
|
break;
|
|
300
300
|
}
|
|
301
301
|
from -= prev.size;
|
|
@@ -307,7 +307,7 @@ let ViewDesc = class ViewDesc {
|
|
|
307
307
|
for(let j = i + 1; j < this.children.length; j++){
|
|
308
308
|
const next = this.children[j];
|
|
309
309
|
if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {
|
|
310
|
-
toOffset = (0,
|
|
310
|
+
toOffset = (0, _dom.domIndex)(next.dom);
|
|
311
311
|
break;
|
|
312
312
|
}
|
|
313
313
|
to += next.size;
|
|
@@ -354,7 +354,6 @@ let ViewDesc = class ViewDesc {
|
|
|
354
354
|
let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1);
|
|
355
355
|
let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1);
|
|
356
356
|
const domSel = view.root.getSelection();
|
|
357
|
-
// @ts-expect-error - Internal method domSelectionRange
|
|
358
357
|
const selRange = view.domSelectionRange();
|
|
359
358
|
let brKludge = false;
|
|
360
359
|
// On Firefox, using Selection.collapse to put the cursor after a
|
|
@@ -371,7 +370,7 @@ let ViewDesc = class ViewDesc {
|
|
|
371
370
|
if (after = scan.nextSibling) {
|
|
372
371
|
if (after.nodeName == "BR") anchorDOM = headDOM = {
|
|
373
372
|
node: after.parentNode,
|
|
374
|
-
offset: (0,
|
|
373
|
+
offset: (0, _dom.domIndex)(after) + 1
|
|
375
374
|
};
|
|
376
375
|
break;
|
|
377
376
|
}
|
|
@@ -391,7 +390,7 @@ let ViewDesc = class ViewDesc {
|
|
|
391
390
|
const after = selRange.focusNode.childNodes[selRange.focusOffset];
|
|
392
391
|
if (after && after.contentEditable == "false") force = true;
|
|
393
392
|
}
|
|
394
|
-
if (!(force || brKludge && _browser.browser.safari) && (0,
|
|
393
|
+
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
394
|
// Selection.extend can be used to create an 'inverted' selection
|
|
396
395
|
// (one where the focus is before the anchor), but not all
|
|
397
396
|
// browsers support it yet.
|
|
@@ -609,6 +608,7 @@ let NodeViewDesc = class NodeViewDesc extends ViewDesc {
|
|
|
609
608
|
// If this desc must be updated to match the given node decoration,
|
|
610
609
|
// do so and return true.
|
|
611
610
|
update(_node, _outerDeco, _innerDeco, _view) {
|
|
611
|
+
this.dirty = NOT_DIRTY;
|
|
612
612
|
return true;
|
|
613
613
|
}
|
|
614
614
|
get domAtom() {
|
|
@@ -631,6 +631,7 @@ let TextViewDesc = class TextViewDesc extends NodeViewDesc {
|
|
|
631
631
|
};
|
|
632
632
|
}
|
|
633
633
|
update(_node, _outerDeco, _innerDeco, _view) {
|
|
634
|
+
this.dirty = NOT_DIRTY;
|
|
634
635
|
return true;
|
|
635
636
|
}
|
|
636
637
|
inParent() {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { EditorView } from "prosemirror-view";
|
|
2
|
+
import { EMPTY_STATE } from "./constants.js";
|
|
3
|
+
function buildNodeViews(view) {
|
|
4
|
+
const result = Object.create(null);
|
|
5
|
+
function add(obj) {
|
|
6
|
+
for(const prop in obj)if (!Object.prototype.hasOwnProperty.call(result, prop)) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
7
|
+
result[prop] = obj[prop];
|
|
8
|
+
}
|
|
9
|
+
view.someProp("nodeViews", add);
|
|
10
|
+
view.someProp("markViews", add);
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
function changedNodeViews(a, b) {
|
|
14
|
+
let nA = 0, nB = 0;
|
|
15
|
+
for(const prop in a){
|
|
16
|
+
if (a[prop] != b[prop]) return true;
|
|
17
|
+
nA++;
|
|
18
|
+
}
|
|
19
|
+
for(const _ in b)nB++;
|
|
20
|
+
return nA != nB;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extends EditorView to make prop and state updates pure, remove the DOM
|
|
24
|
+
* Mutation Observer, and use a custom document view managed by React.
|
|
25
|
+
*
|
|
26
|
+
* @privateRemarks
|
|
27
|
+
*
|
|
28
|
+
* The implementation relies on the base class using a private member to store
|
|
29
|
+
* the committed props and having a public getter that we override to return the
|
|
30
|
+
* latest, uncommitted props. The base class can then be told to update when the
|
|
31
|
+
* React effects are commit an update, applying the pending, uncommitted props.
|
|
32
|
+
*/ export class ReactEditorView extends EditorView {
|
|
33
|
+
nextProps;
|
|
34
|
+
prevState;
|
|
35
|
+
constructor(place, props){
|
|
36
|
+
// By the time the editor view mounts this should exist.
|
|
37
|
+
// We assume it is not possible to set the mount point otherwise.
|
|
38
|
+
const docView = place.mount.pmViewDesc;
|
|
39
|
+
// Prevent the base class from destroying the React-managed nodes.
|
|
40
|
+
// Restore them below after invoking the base class constructor.
|
|
41
|
+
const reactContent = [
|
|
42
|
+
...place.mount.childNodes
|
|
43
|
+
];
|
|
44
|
+
// Prevent the base class from mutating the React-managed attributes.
|
|
45
|
+
// Restore them below after invoking the base class constructor.
|
|
46
|
+
const reactAttrs = [
|
|
47
|
+
...place.mount.attributes
|
|
48
|
+
];
|
|
49
|
+
for (const attr of reactAttrs){
|
|
50
|
+
place.mount.removeAttributeNode(attr);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
// Call the superclass constructor with only a state and no plugins.
|
|
54
|
+
// We'll set everything else ourselves and apply props during layout.
|
|
55
|
+
super(place, {
|
|
56
|
+
state: EMPTY_STATE
|
|
57
|
+
});
|
|
58
|
+
this.domObserver.stop();
|
|
59
|
+
this.domObserver.observer = null;
|
|
60
|
+
this.domObserver.queue = [];
|
|
61
|
+
} finally{
|
|
62
|
+
place.mount.replaceChildren(...reactContent);
|
|
63
|
+
for (const attr of place.mount.attributes){
|
|
64
|
+
place.mount.removeAttributeNode(attr);
|
|
65
|
+
}
|
|
66
|
+
for (const attr of reactAttrs){
|
|
67
|
+
place.mount.setAttributeNode(attr);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
this.prevState = EMPTY_STATE;
|
|
71
|
+
this.nextProps = props;
|
|
72
|
+
this.state = props.state;
|
|
73
|
+
this.nodeViews = buildNodeViews(this);
|
|
74
|
+
this.docView = docView;
|
|
75
|
+
this.dom.pmViewDesc = docView;
|
|
76
|
+
}
|
|
77
|
+
get props() {
|
|
78
|
+
return this.nextProps;
|
|
79
|
+
}
|
|
80
|
+
setProps(props) {
|
|
81
|
+
this.update({
|
|
82
|
+
...this.props,
|
|
83
|
+
...props
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
update(props) {
|
|
87
|
+
const prevProps = this.nextProps;
|
|
88
|
+
this.nextProps = props;
|
|
89
|
+
this.state = props.state;
|
|
90
|
+
if (prevProps.state.plugins !== props.state.plugins || prevProps.plugins !== props.plugins) {
|
|
91
|
+
const nodeViews = buildNodeViews(this);
|
|
92
|
+
if (changedNodeViews(this.nodeViews, nodeViews)) {
|
|
93
|
+
this.nodeViews = nodeViews;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
this.editable = !this.someProp("editable", (value)=>value(this.state) === false);
|
|
97
|
+
}
|
|
98
|
+
updateState(state) {
|
|
99
|
+
this.setProps({
|
|
100
|
+
state
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
someProp(propName, f) {
|
|
104
|
+
if (!this.props) {
|
|
105
|
+
// The base class constructor calls this method before props are set.
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const prop = this.props[propName];
|
|
109
|
+
if (prop) {
|
|
110
|
+
const result = f ? f(prop) : prop;
|
|
111
|
+
if (result) {
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
for (const plugin of this.props.plugins ?? []){
|
|
116
|
+
const prop = plugin.props[propName];
|
|
117
|
+
if (prop) {
|
|
118
|
+
const result = f ? f(prop) : prop;
|
|
119
|
+
if (result) {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
for (const plugin of this.state.plugins){
|
|
125
|
+
const prop = plugin.props[propName];
|
|
126
|
+
if (prop) {
|
|
127
|
+
const result = f ? f(prop) : prop;
|
|
128
|
+
if (result) {
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Commit effects by appling the pending props and state.
|
|
137
|
+
*
|
|
138
|
+
* Ensures the DOM selection is correct and updates plugin views.
|
|
139
|
+
*
|
|
140
|
+
* @privateRemarks
|
|
141
|
+
*
|
|
142
|
+
* The correctness of this depends on the pure update function ensuring that
|
|
143
|
+
* the node view set is up to date so that it does not try to redraw.
|
|
144
|
+
*/ commitPendingEffects() {
|
|
145
|
+
// This class tracks state eagerly but the base class does it lazily.
|
|
146
|
+
// Temporarily roll it back so the base class can handle the updates.
|
|
147
|
+
this.state = this.prevState;
|
|
148
|
+
// Force the base class to try to update the document. React updated it, but
|
|
149
|
+
// this ensures that the base class validates the DOM selection and invokes
|
|
150
|
+
// node view selection callbacks.
|
|
151
|
+
this.docView.markDirty(-1, -1);
|
|
152
|
+
super.update(this.nextProps);
|
|
153
|
+
// Store the new previous state.
|
|
154
|
+
this.prevState = this.state;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export class StaticEditorView {
|
|
2
|
+
props;
|
|
3
|
+
nodeViews;
|
|
4
|
+
constructor(props){
|
|
5
|
+
this.props = props;
|
|
6
|
+
this.nodeViews = {};
|
|
7
|
+
}
|
|
8
|
+
get composing() {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
get dom() {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
get editable() {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
get state() {
|
|
18
|
+
return this.props.state;
|
|
19
|
+
}
|
|
20
|
+
setProps(props) {
|
|
21
|
+
return this.update({
|
|
22
|
+
...this.props,
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
update(props) {
|
|
27
|
+
this.props = props;
|
|
28
|
+
}
|
|
29
|
+
updateState(state) {
|
|
30
|
+
this.setProps({
|
|
31
|
+
state
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
someProp(propName, f) {
|
|
35
|
+
const prop = this.props[propName];
|
|
36
|
+
if (prop) {
|
|
37
|
+
const result = f ? f(prop) : prop;
|
|
38
|
+
if (result) {
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
for (const plugin of this.props.plugins ?? []){
|
|
43
|
+
const prop = plugin.props[propName];
|
|
44
|
+
if (prop) {
|
|
45
|
+
const result = f ? f(prop) : prop;
|
|
46
|
+
if (result) {
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const plugin of this.state.plugins){
|
|
52
|
+
const prop = plugin.props[propName];
|
|
53
|
+
if (prop) {
|
|
54
|
+
const result = f ? f(prop) : prop;
|
|
55
|
+
if (result) {
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
destroy() {
|
|
63
|
+
// pass
|
|
64
|
+
}
|
|
65
|
+
domSelectionRange() {
|
|
66
|
+
return {
|
|
67
|
+
anchorNode: null,
|
|
68
|
+
anchorOffset: 0,
|
|
69
|
+
focusNode: null,
|
|
70
|
+
focusOffset: 0
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
domSelection() {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import React, { cloneElement, createElement, memo, useContext, useRef } from "react";
|
|
1
|
+
import React, { cloneElement, createElement, memo, useCallback, useContext, useRef } from "react";
|
|
2
2
|
import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
|
|
3
3
|
import { EditorContext } from "../contexts/EditorContext.js";
|
|
4
4
|
import { iterDeco } from "../decorations/iterDeco.js";
|
|
5
|
-
// import { useEditorState } from "../hooks/useEditorState.js";
|
|
6
5
|
import { useReactKeys } from "../hooks/useReactKeys.js";
|
|
7
6
|
import { htmlAttrsToReactProps, mergeReactProps } from "../props.js";
|
|
8
7
|
import { MarkView } from "./MarkView.js";
|
|
@@ -24,21 +23,30 @@ export function wrapInDeco(reactNode, deco) {
|
|
|
24
23
|
return /*#__PURE__*/ cloneElement(reactNode, mergeReactProps(reactNode.props, props));
|
|
25
24
|
}
|
|
26
25
|
function areChildrenEqual(a, b) {
|
|
27
|
-
return a.type === b.type && a.marks.every((mark)=>mark.isInSet(b.marks)) && b.marks.every((mark)=>mark.isInSet(a.marks)) && a.key === b.key && (a.type === "node" ? a.outerDeco?.length === b.outerDeco?.length && a.outerDeco?.every((prevDeco)=>b.outerDeco?.some((nextDeco)=>prevDeco.from === nextDeco.from && prevDeco.to && nextDeco.to &&
|
|
26
|
+
return a.type === b.type && a.marks.every((mark)=>mark.isInSet(b.marks)) && b.marks.every((mark)=>mark.isInSet(a.marks)) && a.key === b.key && (a.type === "node" ? a.outerDeco?.length === b.outerDeco?.length && a.outerDeco?.every((prevDeco)=>b.outerDeco?.some((nextDeco)=>prevDeco.from === nextDeco.from && prevDeco.to && nextDeco.to && // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
prevDeco.type.eq(nextDeco.type))) && a.innerDeco.eq(b.innerDeco) : true) && a.node === b.node && a.widget === b.widget;
|
|
28
28
|
}
|
|
29
29
|
const ChildView = /*#__PURE__*/ memo(function ChildView(param) {
|
|
30
30
|
let { child, getInnerPos } = param;
|
|
31
31
|
const { view } = useContext(EditorContext);
|
|
32
|
-
const
|
|
33
|
-
|
|
32
|
+
const childRef = useRef(child);
|
|
33
|
+
childRef.current = child;
|
|
34
|
+
const getPos = useCallback(()=>{
|
|
35
|
+
return getInnerPos() + childRef.current.offset;
|
|
36
|
+
}, [
|
|
37
|
+
getInnerPos
|
|
38
|
+
]);
|
|
34
39
|
return child.type === "widget" ? /*#__PURE__*/ React.createElement(WidgetView, {
|
|
35
40
|
key: child.key,
|
|
36
41
|
widget: child.widget,
|
|
37
|
-
getPos:
|
|
42
|
+
getPos: getPos
|
|
38
43
|
}) : child.type === "native-widget" ? /*#__PURE__*/ React.createElement(NativeWidgetView, {
|
|
39
44
|
key: child.key,
|
|
40
45
|
widget: child.widget,
|
|
41
|
-
getPos:
|
|
46
|
+
getPos: getPos
|
|
47
|
+
}) : child.type === "hack" ? /*#__PURE__*/ React.createElement(child.component, {
|
|
48
|
+
key: child.key,
|
|
49
|
+
getPos: getPos
|
|
42
50
|
}) : child.node.isText ? /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Consumer, {
|
|
43
51
|
key: child.key
|
|
44
52
|
}, (param)=>{
|
|
@@ -46,7 +54,7 @@ const ChildView = /*#__PURE__*/ memo(function ChildView(param) {
|
|
|
46
54
|
return /*#__PURE__*/ React.createElement(TextNodeView, {
|
|
47
55
|
view: view,
|
|
48
56
|
node: child.node,
|
|
49
|
-
getPos:
|
|
57
|
+
getPos: getPos,
|
|
50
58
|
siblingsRef: siblingsRef,
|
|
51
59
|
parentRef: parentRef,
|
|
52
60
|
decorations: child.outerDeco
|
|
@@ -54,7 +62,7 @@ const ChildView = /*#__PURE__*/ memo(function ChildView(param) {
|
|
|
54
62
|
}) : /*#__PURE__*/ React.createElement(NodeView, {
|
|
55
63
|
key: child.key,
|
|
56
64
|
node: child.node,
|
|
57
|
-
getPos:
|
|
65
|
+
getPos: getPos,
|
|
58
66
|
outerDeco: child.outerDeco,
|
|
59
67
|
innerDeco: child.innerDeco
|
|
60
68
|
});
|
|
@@ -62,8 +70,13 @@ const ChildView = /*#__PURE__*/ memo(function ChildView(param) {
|
|
|
62
70
|
const InlinePartition = /*#__PURE__*/ memo(function InlinePartition(param) {
|
|
63
71
|
let { childViews, getInnerPos } = param;
|
|
64
72
|
const firstChild = childViews[0];
|
|
65
|
-
const
|
|
66
|
-
|
|
73
|
+
const firstChildRef = useRef(firstChild);
|
|
74
|
+
firstChildRef.current = firstChild;
|
|
75
|
+
const getPos = useCallback(()=>{
|
|
76
|
+
return getInnerPos() + firstChildRef.current.offset;
|
|
77
|
+
}, [
|
|
78
|
+
getInnerPos
|
|
79
|
+
]);
|
|
67
80
|
const firstMark = firstChild.marks[0];
|
|
68
81
|
if (!firstMark) {
|
|
69
82
|
return /*#__PURE__*/ React.createElement(React.Fragment, null, childViews.map((child)=>{
|
|
@@ -75,9 +88,9 @@ const InlinePartition = /*#__PURE__*/ memo(function InlinePartition(param) {
|
|
|
75
88
|
}));
|
|
76
89
|
}
|
|
77
90
|
return /*#__PURE__*/ React.createElement(MarkView, {
|
|
78
|
-
getPos: getFirstChildPos,
|
|
79
91
|
key: firstChild.key,
|
|
80
|
-
mark: firstMark
|
|
92
|
+
mark: firstMark,
|
|
93
|
+
getPos: getPos
|
|
81
94
|
}, /*#__PURE__*/ React.createElement(InlineView, {
|
|
82
95
|
key: firstChild.key,
|
|
83
96
|
getInnerPos: getInnerPos,
|
|
@@ -135,7 +148,7 @@ const InlineView = /*#__PURE__*/ memo(function InlineView(param) {
|
|
|
135
148
|
});
|
|
136
149
|
}));
|
|
137
150
|
});
|
|
138
|
-
function createKey(innerPos, offset, type, posToKey, widget
|
|
151
|
+
function createKey(innerPos, offset, index, type, posToKey, widget) {
|
|
139
152
|
const pos = innerPos + offset;
|
|
140
153
|
const key = posToKey?.get(pos);
|
|
141
154
|
if (type === "widget" || type === "native-widget") {
|
|
@@ -179,18 +192,23 @@ function adjustWidgetMarksBack(widgetChildren, nodeChild) {
|
|
|
179
192
|
}
|
|
180
193
|
const ChildElement = /*#__PURE__*/ memo(function ChildElement(param) {
|
|
181
194
|
let { child, getInnerPos } = param;
|
|
182
|
-
const
|
|
183
|
-
|
|
195
|
+
const childRef = useRef(child);
|
|
196
|
+
childRef.current = child;
|
|
197
|
+
const getPos = useCallback(()=>{
|
|
198
|
+
return getInnerPos() + childRef.current.offset;
|
|
199
|
+
}, [
|
|
200
|
+
getInnerPos
|
|
201
|
+
]);
|
|
184
202
|
if (child.type === "node") {
|
|
185
203
|
return child.marks.reduce((element, mark)=>/*#__PURE__*/ React.createElement(MarkView, {
|
|
186
|
-
|
|
187
|
-
|
|
204
|
+
mark: mark,
|
|
205
|
+
getPos: getPos
|
|
188
206
|
}, element), /*#__PURE__*/ React.createElement(NodeView, {
|
|
189
207
|
key: child.key,
|
|
190
208
|
outerDeco: child.outerDeco,
|
|
191
209
|
node: child.node,
|
|
192
210
|
innerDeco: child.innerDeco,
|
|
193
|
-
getPos:
|
|
211
|
+
getPos: getPos
|
|
194
212
|
}));
|
|
195
213
|
} else {
|
|
196
214
|
return /*#__PURE__*/ React.createElement(InlineView, {
|
|
@@ -224,9 +242,10 @@ function createChildElements(children, getInnerPos) {
|
|
|
224
242
|
}
|
|
225
243
|
export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param) {
|
|
226
244
|
let { getPos, node, innerDecorations } = param;
|
|
227
|
-
// const editorState = useEditorState();
|
|
228
245
|
const reactKeys = useReactKeys();
|
|
229
|
-
const getInnerPos =
|
|
246
|
+
const getInnerPos = useCallback(()=>getPos() + 1, [
|
|
247
|
+
getPos
|
|
248
|
+
]);
|
|
230
249
|
const childMap = useRef(new Map()).current;
|
|
231
250
|
if (!node) return null;
|
|
232
251
|
const keysSeen = new Map();
|
|
@@ -237,7 +256,7 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
|
|
|
237
256
|
const widgetMarks = widget.type.spec.marks ?? [];
|
|
238
257
|
let key;
|
|
239
258
|
if (isNative) {
|
|
240
|
-
key = createKey(getInnerPos
|
|
259
|
+
key = createKey(getInnerPos(), offset, index, "native-widget", reactKeys?.posToKey, widget);
|
|
241
260
|
const child = {
|
|
242
261
|
type: "native-widget",
|
|
243
262
|
widget,
|
|
@@ -254,7 +273,7 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
|
|
|
254
273
|
}
|
|
255
274
|
keysSeen.set(key, keysSeen.size);
|
|
256
275
|
} else {
|
|
257
|
-
key = createKey(getInnerPos
|
|
276
|
+
key = createKey(getInnerPos(), offset, index, "widget", reactKeys?.posToKey, widget);
|
|
258
277
|
const child = {
|
|
259
278
|
type: "widget",
|
|
260
279
|
widget: widget,
|
|
@@ -274,8 +293,8 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
|
|
|
274
293
|
const child = childMap.get(key);
|
|
275
294
|
widgetChildren.push(child);
|
|
276
295
|
adjustWidgetMarksForward(lastNodeChild, childMap.get(key));
|
|
277
|
-
}, (childNode, outerDeco, innerDeco, offset)=>{
|
|
278
|
-
const key = createKey(getInnerPos
|
|
296
|
+
}, (childNode, outerDeco, innerDeco, offset, index)=>{
|
|
297
|
+
const key = createKey(getInnerPos(), offset, index, "node", reactKeys?.posToKey);
|
|
279
298
|
const child = {
|
|
280
299
|
type: "node",
|
|
281
300
|
node: childNode,
|
|
@@ -283,6 +302,7 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
|
|
|
283
302
|
innerDeco,
|
|
284
303
|
outerDeco,
|
|
285
304
|
offset,
|
|
305
|
+
index,
|
|
286
306
|
key
|
|
287
307
|
};
|
|
288
308
|
const prevChild = childMap.get(key);
|
|
@@ -306,20 +326,28 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
|
|
|
306
326
|
// step
|
|
307
327
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
308
328
|
(a, b)=>keysSeen.get(a.key) - keysSeen.get(b.key));
|
|
309
|
-
const childElements = createChildElements(children, getInnerPos);
|
|
310
329
|
if (node.isTextblock) {
|
|
311
330
|
const lastChild = children[children.length - 1];
|
|
312
331
|
if (!lastChild || lastChild.type !== "node" || lastChild.node.isInline && !lastChild.node.isText || // RegExp.test actually handles undefined just fine
|
|
313
332
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
314
333
|
/\n$/.test(lastChild.node.text)) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
334
|
+
children.push({
|
|
335
|
+
type: "hack",
|
|
336
|
+
component: TrailingHackView,
|
|
337
|
+
marks: [],
|
|
338
|
+
offset: lastChild?.offset ?? 0,
|
|
339
|
+
index: (lastChild?.index ?? 0) + 1,
|
|
320
340
|
key: "trailing-hack-br"
|
|
321
|
-
}
|
|
341
|
+
}, {
|
|
342
|
+
type: "hack",
|
|
343
|
+
component: SeparatorHackView,
|
|
344
|
+
marks: [],
|
|
345
|
+
offset: lastChild?.offset ?? 0,
|
|
346
|
+
index: (lastChild?.index ?? 0) + 2,
|
|
347
|
+
key: "trailing-hack-img"
|
|
348
|
+
});
|
|
322
349
|
}
|
|
323
350
|
}
|
|
351
|
+
const childElements = createChildElements(children, getInnerPos);
|
|
324
352
|
return /*#__PURE__*/ React.createElement(React.Fragment, null, childElements);
|
|
325
353
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NodeSelection } from "prosemirror-state";
|
|
2
1
|
import React, { cloneElement, createElement, memo, useContext, useMemo, useRef } from "react";
|
|
3
2
|
import { createPortal } from "react-dom";
|
|
4
3
|
import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
|
|
@@ -10,11 +9,12 @@ import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js";
|
|
|
10
9
|
import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js";
|
|
11
10
|
export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param) {
|
|
12
11
|
let { customNodeView, node, getPos, innerDeco, outerDeco } = param;
|
|
13
|
-
const
|
|
12
|
+
const editor = useContext(EditorContext);
|
|
13
|
+
// Only ReactEditorView supports custom node views.
|
|
14
|
+
const view = editor.view;
|
|
14
15
|
const domRef = useRef(null);
|
|
15
16
|
const nodeDomRef = useRef(null);
|
|
16
17
|
const contentDomRef = useRef(null);
|
|
17
|
-
const getPosFunc = useRef(()=>getPos.current()).current;
|
|
18
18
|
const nodeRef = useRef(node);
|
|
19
19
|
nodeRef.current = node;
|
|
20
20
|
const outerDecoRef = useRef(outerDeco);
|
|
@@ -31,10 +31,7 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
|
|
|
31
31
|
// the node view when the layout effect is re-run.
|
|
32
32
|
useClientLayoutEffect(()=>{
|
|
33
33
|
if (!customNodeViewRef.current) {
|
|
34
|
-
customNodeViewRef.current = customNodeView(nodeRef.current,
|
|
35
|
-
// this line if customNodeView is set
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
37
|
-
view, getPosFunc, outerDecoRef.current, innerDecoRef.current);
|
|
34
|
+
customNodeViewRef.current = customNodeView(nodeRef.current, view, getPos, outerDecoRef.current, innerDecoRef.current);
|
|
38
35
|
if (customNodeViewRef.current.stopEvent) {
|
|
39
36
|
setStopEvent(customNodeViewRef.current.stopEvent.bind(customNodeViewRef.current));
|
|
40
37
|
}
|
|
@@ -56,12 +53,6 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
|
|
|
56
53
|
}
|
|
57
54
|
nodeDomRef.current = customNodeViewRootRef.current;
|
|
58
55
|
customNodeViewRootRef.current.appendChild(dom);
|
|
59
|
-
// Layout effects can run multiple times — if this effect
|
|
60
|
-
// destroyed and recreated this node view, then we need to
|
|
61
|
-
// resync the selectNode state
|
|
62
|
-
if (view?.state.selection instanceof NodeSelection && view.state.selection.node === nodeRef.current) {
|
|
63
|
-
customNodeViewRef.current.selectNode?.();
|
|
64
|
-
}
|
|
65
56
|
const nodeView = customNodeViewRef.current;
|
|
66
57
|
return ()=>{
|
|
67
58
|
nodeView.destroy?.();
|
|
@@ -75,7 +66,7 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
|
|
|
75
66
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
67
|
}, [
|
|
77
68
|
customNodeView,
|
|
78
|
-
|
|
69
|
+
getPos,
|
|
79
70
|
view
|
|
80
71
|
]);
|
|
81
72
|
useClientLayoutEffect(()=>{
|
|
@@ -85,10 +76,7 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
|
|
|
85
76
|
if (updated) return;
|
|
86
77
|
destroy?.call(customNodeViewRef.current);
|
|
87
78
|
if (!customNodeViewRootRef.current) return;
|
|
88
|
-
customNodeViewRef.current = customNodeView(nodeRef.current,
|
|
89
|
-
// this line if customNodeView is set
|
|
90
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
91
|
-
view, getPosFunc, outerDecoRef.current, innerDecoRef.current);
|
|
79
|
+
customNodeViewRef.current = customNodeView(nodeRef.current, view, getPos, outerDecoRef.current, innerDecoRef.current);
|
|
92
80
|
const { dom } = customNodeViewRef.current;
|
|
93
81
|
nodeDomRef.current = customNodeViewRootRef.current;
|
|
94
82
|
customNodeViewRootRef.current.appendChild(dom);
|
|
@@ -98,10 +86,9 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
|
|
|
98
86
|
innerDeco,
|
|
99
87
|
node,
|
|
100
88
|
outerDeco,
|
|
101
|
-
getPos
|
|
102
|
-
getPosFunc
|
|
89
|
+
getPos
|
|
103
90
|
]);
|
|
104
|
-
const { childDescriptors, nodeViewDescRef, setStopEvent, setSelectNode, setIgnoreMutation } = useNodeViewDescriptor(node,
|
|
91
|
+
const { childDescriptors, nodeViewDescRef, setStopEvent, setSelectNode, setIgnoreMutation } = useNodeViewDescriptor(node, getPos, domRef, nodeDomRef, innerDeco, outerDeco, contentDomRef);
|
|
105
92
|
const childContextValue = useMemo(()=>({
|
|
106
93
|
parentRef: nodeViewDescRef,
|
|
107
94
|
siblingsRef: childDescriptors
|
|
@@ -116,10 +103,7 @@ export const CustomNodeView = /*#__PURE__*/ memo(function CustomNodeView(param)
|
|
|
116
103
|
// results are stored in a ref but not actually appended
|
|
117
104
|
// to the DOM until a client effect
|
|
118
105
|
if (!customNodeViewRef.current) {
|
|
119
|
-
customNodeViewRef.current = customNodeView(nodeRef.current,
|
|
120
|
-
// this line if customNodeView is set
|
|
121
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
122
|
-
view, ()=>getPos.current(), outerDecoRef.current, innerDecoRef.current);
|
|
106
|
+
customNodeViewRef.current = customNodeView(nodeRef.current, view, getPos, outerDecoRef.current, innerDecoRef.current);
|
|
123
107
|
if (customNodeViewRef.current.stopEvent) {
|
|
124
108
|
setStopEvent(customNodeViewRef.current.stopEvent.bind(customNodeViewRef.current));
|
|
125
109
|
}
|
|
@@ -4,18 +4,16 @@
|
|
|
4
4
|
import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
|
|
5
5
|
import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js";
|
|
6
6
|
import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
};
|
|
7
|
+
function getPos() {
|
|
8
|
+
return -1;
|
|
9
|
+
}
|
|
12
10
|
export const DocNodeView = /*#__PURE__*/ memo(/*#__PURE__*/ forwardRef(function DocNodeView(param, ref) {
|
|
13
|
-
let { className, node, innerDeco, outerDeco, as,
|
|
11
|
+
let { className, node, innerDeco, outerDeco, as, ...elementProps } = param;
|
|
14
12
|
const innerRef = useRef(null);
|
|
15
13
|
useImperativeHandle(ref, ()=>{
|
|
16
14
|
return innerRef.current;
|
|
17
15
|
}, []);
|
|
18
|
-
const { childDescriptors, nodeViewDescRef } = useNodeViewDescriptor(node,
|
|
16
|
+
const { childDescriptors, nodeViewDescRef } = useNodeViewDescriptor(node, getPos, innerRef, innerRef, innerDeco, outerDeco, innerRef);
|
|
19
17
|
const childContextValue = useMemo(()=>({
|
|
20
18
|
parentRef: nodeViewDescRef,
|
|
21
19
|
siblingsRef: childDescriptors
|
|
@@ -42,12 +40,5 @@ export const DocNodeView = /*#__PURE__*/ memo(/*#__PURE__*/ forwardRef(function
|
|
|
42
40
|
node: node,
|
|
43
41
|
innerDecorations: innerDeco
|
|
44
42
|
})));
|
|
45
|
-
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
-
const nodeDecorations = outerDeco.filter((deco)=>!deco.inline);
|
|
48
|
-
if (!nodeDecorations.length) {
|
|
49
|
-
return element;
|
|
50
|
-
}
|
|
51
|
-
const wrapped = nodeDecorations.reduce(wrapInDeco, element);
|
|
52
|
-
return wrapped;
|
|
43
|
+
return outerDeco.reduce(wrapInDeco, element);
|
|
53
44
|
}));
|