@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,53 @@
|
|
|
1
|
+
/* Copyright (c) The New York Times Company */ "use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
function _export(target, all) {
|
|
7
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: all[name]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
_export(exports, {
|
|
13
|
+
ProseMirror: function() {
|
|
14
|
+
return _ProseMirror.ProseMirror;
|
|
15
|
+
},
|
|
16
|
+
ProseMirrorDoc: function() {
|
|
17
|
+
return _ProseMirrorDoc.ProseMirrorDoc;
|
|
18
|
+
},
|
|
19
|
+
reactKeys: function() {
|
|
20
|
+
return _reactKeys.reactKeys;
|
|
21
|
+
},
|
|
22
|
+
useEditorEffect: function() {
|
|
23
|
+
return _useEditorEffect.useEditorEffect;
|
|
24
|
+
},
|
|
25
|
+
useEditorEventCallback: function() {
|
|
26
|
+
return _useEditorEventCallback.useEditorEventCallback;
|
|
27
|
+
},
|
|
28
|
+
useEditorEventListener: function() {
|
|
29
|
+
return _useEditorEventListener.useEditorEventListener;
|
|
30
|
+
},
|
|
31
|
+
useEditorState: function() {
|
|
32
|
+
return _useEditorState.useEditorState;
|
|
33
|
+
},
|
|
34
|
+
useSelectNode: function() {
|
|
35
|
+
return _useSelectNode.useSelectNode;
|
|
36
|
+
},
|
|
37
|
+
useStopEvent: function() {
|
|
38
|
+
return _useStopEvent.useStopEvent;
|
|
39
|
+
},
|
|
40
|
+
widget: function() {
|
|
41
|
+
return _ReactWidgetType.widget;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
const _ProseMirror = require("./components/ProseMirror.js");
|
|
45
|
+
const _ProseMirrorDoc = require("./components/ProseMirrorDoc.js");
|
|
46
|
+
const _useEditorEffect = require("./hooks/useEditorEffect.js");
|
|
47
|
+
const _useEditorEventCallback = require("./hooks/useEditorEventCallback.js");
|
|
48
|
+
const _useEditorEventListener = require("./hooks/useEditorEventListener.js");
|
|
49
|
+
const _useEditorState = require("./hooks/useEditorState.js");
|
|
50
|
+
const _useStopEvent = require("./hooks/useStopEvent.js");
|
|
51
|
+
const _useSelectNode = require("./hooks/useSelectNode.js");
|
|
52
|
+
const _reactKeys = require("./plugins/reactKeys.js");
|
|
53
|
+
const _ReactWidgetType = require("./decorations/ReactWidgetType.js");
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */ "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _prosemirrorModel = require("prosemirror-model");
|
|
6
|
+
const _prosemirrorState = require("prosemirror-state");
|
|
7
|
+
const _reactKeysJs = require("../reactKeys.js");
|
|
8
|
+
const schema = new _prosemirrorModel.Schema({
|
|
9
|
+
nodes: {
|
|
10
|
+
doc: {
|
|
11
|
+
content: "block+"
|
|
12
|
+
},
|
|
13
|
+
paragraph: {
|
|
14
|
+
group: "block",
|
|
15
|
+
content: "inline*"
|
|
16
|
+
},
|
|
17
|
+
list: {
|
|
18
|
+
group: "block",
|
|
19
|
+
content: "list_item+"
|
|
20
|
+
},
|
|
21
|
+
list_item: {
|
|
22
|
+
content: "inline*"
|
|
23
|
+
},
|
|
24
|
+
text: {
|
|
25
|
+
group: "inline"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
describe("reactNodeViewPlugin", ()=>{
|
|
30
|
+
it("should create a unique key for each node", ()=>{
|
|
31
|
+
const editorState = _prosemirrorState.EditorState.create({
|
|
32
|
+
doc: schema.topNodeType.create(null, [
|
|
33
|
+
schema.nodes.paragraph.create(),
|
|
34
|
+
schema.nodes.paragraph.create(),
|
|
35
|
+
schema.nodes.paragraph.create()
|
|
36
|
+
]),
|
|
37
|
+
plugins: [
|
|
38
|
+
(0, _reactKeysJs.reactKeys)()
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
const pluginState = _reactKeysJs.reactKeysPluginKey.getState(editorState);
|
|
42
|
+
expect(pluginState.posToKey.size).toBe(3);
|
|
43
|
+
});
|
|
44
|
+
it("should maintain key stability when possible", ()=>{
|
|
45
|
+
const initialEditorState = _prosemirrorState.EditorState.create({
|
|
46
|
+
doc: schema.topNodeType.create(null, [
|
|
47
|
+
schema.nodes.paragraph.create({}, schema.text("Hello")),
|
|
48
|
+
schema.nodes.paragraph.create(),
|
|
49
|
+
schema.nodes.paragraph.create()
|
|
50
|
+
]),
|
|
51
|
+
plugins: [
|
|
52
|
+
(0, _reactKeysJs.reactKeys)()
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
const initialPluginState = _reactKeysJs.reactKeysPluginKey.getState(initialEditorState);
|
|
56
|
+
const nextEditorState = initialEditorState.apply(initialEditorState.tr.insertText(", world!", 6));
|
|
57
|
+
const nextPluginState = _reactKeysJs.reactKeysPluginKey.getState(nextEditorState);
|
|
58
|
+
expect(Array.from(initialPluginState.keyToPos.keys())).toEqual(Array.from(nextPluginState.keyToPos.keys()));
|
|
59
|
+
});
|
|
60
|
+
it("should create unique keys for new nodes", ()=>{
|
|
61
|
+
const initialEditorState = _prosemirrorState.EditorState.create({
|
|
62
|
+
doc: schema.topNodeType.create(null, [
|
|
63
|
+
schema.nodes.paragraph.create(),
|
|
64
|
+
schema.nodes.paragraph.create(),
|
|
65
|
+
schema.nodes.paragraph.create()
|
|
66
|
+
]),
|
|
67
|
+
plugins: [
|
|
68
|
+
(0, _reactKeysJs.reactKeys)()
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
const initialPluginState = _reactKeysJs.reactKeysPluginKey.getState(initialEditorState);
|
|
72
|
+
const nextEditorState = initialEditorState.apply(initialEditorState.tr.insert(0, schema.nodes.list.createAndFill()));
|
|
73
|
+
const nextPluginState = _reactKeysJs.reactKeysPluginKey.getState(nextEditorState);
|
|
74
|
+
// Adds new keys for new nodes
|
|
75
|
+
expect(nextPluginState.keyToPos.size).toBe(5);
|
|
76
|
+
// Maintains keys for previous nodes that are still there
|
|
77
|
+
Array.from(initialPluginState.keyToPos.keys()).forEach((key)=>{
|
|
78
|
+
expect(Array.from(nextPluginState.keyToPos.keys())).toContain(key);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "beforeInputPlugin", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return beforeInputPlugin;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _prosemirrorstate = require("prosemirror-state");
|
|
12
|
+
const _CursorWrapper = require("../components/CursorWrapper.js");
|
|
13
|
+
const _ReactWidgetType = require("../decorations/ReactWidgetType.js");
|
|
14
|
+
const _reactKeys = require("./reactKeys.js");
|
|
15
|
+
function insertText(view, eventData) {
|
|
16
|
+
let options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
|
|
17
|
+
if (eventData === null) return false;
|
|
18
|
+
const from = options.from ?? view.state.selection.from;
|
|
19
|
+
const to = options.to ?? view.state.selection.to;
|
|
20
|
+
if (view.someProp("handleTextInput", (f)=>f(view, from, to, eventData))) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const { tr } = view.state;
|
|
24
|
+
if (options.marks) tr.ensureMarks(options.marks);
|
|
25
|
+
tr.insertText(eventData, from, to);
|
|
26
|
+
if (options.bust) {
|
|
27
|
+
const $from = view.state.doc.resolve(from);
|
|
28
|
+
const sharedAncestorDepth = $from.sharedDepth(to);
|
|
29
|
+
const sharedAncestorPos = $from.start(sharedAncestorDepth);
|
|
30
|
+
const parentKey = _reactKeys.reactKeysPluginKey.getState(view.state)?.posToKey.get(sharedAncestorPos - 1);
|
|
31
|
+
tr.setMeta(_reactKeys.reactKeysPluginKey, {
|
|
32
|
+
type: "bustKey",
|
|
33
|
+
payload: {
|
|
34
|
+
key: parentKey
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
view.dispatch(tr);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
function beforeInputPlugin(setCursorWrapper) {
|
|
42
|
+
let compositionText = null;
|
|
43
|
+
let compositionMarks = null;
|
|
44
|
+
return new _prosemirrorstate.Plugin({
|
|
45
|
+
props: {
|
|
46
|
+
handleDOMEvents: {
|
|
47
|
+
compositionstart (view) {
|
|
48
|
+
const { state } = view;
|
|
49
|
+
view.dispatch(state.tr.deleteSelection());
|
|
50
|
+
const $pos = state.selection.$from;
|
|
51
|
+
if (state.selection.empty && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore?.marks.some((m)=>m.type.spec.inclusive === false))) {
|
|
52
|
+
setCursorWrapper((0, _ReactWidgetType.widget)(state.selection.from, _CursorWrapper.CursorWrapper, {
|
|
53
|
+
key: "cursor-wrapper",
|
|
54
|
+
marks: state.storedMarks ?? $pos.marks()
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
compositionMarks = state.storedMarks ?? $pos.marks();
|
|
58
|
+
// @ts-expect-error Internal property - input
|
|
59
|
+
view.input.composing = true;
|
|
60
|
+
return true;
|
|
61
|
+
},
|
|
62
|
+
compositionupdate () {
|
|
63
|
+
return true;
|
|
64
|
+
},
|
|
65
|
+
compositionend (view) {
|
|
66
|
+
// @ts-expect-error Internal property - input
|
|
67
|
+
view.input.composing = false;
|
|
68
|
+
if (compositionText === null) return;
|
|
69
|
+
insertText(view, compositionText, {
|
|
70
|
+
// TODO: Rather than busting the reactKey cache here,
|
|
71
|
+
// which is pretty blunt and doesn't work for
|
|
72
|
+
// multi-node replacements, we should attempt to
|
|
73
|
+
// snapshot the selected DOM during compositionstart
|
|
74
|
+
// and restore it before we end the composition.
|
|
75
|
+
// This should allow React to successfully clean up
|
|
76
|
+
// and insert the newly composed text, without requiring
|
|
77
|
+
// any remounts
|
|
78
|
+
bust: true,
|
|
79
|
+
marks: compositionMarks
|
|
80
|
+
});
|
|
81
|
+
compositionText = null;
|
|
82
|
+
compositionMarks = null;
|
|
83
|
+
setCursorWrapper(null);
|
|
84
|
+
return true;
|
|
85
|
+
},
|
|
86
|
+
beforeinput (view, event) {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
switch(event.inputType){
|
|
89
|
+
case "insertCompositionText":
|
|
90
|
+
{
|
|
91
|
+
if (event.data === null) break;
|
|
92
|
+
compositionText = event.data;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "insertReplacementText":
|
|
96
|
+
{
|
|
97
|
+
const ranges = event.getTargetRanges();
|
|
98
|
+
event.dataTransfer?.items[0]?.getAsString((data)=>{
|
|
99
|
+
for (const range of ranges){
|
|
100
|
+
const from = view.posAtDOM(range.startContainer, range.startOffset, 1);
|
|
101
|
+
const to = view.posAtDOM(range.endContainer, range.endOffset, 1);
|
|
102
|
+
insertText(view, data, {
|
|
103
|
+
from,
|
|
104
|
+
to
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "insertText":
|
|
111
|
+
{
|
|
112
|
+
insertText(view, event.data);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "deleteWordBackward":
|
|
116
|
+
case "deleteContentBackward":
|
|
117
|
+
case "deleteWordForward":
|
|
118
|
+
case "deleteContentForward":
|
|
119
|
+
case "deleteContent":
|
|
120
|
+
{
|
|
121
|
+
const targetRanges = event.getTargetRanges();
|
|
122
|
+
const { tr } = view.state;
|
|
123
|
+
for (const range of targetRanges){
|
|
124
|
+
const start = view.posAtDOM(range.startContainer, range.startOffset);
|
|
125
|
+
const end = view.posAtDOM(range.endContainer, range.endOffset);
|
|
126
|
+
const { doc } = view.state;
|
|
127
|
+
const storedMarks = doc.resolve(start).marksAcross(doc.resolve(end));
|
|
128
|
+
tr.delete(start, end).setStoredMarks(storedMarks);
|
|
129
|
+
}
|
|
130
|
+
view.dispatch(tr);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
default:
|
|
134
|
+
{
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "componentEventListeners", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return componentEventListeners;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _prosemirrorstate = require("prosemirror-state");
|
|
12
|
+
const _reactdom = require("react-dom");
|
|
13
|
+
function componentEventListeners(eventHandlerRegistry) {
|
|
14
|
+
const domEventHandlers = {};
|
|
15
|
+
for (const [eventType, handlers] of eventHandlerRegistry.entries()){
|
|
16
|
+
function handleEvent(view, event) {
|
|
17
|
+
for (const handler of handlers){
|
|
18
|
+
let handled = false;
|
|
19
|
+
(0, _reactdom.unstable_batchedUpdates)(()=>{
|
|
20
|
+
handled = !!handler.call(this, view, event);
|
|
21
|
+
});
|
|
22
|
+
if (handled || event.defaultPrevented) return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
domEventHandlers[eventType] = handleEvent;
|
|
27
|
+
}
|
|
28
|
+
const plugin = new _prosemirrorstate.Plugin({
|
|
29
|
+
key: new _prosemirrorstate.PluginKey("@nytimes/react-prosemirror/componentEventListeners"),
|
|
30
|
+
props: {
|
|
31
|
+
handleDOMEvents: domEventHandlers
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return plugin;
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* Copyright (c) The New York Times Company */ "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "createComponentEventListenersPlugin", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return createComponentEventListenersPlugin;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _prosemirrorstate = require("prosemirror-state");
|
|
12
|
+
const _reactdom = require("react-dom");
|
|
13
|
+
function createComponentEventListenersPlugin(eventHandlerRegistry) {
|
|
14
|
+
const domEventHandlers = {};
|
|
15
|
+
for (const [eventType, handlers] of eventHandlerRegistry.entries()){
|
|
16
|
+
function handleEvent(view, event) {
|
|
17
|
+
for (const handler of handlers){
|
|
18
|
+
let handled = false;
|
|
19
|
+
(0, _reactdom.unstable_batchedUpdates)(()=>{
|
|
20
|
+
handled = !!handler.call(this, view, event);
|
|
21
|
+
});
|
|
22
|
+
if (handled || event.defaultPrevented) return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
domEventHandlers[eventType] = handleEvent;
|
|
27
|
+
}
|
|
28
|
+
const plugin = new _prosemirrorstate.Plugin({
|
|
29
|
+
key: new _prosemirrorstate.PluginKey("componentEventListeners"),
|
|
30
|
+
props: {
|
|
31
|
+
handleDOMEvents: domEventHandlers
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return plugin;
|
|
35
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
createNodeKey: function() {
|
|
13
|
+
return createNodeKey;
|
|
14
|
+
},
|
|
15
|
+
reactKeys: function() {
|
|
16
|
+
return reactKeys;
|
|
17
|
+
},
|
|
18
|
+
reactKeysPluginKey: function() {
|
|
19
|
+
return reactKeysPluginKey;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _prosemirrorstate = require("prosemirror-state");
|
|
23
|
+
function createNodeKey() {
|
|
24
|
+
const key = Math.floor(Math.random() * 0xffffffffffff).toString(16);
|
|
25
|
+
return key;
|
|
26
|
+
}
|
|
27
|
+
const reactKeysPluginKey = new _prosemirrorstate.PluginKey("@nytimes/react-prosemirror/reactKeys");
|
|
28
|
+
function reactKeys() {
|
|
29
|
+
let composing = false;
|
|
30
|
+
return new _prosemirrorstate.Plugin({
|
|
31
|
+
key: reactKeysPluginKey,
|
|
32
|
+
state: {
|
|
33
|
+
init (_, state) {
|
|
34
|
+
const next = {
|
|
35
|
+
posToKey: new Map(),
|
|
36
|
+
keyToPos: new Map()
|
|
37
|
+
};
|
|
38
|
+
state.doc.descendants((_, pos)=>{
|
|
39
|
+
const key = createNodeKey();
|
|
40
|
+
next.posToKey.set(pos, key);
|
|
41
|
+
next.keyToPos.set(key, pos);
|
|
42
|
+
return true;
|
|
43
|
+
});
|
|
44
|
+
return next;
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* Keeps node keys stable across transactions.
|
|
48
|
+
*
|
|
49
|
+
* To accomplish this, we map each node position forwards
|
|
50
|
+
* through the transaction to identify its current position,
|
|
51
|
+
* and assign its key to that new position, dropping it if the
|
|
52
|
+
* node was deleted.
|
|
53
|
+
*/ apply (tr, value, _, newState) {
|
|
54
|
+
if (!tr.docChanged || composing) return value;
|
|
55
|
+
const meta = tr.getMeta(reactKeysPluginKey);
|
|
56
|
+
const keyToBust = meta?.type === "bustKey" && meta.payload.key;
|
|
57
|
+
const next = {
|
|
58
|
+
posToKey: new Map(),
|
|
59
|
+
keyToPos: new Map()
|
|
60
|
+
};
|
|
61
|
+
const posToKeyEntries = Array.from(value.posToKey.entries()).sort((param, param1)=>{
|
|
62
|
+
let [a] = param, [b] = param1;
|
|
63
|
+
return a - b;
|
|
64
|
+
});
|
|
65
|
+
for (const [pos, key] of posToKeyEntries){
|
|
66
|
+
const { pos: newPos, deleted } = tr.mapping.mapResult(pos);
|
|
67
|
+
if (deleted) continue;
|
|
68
|
+
let newKey = key;
|
|
69
|
+
if (keyToBust === key) {
|
|
70
|
+
newKey = createNodeKey();
|
|
71
|
+
}
|
|
72
|
+
next.posToKey.set(newPos, newKey);
|
|
73
|
+
next.keyToPos.set(newKey, newPos);
|
|
74
|
+
}
|
|
75
|
+
newState.doc.descendants((_, pos)=>{
|
|
76
|
+
if (next.posToKey.has(pos)) return true;
|
|
77
|
+
const key = createNodeKey();
|
|
78
|
+
next.posToKey.set(pos, key);
|
|
79
|
+
next.keyToPos.set(key, pos);
|
|
80
|
+
return true;
|
|
81
|
+
});
|
|
82
|
+
return next;
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
props: {
|
|
86
|
+
handleDOMEvents: {
|
|
87
|
+
compositionstart: ()=>{
|
|
88
|
+
composing = true;
|
|
89
|
+
},
|
|
90
|
+
compositionend: ()=>{
|
|
91
|
+
composing = false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|