@handlewithcare/react-prosemirror 2.4.12 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +58 -29
- package/dist/cjs/components/CustomNodeView.js +77 -137
- package/dist/cjs/{hooks/useNodePos.js → components/DefaultNodeView.js} +24 -26
- package/dist/cjs/components/DocNodeView.js +33 -41
- package/dist/cjs/components/MarkView.js +1 -2
- package/dist/cjs/components/NativeWidgetView.js +2 -3
- package/dist/cjs/components/NodeView.js +31 -21
- package/dist/cjs/components/ProseMirror.js +25 -17
- package/dist/cjs/components/ProseMirrorDoc.js +7 -27
- package/dist/cjs/components/ReactNodeView.js +98 -61
- 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 +33 -229
- package/dist/cjs/hooks/useEditorEffect.js +2 -2
- package/dist/cjs/hooks/useEditorEventCallback.js +8 -5
- package/dist/cjs/hooks/useIgnoreMutation.js +1 -1
- package/dist/cjs/hooks/useNodeViewDescriptor.js +123 -80
- package/dist/cjs/hooks/useReactKeys.js +1 -1
- package/dist/cjs/hooks/useSelectNode.js +9 -7
- package/dist/cjs/hooks/useStopEvent.js +1 -1
- package/dist/cjs/plugins/beforeInputPlugin.js +12 -0
- package/dist/cjs/testing/editorViewTestHelpers.js +0 -2
- package/dist/cjs/viewdesc.js +104 -25
- 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 +59 -31
- package/dist/esm/components/CustomNodeView.js +78 -138
- package/dist/esm/components/DefaultNodeView.js +16 -0
- package/dist/esm/components/DocNodeView.js +33 -41
- package/dist/esm/components/MarkView.js +1 -2
- package/dist/esm/components/NativeWidgetView.js +2 -3
- package/dist/esm/components/NodeView.js +32 -22
- package/dist/esm/components/ProseMirror.js +25 -17
- package/dist/esm/components/ProseMirrorDoc.js +7 -28
- package/dist/esm/components/ReactNodeView.js +99 -62
- 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 +29 -218
- package/dist/esm/hooks/useEditorEffect.js +2 -2
- package/dist/esm/hooks/useEditorEventCallback.js +8 -5
- package/dist/esm/hooks/useIgnoreMutation.js +1 -1
- package/dist/esm/hooks/useNodeViewDescriptor.js +125 -82
- package/dist/esm/hooks/useReactKeys.js +1 -1
- package/dist/esm/hooks/useSelectNode.js +9 -7
- package/dist/esm/hooks/useStopEvent.js +1 -1
- package/dist/esm/plugins/beforeInputPlugin.js +12 -0
- package/dist/esm/testing/editorViewTestHelpers.js +0 -2
- package/dist/esm/viewdesc.js +94 -18
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/AbstractEditorView.d.ts +27 -0
- package/dist/types/ReactEditorView.d.ts +80 -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 +3 -3
- package/dist/types/components/DefaultNodeView.d.ts +3 -0
- package/dist/types/components/DocNodeView.d.ts +9 -17
- 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 +5 -5
- package/dist/types/components/NodeViewComponentProps.d.ts +3 -4
- package/dist/types/components/ProseMirrorDoc.d.ts +14 -8
- package/dist/types/components/ReactNodeView.d.ts +4 -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/contexts/IgnoreMutationContext.d.ts +2 -1
- package/dist/types/contexts/NodeViewContext.d.ts +3 -1
- package/dist/types/contexts/SelectNodeContext.d.ts +3 -1
- package/dist/types/contexts/StopEventContext.d.ts +2 -1
- 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 +18 -10
- package/dist/types/hooks/useReactKeys.d.ts +1 -1
- package/dist/types/hooks/useSelectNode.d.ts +2 -1
- package/dist/types/props.d.ts +3 -3
- package/dist/types/viewdesc.d.ts +29 -11
- package/package.json +7 -3
- 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/useClientOnly.js +0 -19
- package/dist/cjs/hooks/useEditorView.js +0 -100
- 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/useClientOnly.js +0 -9
- 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/useClientOnly.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
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { forwardRef, useMemo } from "react";
|
|
2
|
+
import { OutputSpec } from "./OutputSpec.js";
|
|
3
|
+
export const DefaultNodeView = /*#__PURE__*/ forwardRef(function DefaultNodeView(param, ref) {
|
|
4
|
+
let { nodeProps: { node }, children, ...props } = param;
|
|
5
|
+
const spec = useMemo(()=>node.type.spec.toDOM?.(node), [
|
|
6
|
+
node
|
|
7
|
+
]);
|
|
8
|
+
if (!spec) {
|
|
9
|
+
throw new Error(`Node spec for ${node.type.name} is missing toDOM`);
|
|
10
|
+
}
|
|
11
|
+
return /*#__PURE__*/ React.createElement(OutputSpec, {
|
|
12
|
+
...props,
|
|
13
|
+
outputSpec: spec,
|
|
14
|
+
ref: ref
|
|
15
|
+
}, children);
|
|
16
|
+
});
|
|
@@ -1,53 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
// this linting rule is only broken in this file
|
|
3
|
-
/* eslint-disable react/prop-types */ import React, { cloneElement, createElement, forwardRef, memo, useImperativeHandle, useMemo, useRef } from "react";
|
|
1
|
+
import React, { cloneElement, createElement, forwardRef, memo, useImperativeHandle, useMemo, useRef } from "react";
|
|
4
2
|
import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
|
|
5
3
|
import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js";
|
|
6
4
|
import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js";
|
|
7
|
-
const getPos = {
|
|
8
|
-
current () {
|
|
9
|
-
return -1;
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
5
|
export const DocNodeView = /*#__PURE__*/ memo(/*#__PURE__*/ forwardRef(function DocNodeView(param, ref) {
|
|
13
|
-
let {
|
|
6
|
+
let { as, node, getPos, decorations, innerDecorations, setMount, ...elementProps } = param;
|
|
14
7
|
const innerRef = useRef(null);
|
|
15
|
-
useImperativeHandle(ref, ()=>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
useImperativeHandle(ref, ()=>innerRef.current);
|
|
9
|
+
useImperativeHandle(setMount, ()=>innerRef.current);
|
|
10
|
+
const nodeProps = useMemo(()=>({
|
|
11
|
+
node,
|
|
12
|
+
getPos,
|
|
13
|
+
decorations,
|
|
14
|
+
innerDecorations
|
|
22
15
|
}), [
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
node,
|
|
17
|
+
getPos,
|
|
18
|
+
decorations,
|
|
19
|
+
innerDecorations
|
|
25
20
|
]);
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
innerDecorations: innerDeco
|
|
38
|
-
}))) : /*#__PURE__*/ createElement("div", props, /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, {
|
|
21
|
+
const { childContextValue } = useNodeViewDescriptor(innerRef, ()=>{
|
|
22
|
+
const dom = innerRef.current;
|
|
23
|
+
return {
|
|
24
|
+
dom,
|
|
25
|
+
contentDOM: dom,
|
|
26
|
+
update () {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}, nodeProps);
|
|
31
|
+
const children = /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, {
|
|
39
32
|
value: childContextValue
|
|
40
33
|
}, /*#__PURE__*/ React.createElement(ChildNodeViews, {
|
|
41
34
|
getPos: getPos,
|
|
42
35
|
node: node,
|
|
43
|
-
innerDecorations:
|
|
44
|
-
}))
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return wrapped;
|
|
36
|
+
innerDecorations: innerDecorations
|
|
37
|
+
}));
|
|
38
|
+
const props = {
|
|
39
|
+
...elementProps,
|
|
40
|
+
suppressContentEditableWarning: true,
|
|
41
|
+
ref: innerRef
|
|
42
|
+
};
|
|
43
|
+
const element = as ? /*#__PURE__*/ cloneElement(as, props, children) : /*#__PURE__*/ createElement("div", props, children);
|
|
44
|
+
return nodeProps.decorations.reduce(wrapInDeco, element);
|
|
53
45
|
}));
|
|
@@ -32,7 +32,7 @@ export const MarkView = /*#__PURE__*/ memo(/*#__PURE__*/ forwardRef(function Mar
|
|
|
32
32
|
if (!domRef.current) return;
|
|
33
33
|
const firstChildDesc = childDescriptors.current[0];
|
|
34
34
|
if (!viewDescRef.current) {
|
|
35
|
-
viewDescRef.current = new MarkViewDesc(parentRef.current, childDescriptors.current,
|
|
35
|
+
viewDescRef.current = new MarkViewDesc(parentRef.current, childDescriptors.current, getPos, mark, domRef.current, firstChildDesc?.dom.parentElement ?? domRef.current, {
|
|
36
36
|
dom: domRef.current,
|
|
37
37
|
contentDOM: firstChildDesc?.dom.parentElement ?? domRef.current
|
|
38
38
|
});
|
|
@@ -42,7 +42,6 @@ export const MarkView = /*#__PURE__*/ memo(/*#__PURE__*/ forwardRef(function Mar
|
|
|
42
42
|
viewDescRef.current.children = childDescriptors.current;
|
|
43
43
|
viewDescRef.current.spec.contentDOM = viewDescRef.current.contentDOM = firstChildDesc?.dom.parentElement ?? domRef.current;
|
|
44
44
|
viewDescRef.current.mark = mark;
|
|
45
|
-
viewDescRef.current.getPos = ()=>getPos.current();
|
|
46
45
|
}
|
|
47
46
|
if (!siblingsRef.current.includes(viewDescRef.current)) {
|
|
48
47
|
siblingsRef.current.push(viewDescRef.current);
|
|
@@ -24,7 +24,7 @@ export function NativeWidgetView(param) {
|
|
|
24
24
|
if (!rootDomRef.current) return;
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
26
|
const toDOM = widget.type.toDOM;
|
|
27
|
-
let dom = typeof toDOM === "function" ? toDOM(view,
|
|
27
|
+
let dom = typeof toDOM === "function" ? toDOM(view, getPos) : toDOM;
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
29
|
if (!widget.type.spec.raw) {
|
|
30
30
|
if (dom.nodeType != 1) {
|
|
@@ -41,11 +41,10 @@ export function NativeWidgetView(param) {
|
|
|
41
41
|
useClientLayoutEffect(()=>{
|
|
42
42
|
if (!rootDomRef.current) return;
|
|
43
43
|
if (!viewDescRef.current) {
|
|
44
|
-
viewDescRef.current = new WidgetViewDesc(parentRef.current,
|
|
44
|
+
viewDescRef.current = new WidgetViewDesc(parentRef.current, getPos, widget, rootDomRef.current);
|
|
45
45
|
} else {
|
|
46
46
|
viewDescRef.current.parent = parentRef.current;
|
|
47
47
|
viewDescRef.current.widget = widget;
|
|
48
|
-
viewDescRef.current.getPos = ()=>getPos.current();
|
|
49
48
|
viewDescRef.current.dom = rootDomRef.current;
|
|
50
49
|
}
|
|
51
50
|
if (!siblingsRef.current.includes(viewDescRef.current)) {
|
|
@@ -1,25 +1,35 @@
|
|
|
1
|
-
import React, { memo, useContext } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import React, { memo, useContext, useMemo } from "react";
|
|
2
|
+
import { NodeViewContext } from "../contexts/NodeViewContext.js";
|
|
3
3
|
import { CustomNodeView } from "./CustomNodeView.js";
|
|
4
|
+
import { DefaultNodeView } from "./DefaultNodeView.js";
|
|
4
5
|
import { ReactNodeView } from "./ReactNodeView.js";
|
|
5
|
-
export const NodeView = /*#__PURE__*/ memo(function NodeView(
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
6
|
+
export const NodeView = /*#__PURE__*/ memo(function NodeView(props) {
|
|
7
|
+
const { components, constructors } = useContext(NodeViewContext);
|
|
8
|
+
const component = components[props.node.type.name] ?? DefaultNodeView;
|
|
9
|
+
const constructor = constructors[props.node.type.name];
|
|
10
|
+
// Construct a wrapper component so that the node view remounts when either
|
|
11
|
+
// its component or constructor changes. A React node view would remount if
|
|
12
|
+
// its underlying component changed without this wrapper, but a custom node
|
|
13
|
+
// view otherwise uses the same React components for all custom node views.
|
|
14
|
+
const Component = useMemo(()=>{
|
|
15
|
+
if (constructor) {
|
|
16
|
+
return function NodeView(props) {
|
|
17
|
+
return /*#__PURE__*/ React.createElement(CustomNodeView, {
|
|
18
|
+
constructor: constructor,
|
|
19
|
+
...props
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
} else {
|
|
23
|
+
return function NodeView(props) {
|
|
24
|
+
return /*#__PURE__*/ React.createElement(ReactNodeView, {
|
|
25
|
+
component: component,
|
|
26
|
+
...props
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}, [
|
|
31
|
+
constructor,
|
|
32
|
+
component
|
|
33
|
+
]);
|
|
34
|
+
return /*#__PURE__*/ React.createElement(Component, props);
|
|
25
35
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { DecorationSet } from "prosemirror-view";
|
|
2
1
|
import React, { useMemo, useState } from "react";
|
|
3
2
|
import { EditorContext } from "../contexts/EditorContext.js";
|
|
4
3
|
import { EditorStateContext } from "../contexts/EditorStateContext.js";
|
|
@@ -8,7 +7,9 @@ import { viewDecorations } from "../decorations/viewDecorations.js";
|
|
|
8
7
|
import { useEditor } from "../hooks/useEditor.js";
|
|
9
8
|
import { LayoutGroup } from "./LayoutGroup.js";
|
|
10
9
|
import { DocNodeViewContext } from "./ProseMirrorDoc.js";
|
|
11
|
-
|
|
10
|
+
function getPos() {
|
|
11
|
+
return -1;
|
|
12
|
+
}
|
|
12
13
|
function ProseMirrorInner(param) {
|
|
13
14
|
let { className, children, nodeViews, customNodeViews, ...props } = param;
|
|
14
15
|
const [mount, setMount] = useState(null);
|
|
@@ -16,26 +17,33 @@ function ProseMirrorInner(param) {
|
|
|
16
17
|
...props,
|
|
17
18
|
nodeViews: customNodeViews
|
|
18
19
|
});
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const nodeViewConstructors = editor.view.nodeViews;
|
|
21
|
+
const nodeViewContextValue = useMemo(()=>{
|
|
22
|
+
return {
|
|
23
|
+
components: {
|
|
24
|
+
...nodeViews
|
|
25
|
+
},
|
|
26
|
+
constructors: nodeViewConstructors
|
|
27
|
+
};
|
|
28
|
+
}, [
|
|
29
|
+
nodeViewConstructors,
|
|
24
30
|
nodeViews
|
|
25
31
|
]);
|
|
32
|
+
const node = state.doc;
|
|
33
|
+
const decorations = computeDocDeco(editor.view);
|
|
34
|
+
const innerDecorations = viewDecorations(editor.view, editor.cursorWrapper);
|
|
26
35
|
const docNodeViewContextValue = useMemo(()=>({
|
|
27
|
-
className
|
|
28
|
-
setMount
|
|
29
|
-
node
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
className,
|
|
37
|
+
setMount,
|
|
38
|
+
node,
|
|
39
|
+
getPos,
|
|
40
|
+
decorations,
|
|
41
|
+
innerDecorations
|
|
33
42
|
}), [
|
|
34
43
|
className,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
outerDecos
|
|
44
|
+
node,
|
|
45
|
+
decorations,
|
|
46
|
+
innerDecorations
|
|
39
47
|
]);
|
|
40
48
|
return /*#__PURE__*/ React.createElement(EditorContext.Provider, {
|
|
41
49
|
value: editor
|
|
@@ -1,34 +1,13 @@
|
|
|
1
|
-
import React, { createContext, forwardRef, useContext
|
|
2
|
-
import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
|
|
1
|
+
import React, { createContext, forwardRef, useContext } from "react";
|
|
3
2
|
import { DocNodeView } from "./DocNodeView.js";
|
|
4
3
|
export const DocNodeViewContext = /*#__PURE__*/ createContext(null);
|
|
5
|
-
function ProseMirrorDoc(param, ref) {
|
|
4
|
+
export const ProseMirrorDoc = /*#__PURE__*/ forwardRef(function ProseMirrorDoc(param, ref) {
|
|
6
5
|
let { as, ...props } = param;
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const viewDescRef = useRef(undefined);
|
|
11
|
-
useImperativeHandle(ref, ()=>{
|
|
12
|
-
return innerRef.current;
|
|
13
|
-
}, []);
|
|
14
|
-
const childContextValue = useMemo(()=>({
|
|
15
|
-
parentRef: viewDescRef,
|
|
16
|
-
siblingsRef: childDescriptors
|
|
17
|
-
}), [
|
|
18
|
-
childDescriptors,
|
|
19
|
-
viewDescRef
|
|
20
|
-
]);
|
|
21
|
-
return /*#__PURE__*/ React.createElement(ChildDescriptorsContext.Provider, {
|
|
22
|
-
value: childContextValue
|
|
23
|
-
}, /*#__PURE__*/ React.createElement(DocNodeView, {
|
|
24
|
-
ref: (el)=>{
|
|
25
|
-
innerRef.current = el;
|
|
26
|
-
setMount(el);
|
|
27
|
-
},
|
|
6
|
+
const docProps = useContext(DocNodeViewContext);
|
|
7
|
+
return /*#__PURE__*/ React.createElement(DocNodeView, {
|
|
8
|
+
ref: ref,
|
|
28
9
|
...props,
|
|
29
10
|
...docProps,
|
|
30
11
|
as: as
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
const ForwardedProseMirrorDoc = /*#__PURE__*/ forwardRef(ProseMirrorDoc);
|
|
34
|
-
export { ForwardedProseMirrorDoc as ProseMirrorDoc };
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -1,81 +1,118 @@
|
|
|
1
|
-
import React, { cloneElement, memo,
|
|
1
|
+
import React, { cloneElement, memo, useCallback, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js";
|
|
3
3
|
import { IgnoreMutationContext } from "../contexts/IgnoreMutationContext.js";
|
|
4
|
-
import { NodeViewContext } from "../contexts/NodeViewContext.js";
|
|
5
4
|
import { SelectNodeContext } from "../contexts/SelectNodeContext.js";
|
|
6
5
|
import { StopEventContext } from "../contexts/StopEventContext.js";
|
|
7
6
|
import { useNodeViewDescriptor } from "../hooks/useNodeViewDescriptor.js";
|
|
8
7
|
import { ChildNodeViews, wrapInDeco } from "./ChildNodeViews.js";
|
|
9
|
-
import { OutputSpec } from "./OutputSpec.js";
|
|
10
8
|
export const ReactNodeView = /*#__PURE__*/ memo(function ReactNodeView(param) {
|
|
11
|
-
let { outerDeco, getPos, node, innerDeco
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
9
|
+
let { component: Component, outerDeco, getPos, node, innerDeco } = param;
|
|
10
|
+
const [controlSelected, setControlSelected] = useState(false);
|
|
11
|
+
const [selected, setSelected] = useState(false);
|
|
12
|
+
const ref = useRef(null);
|
|
13
|
+
const innerRef = useRef(null);
|
|
14
|
+
const selectNodeRef = useRef(null);
|
|
15
|
+
const deselectNodeRef = useRef(null);
|
|
16
|
+
const stopEventRef = useRef(null);
|
|
17
|
+
const ignoreMutationRef = useRef(null);
|
|
18
|
+
const setSelectNode = useCallback((selectHandler, deselectHandler)=>{
|
|
19
|
+
selectNodeRef.current = selectHandler;
|
|
20
|
+
deselectNodeRef.current = deselectHandler;
|
|
21
|
+
setControlSelected(true);
|
|
22
|
+
return ()=>{
|
|
23
|
+
selectNodeRef.current = null;
|
|
24
|
+
deselectNodeRef.current = null;
|
|
25
|
+
setControlSelected(false);
|
|
26
|
+
};
|
|
27
|
+
}, []);
|
|
28
|
+
const setStopEvent = useCallback((handler)=>{
|
|
29
|
+
stopEventRef.current = handler;
|
|
30
|
+
return ()=>{
|
|
31
|
+
stopEventRef.current = null;
|
|
32
|
+
};
|
|
33
|
+
}, []);
|
|
34
|
+
const setIgnoreMutation = useCallback((handler)=>{
|
|
35
|
+
ignoreMutationRef.current = handler;
|
|
36
|
+
return ()=>{
|
|
37
|
+
ignoreMutationRef.current = null;
|
|
38
|
+
return ()=>{
|
|
39
|
+
ignoreMutationRef.current = null;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
29
43
|
const nodeProps = useMemo(()=>({
|
|
30
44
|
node: node,
|
|
31
|
-
getPos:
|
|
45
|
+
getPos: getPos,
|
|
32
46
|
decorations: outerDeco,
|
|
33
47
|
innerDecorations: innerDeco
|
|
34
48
|
}), [
|
|
35
|
-
|
|
49
|
+
getPos,
|
|
36
50
|
innerDeco,
|
|
37
51
|
node,
|
|
38
52
|
outerDeco
|
|
39
53
|
]);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
54
|
+
const { childContextValue, contentDOM, nodeDOM } = useNodeViewDescriptor(ref, ()=>{
|
|
55
|
+
setSelected(false);
|
|
56
|
+
return {
|
|
57
|
+
dom: innerRef.current ?? ref.current,
|
|
58
|
+
update () {
|
|
59
|
+
return true;
|
|
60
|
+
},
|
|
61
|
+
multiType: true,
|
|
62
|
+
selectNode () {
|
|
63
|
+
const selectNode = selectNodeRef.current;
|
|
64
|
+
if (selectNode) {
|
|
65
|
+
selectNode();
|
|
66
|
+
}
|
|
67
|
+
setSelected(true);
|
|
68
|
+
},
|
|
69
|
+
deselectNode () {
|
|
70
|
+
const deselectNode = deselectNodeRef.current;
|
|
71
|
+
if (deselectNode) {
|
|
72
|
+
deselectNode();
|
|
73
|
+
}
|
|
74
|
+
setSelected(false);
|
|
75
|
+
},
|
|
76
|
+
stopEvent (event) {
|
|
77
|
+
const stopEvent = stopEventRef.current;
|
|
78
|
+
if (stopEvent) {
|
|
79
|
+
return stopEvent(event);
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
},
|
|
83
|
+
ignoreMutation (mutation) {
|
|
84
|
+
const ignoreMutation = ignoreMutationRef.current;
|
|
85
|
+
if (ignoreMutation) {
|
|
86
|
+
return ignoreMutation(mutation);
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
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 = {
|
|
98
|
+
nodeProps,
|
|
99
|
+
...!contentDOM && !nodeProps.node.isText && nodeDOM?.nodeName !== "BR" ? {
|
|
100
|
+
contentEditable: false,
|
|
101
|
+
suppressContentEditableWarning: true
|
|
102
|
+
} : null,
|
|
103
|
+
...controlSelected && selected ? {
|
|
104
|
+
className: "ProseMirror-selectednode"
|
|
105
|
+
} : null,
|
|
106
|
+
ref: innerRef
|
|
107
|
+
};
|
|
108
|
+
const innerElement = /*#__PURE__*/ React.createElement(Component, innerProps, children);
|
|
109
|
+
const props = {
|
|
110
|
+
...controlSelected && selected || node.type.spec.draggable ? {
|
|
111
|
+
draggable: true
|
|
112
|
+
} : null,
|
|
113
|
+
ref
|
|
114
|
+
};
|
|
115
|
+
const decoratedElement = /*#__PURE__*/ cloneElement(outerDeco.reduce(wrapInDeco, innerElement), props);
|
|
79
116
|
return /*#__PURE__*/ React.createElement(SelectNodeContext.Provider, {
|
|
80
117
|
value: setSelectNode
|
|
81
118
|
}, /*#__PURE__*/ React.createElement(StopEventContext.Provider, {
|
|
@@ -32,11 +32,10 @@ export function SeparatorHackView(param) {
|
|
|
32
32
|
}
|
|
33
33
|
if (!ref.current) return;
|
|
34
34
|
if (!viewDescRef.current) {
|
|
35
|
-
viewDescRef.current = new TrailingHackViewDesc(parentRef.current, [],
|
|
35
|
+
viewDescRef.current = new TrailingHackViewDesc(parentRef.current, [], getPos, ref.current, null);
|
|
36
36
|
} else {
|
|
37
37
|
viewDescRef.current.parent = parentRef.current;
|
|
38
38
|
viewDescRef.current.dom = ref.current;
|
|
39
|
-
viewDescRef.current.getPos = ()=>getPos.current();
|
|
40
39
|
}
|
|
41
40
|
if (!siblingsRef.current.includes(viewDescRef.current)) {
|
|
42
41
|
siblingsRef.current.push(viewDescRef.current);
|
|
@@ -37,8 +37,8 @@ export class TextNodeView extends Component {
|
|
|
37
37
|
// when a composition was started that produces a new text node.
|
|
38
38
|
// Otherwise we just rely on re-rendering the renderRef
|
|
39
39
|
if (!dom) {
|
|
40
|
-
if (!view
|
|
41
|
-
this.viewDescRef = new CompositionViewDesc(parentRef.current,
|
|
40
|
+
if (!view.composing) return;
|
|
41
|
+
this.viewDescRef = new CompositionViewDesc(parentRef.current, getPos, // These are just placeholders/dummies. We can't
|
|
42
42
|
// actually find the correct DOM nodes from here,
|
|
43
43
|
// so we let our parent do it.
|
|
44
44
|
// Passing a valid element here just so that the
|
|
@@ -51,12 +51,11 @@ export class TextNodeView extends Component {
|
|
|
51
51
|
textNode = textNode.firstChild;
|
|
52
52
|
}
|
|
53
53
|
if (!this.viewDescRef || this.viewDescRef instanceof CompositionViewDesc) {
|
|
54
|
-
this.viewDescRef = new TextViewDesc(undefined, [],
|
|
54
|
+
this.viewDescRef = new TextViewDesc(undefined, [], getPos, node, decorations, DecorationSet.empty, dom, textNode);
|
|
55
55
|
} else {
|
|
56
56
|
this.viewDescRef.parent = parentRef.current;
|
|
57
57
|
this.viewDescRef.children = [];
|
|
58
58
|
this.viewDescRef.node = node;
|
|
59
|
-
this.viewDescRef.getPos = ()=>getPos.current();
|
|
60
59
|
this.viewDescRef.outerDeco = decorations;
|
|
61
60
|
this.viewDescRef.innerDeco = DecorationSet.empty;
|
|
62
61
|
this.viewDescRef.dom = dom;
|
|
@@ -92,7 +91,7 @@ export class TextNodeView extends Component {
|
|
|
92
91
|
// an active composition and the selection is in this node,
|
|
93
92
|
// we freeze the DOM of this element so that it doesn't
|
|
94
93
|
// interrupt the composition
|
|
95
|
-
if (view
|
|
94
|
+
if (view.composing && view.state.selection.from >= getPos() && view.state.selection.from <= getPos() + node.nodeSize) {
|
|
96
95
|
return this.renderRef;
|
|
97
96
|
}
|
|
98
97
|
this.renderRef = decorations.reduce(wrapInDeco, node.text);
|
|
@@ -22,11 +22,10 @@ export function TrailingHackView(param) {
|
|
|
22
22
|
useClientLayoutEffect(()=>{
|
|
23
23
|
if (!ref.current) return;
|
|
24
24
|
if (!viewDescRef.current) {
|
|
25
|
-
viewDescRef.current = new TrailingHackViewDesc(parentRef.current, [],
|
|
25
|
+
viewDescRef.current = new TrailingHackViewDesc(parentRef.current, [], getPos, ref.current, null);
|
|
26
26
|
} else {
|
|
27
27
|
viewDescRef.current.parent = parentRef.current;
|
|
28
28
|
viewDescRef.current.dom = ref.current;
|
|
29
|
-
viewDescRef.current.getPos = ()=>getPos.current();
|
|
30
29
|
}
|
|
31
30
|
if (!siblingsRef.current.includes(viewDescRef.current)) {
|
|
32
31
|
siblingsRef.current.push(viewDescRef.current);
|
|
@@ -6,7 +6,6 @@ export function WidgetView(param) {
|
|
|
6
6
|
let { widget, getPos } = param;
|
|
7
7
|
const { siblingsRef, parentRef } = useContext(ChildDescriptorsContext);
|
|
8
8
|
const viewDescRef = useRef(null);
|
|
9
|
-
const getPosFunc = useRef(()=>getPos.current()).current;
|
|
10
9
|
const domRef = useRef(null);
|
|
11
10
|
useClientLayoutEffect(()=>{
|
|
12
11
|
const siblings = siblingsRef.current;
|
|
@@ -23,11 +22,10 @@ export function WidgetView(param) {
|
|
|
23
22
|
useClientLayoutEffect(()=>{
|
|
24
23
|
if (!domRef.current) return;
|
|
25
24
|
if (!viewDescRef.current) {
|
|
26
|
-
viewDescRef.current = new WidgetViewDesc(parentRef.current,
|
|
25
|
+
viewDescRef.current = new WidgetViewDesc(parentRef.current, getPos, widget, domRef.current);
|
|
27
26
|
} else {
|
|
28
27
|
viewDescRef.current.parent = parentRef.current;
|
|
29
28
|
viewDescRef.current.widget = widget;
|
|
30
|
-
viewDescRef.current.getPos = ()=>getPos.current();
|
|
31
29
|
viewDescRef.current.dom = domRef.current;
|
|
32
30
|
}
|
|
33
31
|
if (!siblingsRef.current.includes(viewDescRef.current)) {
|
|
@@ -39,7 +37,7 @@ export function WidgetView(param) {
|
|
|
39
37
|
return Component && /*#__PURE__*/ React.createElement(Component, {
|
|
40
38
|
ref: domRef,
|
|
41
39
|
widget: widget,
|
|
42
|
-
getPos:
|
|
40
|
+
getPos: getPos,
|
|
43
41
|
contentEditable: false
|
|
44
42
|
});
|
|
45
43
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Schema } from "prosemirror-model";
|
|
2
|
+
import { EditorState } from "prosemirror-state";
|
|
3
|
+
export const EMPTY_SCHEMA = new Schema({
|
|
4
|
+
nodes: {
|
|
5
|
+
doc: {
|
|
6
|
+
content: "text*"
|
|
7
|
+
},
|
|
8
|
+
text: {
|
|
9
|
+
inline: true
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
export const EMPTY_STATE = EditorState.create({
|
|
14
|
+
schema: EMPTY_SCHEMA
|
|
15
|
+
});
|