@handlewithcare/react-prosemirror 2.0.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/LICENSE.txt +12 -0
- package/README.md +705 -0
- package/dist/cjs/browser.js +53 -0
- package/dist/cjs/components/ChildNodeViews.js +376 -0
- package/dist/cjs/components/CursorWrapper.js +91 -0
- package/dist/cjs/components/CustomNodeView.js +79 -0
- package/dist/cjs/components/DocNodeView.js +104 -0
- package/dist/cjs/components/LayoutGroup.js +111 -0
- package/dist/cjs/components/MarkView.js +115 -0
- package/dist/cjs/components/NativeWidgetView.js +109 -0
- package/dist/cjs/components/NodeView.js +196 -0
- package/dist/cjs/components/NodeViewComponentProps.js +4 -0
- package/dist/cjs/components/OutputSpec.js +88 -0
- package/dist/cjs/components/ProseMirror.js +103 -0
- package/dist/cjs/components/ProseMirrorDoc.js +92 -0
- package/dist/cjs/components/SeparatorHackView.js +100 -0
- package/dist/cjs/components/TextNodeView.js +112 -0
- package/dist/cjs/components/TrailingHackView.js +90 -0
- package/dist/cjs/components/WidgetView.js +95 -0
- package/dist/cjs/components/WidgetViewComponentProps.js +4 -0
- package/dist/cjs/components/__tests__/ProseMirror.composition.test.js +398 -0
- package/dist/cjs/components/__tests__/ProseMirror.domchange.test.js +270 -0
- package/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js +1010 -0
- package/dist/cjs/components/__tests__/ProseMirror.draw.test.js +337 -0
- package/dist/cjs/components/__tests__/ProseMirror.node-view.test.js +315 -0
- package/dist/cjs/components/__tests__/ProseMirror.selection.test.js +444 -0
- package/dist/cjs/components/__tests__/ProseMirror.test.js +382 -0
- package/dist/cjs/contexts/ChildDescriptorsContext.js +19 -0
- package/dist/cjs/contexts/EditorContext.js +12 -0
- package/dist/cjs/contexts/EditorStateContext.js +12 -0
- package/dist/cjs/contexts/LayoutGroupContext.js +12 -0
- package/dist/cjs/contexts/NodeViewContext.js +12 -0
- package/dist/cjs/contexts/SelectNodeContext.js +12 -0
- package/dist/cjs/contexts/StopEventContext.js +12 -0
- package/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js +141 -0
- package/dist/cjs/decorations/ReactWidgetType.js +58 -0
- package/dist/cjs/decorations/computeDocDeco.js +44 -0
- package/dist/cjs/decorations/internalTypes.js +4 -0
- package/dist/cjs/decorations/iterDeco.js +79 -0
- package/dist/cjs/decorations/viewDecorations.js +163 -0
- package/dist/cjs/dom.js +142 -0
- package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +108 -0
- package/dist/cjs/hooks/useClientOnly.js +18 -0
- package/dist/cjs/hooks/useComponentEventListeners.js +39 -0
- package/dist/cjs/hooks/useEditor.js +287 -0
- package/dist/cjs/hooks/useEditorEffect.js +35 -0
- package/dist/cjs/hooks/useEditorEventCallback.js +33 -0
- package/dist/cjs/hooks/useEditorEventListener.js +34 -0
- package/dist/cjs/hooks/useEditorState.js +16 -0
- package/dist/cjs/hooks/useForceUpdate.js +15 -0
- package/dist/cjs/hooks/useLayoutGroupEffect.js +19 -0
- package/dist/cjs/hooks/useNodeViewDescriptor.js +115 -0
- package/dist/cjs/hooks/useReactKeys.js +17 -0
- package/dist/cjs/hooks/useSelectNode.js +28 -0
- package/dist/cjs/hooks/useStopEvent.js +24 -0
- package/dist/cjs/index.js +53 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/plugins/__tests__/reactKeys.test.js +81 -0
- package/dist/cjs/plugins/beforeInputPlugin.js +143 -0
- package/dist/cjs/plugins/componentEventListeners.js +35 -0
- package/dist/cjs/plugins/componentEventListenersPlugin.js +35 -0
- package/dist/cjs/plugins/reactKeys.js +96 -0
- package/dist/cjs/props.js +269 -0
- package/dist/cjs/selection/SelectionDOMObserver.js +174 -0
- package/dist/cjs/selection/hasFocusAndSelection.js +35 -0
- package/dist/cjs/selection/selectionFromDOM.js +77 -0
- package/dist/cjs/selection/selectionToDOM.js +226 -0
- package/dist/cjs/ssr.js +85 -0
- package/dist/cjs/testing/editorViewTestHelpers.js +111 -0
- package/dist/cjs/testing/setupProseMirrorView.js +94 -0
- package/dist/cjs/viewdesc.js +664 -0
- package/dist/esm/browser.js +43 -0
- package/dist/esm/components/ChildNodeViews.js +318 -0
- package/dist/esm/components/CursorWrapper.js +40 -0
- package/dist/esm/components/CustomNodeView.js +28 -0
- package/dist/esm/components/DocNodeView.js +53 -0
- package/dist/esm/components/LayoutGroup.js +66 -0
- package/dist/esm/components/MarkView.js +64 -0
- package/dist/esm/components/NativeWidgetView.js +58 -0
- package/dist/esm/components/NodeView.js +145 -0
- package/dist/esm/components/NodeViewComponentProps.js +1 -0
- package/dist/esm/components/OutputSpec.js +38 -0
- package/dist/esm/components/ProseMirror.js +52 -0
- package/dist/esm/components/ProseMirrorDoc.js +34 -0
- package/dist/esm/components/SeparatorHackView.js +49 -0
- package/dist/esm/components/TextNodeView.js +102 -0
- package/dist/esm/components/TrailingHackView.js +39 -0
- package/dist/esm/components/WidgetView.js +44 -0
- package/dist/esm/components/WidgetViewComponentProps.js +1 -0
- package/dist/esm/components/__tests__/ProseMirror.composition.test.js +395 -0
- package/dist/esm/components/__tests__/ProseMirror.domchange.test.js +266 -0
- package/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js +967 -0
- package/dist/esm/components/__tests__/ProseMirror.draw.test.js +294 -0
- package/dist/esm/components/__tests__/ProseMirror.node-view.test.js +272 -0
- package/dist/esm/components/__tests__/ProseMirror.selection.test.js +440 -0
- package/dist/esm/components/__tests__/ProseMirror.test.js +339 -0
- package/dist/esm/contexts/ChildDescriptorsContext.js +9 -0
- package/dist/esm/contexts/EditorContext.js +7 -0
- package/dist/esm/contexts/EditorStateContext.js +2 -0
- package/dist/esm/contexts/LayoutGroupContext.js +2 -0
- package/dist/esm/contexts/NodeViewContext.js +2 -0
- package/dist/esm/contexts/SelectNodeContext.js +2 -0
- package/dist/esm/contexts/StopEventContext.js +2 -0
- package/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js +98 -0
- package/dist/esm/decorations/ReactWidgetType.js +40 -0
- package/dist/esm/decorations/computeDocDeco.js +44 -0
- package/dist/esm/decorations/internalTypes.js +1 -0
- package/dist/esm/decorations/iterDeco.js +73 -0
- package/dist/esm/decorations/viewDecorations.js +163 -0
- package/dist/esm/dom.js +105 -0
- package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +99 -0
- package/dist/esm/hooks/useClientOnly.js +8 -0
- package/dist/esm/hooks/useComponentEventListeners.js +54 -0
- package/dist/esm/hooks/useEditor.js +278 -0
- package/dist/esm/hooks/useEditorEffect.js +38 -0
- package/dist/esm/hooks/useEditorEventCallback.js +35 -0
- package/dist/esm/hooks/useEditorEventListener.js +28 -0
- package/dist/esm/hooks/useEditorState.js +8 -0
- package/dist/esm/hooks/useForceUpdate.js +8 -0
- package/dist/esm/hooks/useLayoutGroupEffect.js +9 -0
- package/dist/esm/hooks/useNodeViewDescriptor.js +105 -0
- package/dist/esm/hooks/useReactKeys.js +7 -0
- package/dist/esm/hooks/useSelectNode.js +18 -0
- package/dist/esm/hooks/useStopEvent.js +14 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/plugins/__tests__/reactKeys.test.js +77 -0
- package/dist/esm/plugins/beforeInputPlugin.js +133 -0
- package/dist/esm/plugins/componentEventListeners.js +25 -0
- package/dist/esm/plugins/componentEventListenersPlugin.js +25 -0
- package/dist/esm/plugins/reactKeys.js +81 -0
- package/dist/esm/props.js +251 -0
- package/dist/esm/selection/SelectionDOMObserver.js +164 -0
- package/dist/esm/selection/hasFocusAndSelection.js +17 -0
- package/dist/esm/selection/selectionFromDOM.js +59 -0
- package/dist/esm/selection/selectionToDOM.js +196 -0
- package/dist/esm/ssr.js +82 -0
- package/dist/esm/testing/editorViewTestHelpers.js +88 -0
- package/dist/esm/testing/setupProseMirrorView.js +76 -0
- package/dist/esm/viewdesc.js +654 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/browser.d.ts +15 -0
- package/dist/types/components/ChildNodeViews.d.ts +9 -0
- package/dist/types/components/CursorWrapper.d.ts +5 -0
- package/dist/types/components/CustomNodeView.d.ts +21 -0
- package/dist/types/components/DocNodeView.d.ts +20 -0
- package/dist/types/components/LayoutGroup.d.ts +12 -0
- package/dist/types/components/MarkView.d.ts +9 -0
- package/dist/types/components/NativeWidgetView.d.ts +8 -0
- package/dist/types/components/NodeView.d.ts +11 -0
- package/dist/types/components/NodeViewComponentProps.d.ts +12 -0
- package/dist/types/components/OutputSpec.d.ts +8 -0
- package/dist/types/components/ProseMirror.d.ts +15 -0
- package/dist/types/components/ProseMirrorDoc.d.ts +10 -0
- package/dist/types/components/SeparatorHackView.d.ts +6 -0
- package/dist/types/components/TextNodeView.d.ts +23 -0
- package/dist/types/components/TrailingHackView.d.ts +6 -0
- package/dist/types/components/WidgetView.d.ts +8 -0
- package/dist/types/components/WidgetViewComponentProps.d.ts +6 -0
- package/dist/types/components/__tests__/ProseMirror.composition.test.d.ts +1 -0
- package/dist/types/components/__tests__/ProseMirror.domchange.test.d.ts +1 -0
- package/dist/types/components/__tests__/ProseMirror.draw-decoration.test.d.ts +1 -0
- package/dist/types/components/__tests__/ProseMirror.draw.test.d.ts +1 -0
- package/dist/types/components/__tests__/ProseMirror.node-view.test.d.ts +1 -0
- package/dist/types/components/__tests__/ProseMirror.selection.test.d.ts +1 -0
- package/dist/types/components/__tests__/ProseMirror.test.d.ts +1 -0
- package/dist/types/contexts/ChildDescriptorsContext.d.ts +6 -0
- package/dist/types/contexts/EditorContext.d.ts +14 -0
- package/dist/types/contexts/EditorStateContext.d.ts +2 -0
- package/dist/types/contexts/LayoutGroupContext.d.ts +5 -0
- package/dist/types/contexts/NodeViewContext.d.ts +6 -0
- package/dist/types/contexts/SelectNodeContext.d.ts +3 -0
- package/dist/types/contexts/StopEventContext.d.ts +3 -0
- package/dist/types/contexts/__tests__/DeferredLayoutEffects.test.d.ts +1 -0
- package/dist/types/decorations/ReactWidgetType.d.ts +39 -0
- package/dist/types/decorations/computeDocDeco.d.ts +13 -0
- package/dist/types/decorations/internalTypes.d.ts +16 -0
- package/dist/types/decorations/iterDeco.d.ts +3 -0
- package/dist/types/decorations/viewDecorations.d.ts +13 -0
- package/dist/types/dom.d.ts +22 -0
- package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +1 -0
- package/dist/types/hooks/useClientOnly.d.ts +1 -0
- package/dist/types/hooks/useComponentEventListeners.d.ts +33 -0
- package/dist/types/hooks/useEditor.d.ts +66 -0
- package/dist/types/hooks/useEditorEffect.d.ts +17 -0
- package/dist/types/hooks/useEditorEventCallback.d.ts +15 -0
- package/dist/types/hooks/useEditorEventListener.d.ts +8 -0
- package/dist/types/hooks/useEditorState.d.ts +5 -0
- package/dist/types/hooks/useForceUpdate.d.ts +5 -0
- package/dist/types/hooks/useLayoutGroupEffect.d.ts +3 -0
- package/dist/types/hooks/useNodeViewDescriptor.d.ts +11 -0
- package/dist/types/hooks/useReactKeys.d.ts +5 -0
- package/dist/types/hooks/useSelectNode.d.ts +1 -0
- package/dist/types/hooks/useStopEvent.d.ts +2 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/plugins/__tests__/reactKeys.test.d.ts +1 -0
- package/dist/types/plugins/beforeInputPlugin.d.ts +3 -0
- package/dist/types/plugins/componentEventListeners.d.ts +4 -0
- package/dist/types/plugins/componentEventListenersPlugin.d.ts +4 -0
- package/dist/types/plugins/reactKeys.d.ts +19 -0
- package/dist/types/props.d.ts +1174 -0
- package/dist/types/selection/SelectionDOMObserver.d.ts +34 -0
- package/dist/types/selection/hasFocusAndSelection.d.ts +3 -0
- package/dist/types/selection/selectionFromDOM.d.ts +4 -0
- package/dist/types/selection/selectionToDOM.d.ts +9 -0
- package/dist/types/ssr.d.ts +19 -0
- package/dist/types/testing/editorViewTestHelpers.d.ts +23 -0
- package/dist/types/testing/setupProseMirrorView.d.ts +2 -0
- package/dist/types/viewdesc.d.ts +131 -0
- package/package.json +113 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "computeDocDeco", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return computeDocDeco;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _prosemirrorview = require("prosemirror-view");
|
|
12
|
+
const DocDecorationsCache = new WeakMap();
|
|
13
|
+
function computeDocDeco(view) {
|
|
14
|
+
const attrs = Object.create(null);
|
|
15
|
+
attrs.class = "ProseMirror";
|
|
16
|
+
attrs.contenteditable = String(view.editable);
|
|
17
|
+
view.someProp("attributes", (value)=>{
|
|
18
|
+
if (typeof value == "function") value = value(view.state);
|
|
19
|
+
if (value) for(const attr in value){
|
|
20
|
+
if (attr == "class") attrs.class += " " + value[attr];
|
|
21
|
+
else if (attr == "style") attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr];
|
|
22
|
+
else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") attrs[attr] = String(value[attr]);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
if (!attrs.translate) attrs.translate = "no";
|
|
26
|
+
const next = [
|
|
27
|
+
_prosemirrorview.Decoration.node(0, view.state.doc.content.size, attrs)
|
|
28
|
+
];
|
|
29
|
+
const previous = DocDecorationsCache.get(view);
|
|
30
|
+
if (!previous) {
|
|
31
|
+
DocDecorationsCache.set(view, next);
|
|
32
|
+
return next;
|
|
33
|
+
}
|
|
34
|
+
if (previous[0].to !== view.state.doc.content.size) {
|
|
35
|
+
DocDecorationsCache.set(view, next);
|
|
36
|
+
return next;
|
|
37
|
+
}
|
|
38
|
+
// @ts-expect-error Internal property (Decoration.type)
|
|
39
|
+
if (!previous[0].type.eq(next[0].type)) {
|
|
40
|
+
DocDecorationsCache.set(view, next);
|
|
41
|
+
return next;
|
|
42
|
+
}
|
|
43
|
+
return previous;
|
|
44
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "iterDeco", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return iterDeco;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _ReactWidgetType = require("./ReactWidgetType.js");
|
|
12
|
+
function compareSide(a, b) {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
return a.type.side - b.type.side;
|
|
15
|
+
}
|
|
16
|
+
function iterDeco(parent, deco, // Callbacks have been slightly modified to pass
|
|
17
|
+
// the offset, so that we can pass the position as
|
|
18
|
+
// a prop to components
|
|
19
|
+
onWidget, onNode) {
|
|
20
|
+
const locals = deco.locals(parent);
|
|
21
|
+
let offset = 0;
|
|
22
|
+
// Simple, cheap variant for when there are no local decorations
|
|
23
|
+
if (locals.length == 0) {
|
|
24
|
+
for(let i = 0; i < parent.childCount; i++){
|
|
25
|
+
const child = parent.child(i);
|
|
26
|
+
onNode(child, locals, deco.forChild(offset, child), offset, i);
|
|
27
|
+
offset += child.nodeSize;
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let decoIndex = 0;
|
|
32
|
+
const active = [];
|
|
33
|
+
let restNode = null;
|
|
34
|
+
for(let parentIndex = 0;;){
|
|
35
|
+
if (decoIndex < locals.length && locals[decoIndex].to == offset) {
|
|
36
|
+
const widget = locals[decoIndex++];
|
|
37
|
+
let widgets;
|
|
38
|
+
while(decoIndex < locals.length && locals[decoIndex].to == offset)(widgets || (widgets = [
|
|
39
|
+
widget
|
|
40
|
+
])).push(locals[decoIndex++]);
|
|
41
|
+
if (widgets) {
|
|
42
|
+
widgets.sort(compareSide);
|
|
43
|
+
for(let i = 0; i < widgets.length; i++)onWidget(widgets[i], // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
!(widgets[i].type instanceof _ReactWidgetType.ReactWidgetType), offset, parentIndex + i, !!restNode);
|
|
45
|
+
} else {
|
|
46
|
+
onWidget(widget, // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
+
!(widget.type instanceof _ReactWidgetType.ReactWidgetType), offset, parentIndex, !!restNode);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
let child, index;
|
|
51
|
+
if (restNode) {
|
|
52
|
+
index = -1;
|
|
53
|
+
child = restNode;
|
|
54
|
+
restNode = null;
|
|
55
|
+
} else if (parentIndex < parent.childCount) {
|
|
56
|
+
index = parentIndex;
|
|
57
|
+
child = parent.child(parentIndex++);
|
|
58
|
+
} else {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
for(let i = 0; i < active.length; i++)if (active[i].to <= offset) active.splice(i--, 1);
|
|
62
|
+
while(decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset)active.push(locals[decoIndex++]);
|
|
63
|
+
let end = offset + child.nodeSize;
|
|
64
|
+
if (child.isText) {
|
|
65
|
+
let cutAt = end;
|
|
66
|
+
if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from;
|
|
67
|
+
for(let i = 0; i < active.length; i++)if (active[i].to < cutAt) cutAt = active[i].to;
|
|
68
|
+
if (cutAt < end) {
|
|
69
|
+
restNode = child.cut(cutAt - offset);
|
|
70
|
+
child = child.cut(0, cutAt - offset);
|
|
71
|
+
end = cutAt;
|
|
72
|
+
index = -1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const outerDeco = child.isInline && !child.isLeaf ? active.filter((d)=>!d.inline) : active.slice();
|
|
76
|
+
onNode(child, outerDeco, deco.forChild(offset, child), offset, index);
|
|
77
|
+
offset = end;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "viewDecorations", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return viewDecorations;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _prosemirrorview = require("prosemirror-view");
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
const none = [], noSpec = {};
|
|
14
|
+
const empty = _prosemirrorview.DecorationSet.empty;
|
|
15
|
+
// An abstraction that allows the code dealing with decorations to
|
|
16
|
+
// treat multiple DecorationSet objects as if it were a single object
|
|
17
|
+
// with (a subset of) the same interface.
|
|
18
|
+
let DecorationGroup = class DecorationGroup {
|
|
19
|
+
members;
|
|
20
|
+
constructor(members){
|
|
21
|
+
this.members = members;
|
|
22
|
+
}
|
|
23
|
+
map(mapping, doc) {
|
|
24
|
+
const mappedDecos = this.members.map((member)=>member.map(mapping, doc, noSpec));
|
|
25
|
+
return DecorationGroup.from(mappedDecos);
|
|
26
|
+
}
|
|
27
|
+
forChild(offset, child) {
|
|
28
|
+
if (child.isLeaf) return _prosemirrorview.DecorationSet.empty;
|
|
29
|
+
let found = [];
|
|
30
|
+
for(let i = 0; i < this.members.length; i++){
|
|
31
|
+
const result = this.members[i].forChild(offset, child);
|
|
32
|
+
if (result == empty) continue;
|
|
33
|
+
if (result instanceof DecorationGroup) found = found.concat(result.members);
|
|
34
|
+
else found.push(result);
|
|
35
|
+
}
|
|
36
|
+
return DecorationGroup.from(found);
|
|
37
|
+
}
|
|
38
|
+
eq(other) {
|
|
39
|
+
if (!(other instanceof DecorationGroup) || other.members.length != this.members.length) return false;
|
|
40
|
+
for(let i = 0; i < this.members.length; i++)if (!this.members[i].eq(other.members[i])) return false;
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
locals(node) {
|
|
44
|
+
let result, sorted = true;
|
|
45
|
+
for(let i = 0; i < this.members.length; i++){
|
|
46
|
+
const locals = this.members[i].localsInner(node);
|
|
47
|
+
if (!locals.length) continue;
|
|
48
|
+
if (!result) {
|
|
49
|
+
result = locals;
|
|
50
|
+
} else {
|
|
51
|
+
if (sorted) {
|
|
52
|
+
result = result.slice();
|
|
53
|
+
sorted = false;
|
|
54
|
+
}
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
56
|
+
for(let j = 0; j < locals.length; j++)result.push(locals[j]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none;
|
|
60
|
+
}
|
|
61
|
+
// Create a group for the given array of decoration sets, or return
|
|
62
|
+
// a single set when possible.
|
|
63
|
+
static from(members) {
|
|
64
|
+
switch(members.length){
|
|
65
|
+
case 0:
|
|
66
|
+
return empty;
|
|
67
|
+
case 1:
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
69
|
+
return members[0];
|
|
70
|
+
default:
|
|
71
|
+
return new DecorationGroup(members.every((m)=>m instanceof _prosemirrorview.DecorationSet) ? members : members.reduce((r, m)=>r.concat(m instanceof _prosemirrorview.DecorationSet ? m : m.members), []));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
forEachSet(f) {
|
|
75
|
+
for(let i = 0; i < this.members.length; i++)// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
76
|
+
this.members[i].forEachSet(f);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
// Used to sort decorations so that ones with a low start position
|
|
80
|
+
// come first, and within a set with the same start position, those
|
|
81
|
+
// with an smaller end position come first.
|
|
82
|
+
function byPos(a, b) {
|
|
83
|
+
return a.from - b.from || a.to - b.to;
|
|
84
|
+
}
|
|
85
|
+
// Scan a sorted array of decorations for partially overlapping spans,
|
|
86
|
+
// and split those so that only fully overlapping spans are left (to
|
|
87
|
+
// make subsequent rendering easier). Will return the input array if
|
|
88
|
+
// no partially overlapping spans are found (the common case).
|
|
89
|
+
function removeOverlap(spans) {
|
|
90
|
+
let working = spans;
|
|
91
|
+
for(let i = 0; i < working.length - 1; i++){
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
93
|
+
const span = working[i];
|
|
94
|
+
if (span.from != span.to) for(let j = i + 1; j < working.length; j++){
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
96
|
+
const next = working[j];
|
|
97
|
+
if (next.from == span.from) {
|
|
98
|
+
if (next.to != span.to) {
|
|
99
|
+
if (working == spans) working = spans.slice();
|
|
100
|
+
// Followed by a partially overlapping larger span. Split that
|
|
101
|
+
// span.
|
|
102
|
+
working[j] = next.copy(next.from, span.to);
|
|
103
|
+
insertAhead(working, j + 1, next.copy(span.to, next.to));
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
106
|
+
} else {
|
|
107
|
+
if (next.from < span.to) {
|
|
108
|
+
if (working == spans) working = spans.slice();
|
|
109
|
+
// The end of this one overlaps with a subsequent span. Split
|
|
110
|
+
// this one.
|
|
111
|
+
working[i] = span.copy(span.from, next.from);
|
|
112
|
+
insertAhead(working, j, span.copy(next.from, span.to));
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return working;
|
|
119
|
+
}
|
|
120
|
+
function insertAhead(array, i, deco) {
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
122
|
+
while(i < array.length && byPos(deco, array[i]) > 0)i++;
|
|
123
|
+
array.splice(i, 0, deco);
|
|
124
|
+
}
|
|
125
|
+
const ViewDecorationsCache = new WeakMap();
|
|
126
|
+
function viewDecorations(view, cursorWrapper) {
|
|
127
|
+
const found = [];
|
|
128
|
+
view.someProp("decorations", (f)=>{
|
|
129
|
+
const result = f(view.state);
|
|
130
|
+
if (result && result != empty) found.push(result);
|
|
131
|
+
});
|
|
132
|
+
// We don't have access to types for view.cursorWrapper here
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
if (cursorWrapper) {
|
|
135
|
+
found.push(// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
136
|
+
_prosemirrorview.DecorationSet.create(view.state.doc, [
|
|
137
|
+
cursorWrapper
|
|
138
|
+
]));
|
|
139
|
+
}
|
|
140
|
+
const previous = ViewDecorationsCache.get(view);
|
|
141
|
+
if (!previous) {
|
|
142
|
+
const result = DecorationGroup.from(found);
|
|
143
|
+
ViewDecorationsCache.set(view, result);
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
let numPrevious = 0;
|
|
147
|
+
let areSetsEqual = true;
|
|
148
|
+
previous.forEachSet((set)=>{
|
|
149
|
+
const next = found[numPrevious++];
|
|
150
|
+
if (next !== set) {
|
|
151
|
+
areSetsEqual = false;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
if (numPrevious !== found.length) {
|
|
155
|
+
areSetsEqual = false;
|
|
156
|
+
}
|
|
157
|
+
if (!areSetsEqual) {
|
|
158
|
+
const result = DecorationGroup.from(found);
|
|
159
|
+
ViewDecorationsCache.set(view, result);
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
return previous;
|
|
163
|
+
}
|
package/dist/cjs/dom.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ "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
|
+
caretFromPoint: function() {
|
|
13
|
+
return caretFromPoint;
|
|
14
|
+
},
|
|
15
|
+
deepActiveElement: function() {
|
|
16
|
+
return deepActiveElement;
|
|
17
|
+
},
|
|
18
|
+
domIndex: function() {
|
|
19
|
+
return domIndex;
|
|
20
|
+
},
|
|
21
|
+
hasBlockDesc: function() {
|
|
22
|
+
return hasBlockDesc;
|
|
23
|
+
},
|
|
24
|
+
isEquivalentPosition: function() {
|
|
25
|
+
return isEquivalentPosition;
|
|
26
|
+
},
|
|
27
|
+
isOnEdge: function() {
|
|
28
|
+
return isOnEdge;
|
|
29
|
+
},
|
|
30
|
+
keyEvent: function() {
|
|
31
|
+
return keyEvent;
|
|
32
|
+
},
|
|
33
|
+
nodeSize: function() {
|
|
34
|
+
return nodeSize;
|
|
35
|
+
},
|
|
36
|
+
parentNode: function() {
|
|
37
|
+
return parentNode;
|
|
38
|
+
},
|
|
39
|
+
selectionCollapsed: function() {
|
|
40
|
+
return selectionCollapsed;
|
|
41
|
+
},
|
|
42
|
+
textRange: function() {
|
|
43
|
+
return textRange;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const domIndex = function(node) {
|
|
47
|
+
for(let index = 0;; index++){
|
|
48
|
+
node = node.previousSibling;
|
|
49
|
+
if (!node) return index;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const parentNode = function(node) {
|
|
53
|
+
const parent = node.assignedSlot || node.parentNode;
|
|
54
|
+
return parent && parent.nodeType == 11 ? parent.host : parent;
|
|
55
|
+
};
|
|
56
|
+
let reusedRange = null;
|
|
57
|
+
const textRange = function(node, from, to) {
|
|
58
|
+
const range = reusedRange || (reusedRange = document.createRange());
|
|
59
|
+
range.setEnd(node, to == null ? node.nodeValue.length : to);
|
|
60
|
+
range.setStart(node, from || 0);
|
|
61
|
+
return range;
|
|
62
|
+
};
|
|
63
|
+
const isEquivalentPosition = function(node, off, targetNode, targetOff) {
|
|
64
|
+
return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1));
|
|
65
|
+
};
|
|
66
|
+
const atomElements = /^(img|br|input|textarea|hr)$/i;
|
|
67
|
+
function scanFor(node, off, targetNode, targetOff, dir) {
|
|
68
|
+
for(;;){
|
|
69
|
+
if (node == targetNode && off == targetOff) return true;
|
|
70
|
+
if (off == (dir < 0 ? 0 : nodeSize(node))) {
|
|
71
|
+
const parent = node.parentNode;
|
|
72
|
+
if (!parent || parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") return false;
|
|
73
|
+
off = domIndex(node) + (dir < 0 ? 0 : 1);
|
|
74
|
+
node = parent;
|
|
75
|
+
} else if (node.nodeType == 1) {
|
|
76
|
+
node = node.childNodes[off + (dir < 0 ? -1 : 0)];
|
|
77
|
+
if (node.contentEditable == "false") return false;
|
|
78
|
+
off = dir < 0 ? nodeSize(node) : 0;
|
|
79
|
+
} else {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function nodeSize(node) {
|
|
85
|
+
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
86
|
+
}
|
|
87
|
+
function isOnEdge(node, offset, parent) {
|
|
88
|
+
for(let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;){
|
|
89
|
+
if (node == parent) return true;
|
|
90
|
+
const index = domIndex(node);
|
|
91
|
+
node = node.parentNode;
|
|
92
|
+
if (!node) return false;
|
|
93
|
+
atStart = atStart && index == 0;
|
|
94
|
+
atEnd = atEnd && index == nodeSize(node);
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
function hasBlockDesc(dom) {
|
|
99
|
+
let desc;
|
|
100
|
+
for(let cur = dom; cur; cur = cur.parentNode)if (desc = cur.pmViewDesc) break;
|
|
101
|
+
return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom);
|
|
102
|
+
}
|
|
103
|
+
const selectionCollapsed = function(domSel) {
|
|
104
|
+
return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset);
|
|
105
|
+
};
|
|
106
|
+
function keyEvent(keyCode, key) {
|
|
107
|
+
const event = document.createEvent("Event");
|
|
108
|
+
event.initEvent("keydown", true, true);
|
|
109
|
+
event.keyCode = keyCode;
|
|
110
|
+
event.key = event.code = key;
|
|
111
|
+
return event;
|
|
112
|
+
}
|
|
113
|
+
function deepActiveElement(doc) {
|
|
114
|
+
let elt = doc.activeElement;
|
|
115
|
+
while(elt && elt.shadowRoot)elt = elt.shadowRoot.activeElement;
|
|
116
|
+
return elt;
|
|
117
|
+
}
|
|
118
|
+
function caretFromPoint(doc, x, y) {
|
|
119
|
+
if (doc.caretPositionFromPoint) {
|
|
120
|
+
try {
|
|
121
|
+
// Firefox throws for this call in hard-to-predict circumstances (#994)
|
|
122
|
+
const pos = doc.caretPositionFromPoint(x, y);
|
|
123
|
+
// Clip the offset, because Chrome will return a text offset
|
|
124
|
+
// into <input> nodes, which can't be treated as a regular DOM
|
|
125
|
+
// offset
|
|
126
|
+
if (pos) return {
|
|
127
|
+
node: pos.offsetNode,
|
|
128
|
+
offset: Math.min(nodeSize(pos.offsetNode), pos.offset)
|
|
129
|
+
};
|
|
130
|
+
} catch (_) {
|
|
131
|
+
// pass
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (doc.caretRangeFromPoint) {
|
|
135
|
+
const range = doc.caretRangeFromPoint(x, y);
|
|
136
|
+
if (range) return {
|
|
137
|
+
node: range.startContainer,
|
|
138
|
+
offset: Math.min(nodeSize(range.startContainer), range.startOffset)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */ "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _react = require("@testing-library/react");
|
|
6
|
+
const _react1 = /*#__PURE__*/ _interopRequireDefault(require("react"));
|
|
7
|
+
const _layoutGroupJs = require("../../components/LayoutGroup.js");
|
|
8
|
+
const _editorContextJs = require("../../contexts/EditorContext.js");
|
|
9
|
+
const _editorStateContextJs = require("../../contexts/EditorStateContext.js");
|
|
10
|
+
const _useEditorEffectJs = require("../useEditorEffect.js");
|
|
11
|
+
function _interopRequireDefault(obj) {
|
|
12
|
+
return obj && obj.__esModule ? obj : {
|
|
13
|
+
default: obj
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function TestComponent(param) {
|
|
17
|
+
let { effect , dependencies =[] } = param;
|
|
18
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
19
|
+
(0, _useEditorEffectJs.useEditorEffect)(effect, dependencies);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
describe("useEditorViewLayoutEffect", ()=>{
|
|
23
|
+
it("should run the effect", ()=>{
|
|
24
|
+
const effect = jest.fn();
|
|
25
|
+
const editorView = {};
|
|
26
|
+
const editorState = {};
|
|
27
|
+
const registerEventListener = ()=>{};
|
|
28
|
+
const unregisterEventListener = ()=>{};
|
|
29
|
+
(0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, {
|
|
30
|
+
value: {
|
|
31
|
+
view: editorView,
|
|
32
|
+
registerEventListener,
|
|
33
|
+
unregisterEventListener
|
|
34
|
+
}
|
|
35
|
+
}, /*#__PURE__*/ _react1.default.createElement(_editorStateContextJs.EditorStateContext.Provider, {
|
|
36
|
+
value: editorState
|
|
37
|
+
}, /*#__PURE__*/ _react1.default.createElement(TestComponent, {
|
|
38
|
+
effect: effect
|
|
39
|
+
})))));
|
|
40
|
+
expect(effect).toHaveBeenCalled();
|
|
41
|
+
expect(effect).toHaveBeenCalledWith(editorView);
|
|
42
|
+
});
|
|
43
|
+
it("should not re-run the effect if no dependencies change", ()=>{
|
|
44
|
+
const effect = jest.fn();
|
|
45
|
+
const editorView = {};
|
|
46
|
+
const editorState = {};
|
|
47
|
+
const registerEventListener = ()=>{};
|
|
48
|
+
const unregisterEventListener = ()=>{};
|
|
49
|
+
const contextValue = {
|
|
50
|
+
view: editorView,
|
|
51
|
+
registerEventListener,
|
|
52
|
+
unregisterEventListener
|
|
53
|
+
};
|
|
54
|
+
const { rerender } = (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, {
|
|
55
|
+
value: contextValue
|
|
56
|
+
}, /*#__PURE__*/ _react1.default.createElement(_editorStateContextJs.EditorStateContext.Provider, {
|
|
57
|
+
value: editorState
|
|
58
|
+
}, /*#__PURE__*/ _react1.default.createElement(TestComponent, {
|
|
59
|
+
effect: effect,
|
|
60
|
+
dependencies: []
|
|
61
|
+
})), " ")));
|
|
62
|
+
rerender(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, {
|
|
63
|
+
value: contextValue
|
|
64
|
+
}, /*#__PURE__*/ _react1.default.createElement(_editorStateContextJs.EditorStateContext.Provider, {
|
|
65
|
+
value: editorState
|
|
66
|
+
}, /*#__PURE__*/ _react1.default.createElement(TestComponent, {
|
|
67
|
+
effect: effect,
|
|
68
|
+
dependencies: []
|
|
69
|
+
})))));
|
|
70
|
+
expect(effect).toHaveBeenCalledTimes(1);
|
|
71
|
+
});
|
|
72
|
+
it("should re-run the effect if dependencies change", ()=>{
|
|
73
|
+
const effect = jest.fn();
|
|
74
|
+
const editorView = {};
|
|
75
|
+
const editorState = {};
|
|
76
|
+
const registerEventListener = ()=>{};
|
|
77
|
+
const unregisterEventListener = ()=>{};
|
|
78
|
+
const { rerender } = (0, _react.render)(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, {
|
|
79
|
+
value: {
|
|
80
|
+
view: editorView,
|
|
81
|
+
registerEventListener,
|
|
82
|
+
unregisterEventListener
|
|
83
|
+
}
|
|
84
|
+
}, /*#__PURE__*/ _react1.default.createElement(_editorStateContextJs.EditorStateContext.Provider, {
|
|
85
|
+
value: editorState
|
|
86
|
+
}, /*#__PURE__*/ _react1.default.createElement(TestComponent, {
|
|
87
|
+
effect: effect,
|
|
88
|
+
dependencies: [
|
|
89
|
+
"one"
|
|
90
|
+
]
|
|
91
|
+
})))));
|
|
92
|
+
rerender(/*#__PURE__*/ _react1.default.createElement(_layoutGroupJs.LayoutGroup, null, /*#__PURE__*/ _react1.default.createElement(_editorContextJs.EditorContext.Provider, {
|
|
93
|
+
value: {
|
|
94
|
+
view: editorView,
|
|
95
|
+
registerEventListener,
|
|
96
|
+
unregisterEventListener
|
|
97
|
+
}
|
|
98
|
+
}, /*#__PURE__*/ _react1.default.createElement(_editorStateContextJs.EditorStateContext.Provider, {
|
|
99
|
+
value: editorState
|
|
100
|
+
}, /*#__PURE__*/ _react1.default.createElement(TestComponent, {
|
|
101
|
+
effect: effect,
|
|
102
|
+
dependencies: [
|
|
103
|
+
"two"
|
|
104
|
+
]
|
|
105
|
+
})))));
|
|
106
|
+
expect(effect).toHaveBeenCalledTimes(2);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "useClientOnly", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return useClientOnly;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _react = require("react");
|
|
12
|
+
function useClientOnly() {
|
|
13
|
+
const [render, setRender] = (0, _react.useState)(false);
|
|
14
|
+
(0, _react.useEffect)(()=>{
|
|
15
|
+
setRender(true);
|
|
16
|
+
}, []);
|
|
17
|
+
return render;
|
|
18
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* Copyright (c) The New York Times Company */ "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "useComponentEventListeners", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return useComponentEventListeners;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _react = require("react");
|
|
12
|
+
const _componentEventListeners = require("../plugins/componentEventListeners.js");
|
|
13
|
+
function useComponentEventListeners() {
|
|
14
|
+
const [registry, setRegistry] = (0, _react.useState)(new Map());
|
|
15
|
+
const registerEventListener = (0, _react.useCallback)((eventType, handler)=>{
|
|
16
|
+
const handlers = registry.get(eventType) ?? [];
|
|
17
|
+
handlers.unshift(handler);
|
|
18
|
+
if (!registry.has(eventType)) {
|
|
19
|
+
registry.set(eventType, handlers);
|
|
20
|
+
setRegistry(new Map(registry));
|
|
21
|
+
}
|
|
22
|
+
}, [
|
|
23
|
+
registry
|
|
24
|
+
]);
|
|
25
|
+
const unregisterEventListener = (0, _react.useCallback)((eventType, handler)=>{
|
|
26
|
+
const handlers = registry.get(eventType);
|
|
27
|
+
handlers?.splice(handlers.indexOf(handler), 1);
|
|
28
|
+
}, [
|
|
29
|
+
registry
|
|
30
|
+
]);
|
|
31
|
+
const componentEventListenersPlugin = (0, _react.useMemo)(()=>(0, _componentEventListeners.componentEventListeners)(registry), [
|
|
32
|
+
registry
|
|
33
|
+
]);
|
|
34
|
+
return {
|
|
35
|
+
registerEventListener,
|
|
36
|
+
unregisterEventListener,
|
|
37
|
+
componentEventListenersPlugin
|
|
38
|
+
};
|
|
39
|
+
}
|