@handlewithcare/react-prosemirror 2.4.11 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/cjs/AbstractEditorView.js +4 -0
  2. package/dist/cjs/ReactEditorView.js +156 -0
  3. package/dist/cjs/StaticEditorView.js +86 -0
  4. package/dist/cjs/components/ChildNodeViews.js +59 -30
  5. package/dist/cjs/components/CustomNodeView.js +9 -25
  6. package/dist/cjs/components/DocNodeView.js +6 -15
  7. package/dist/cjs/components/MarkView.js +1 -2
  8. package/dist/cjs/components/NativeWidgetView.js +2 -3
  9. package/dist/cjs/components/NodeView.js +1 -1
  10. package/dist/cjs/components/ProseMirror.js +11 -14
  11. package/dist/cjs/components/ReactNodeView.js +3 -4
  12. package/dist/cjs/components/SeparatorHackView.js +1 -2
  13. package/dist/cjs/components/TextNodeView.js +4 -5
  14. package/dist/cjs/components/TrailingHackView.js +1 -2
  15. package/dist/cjs/components/WidgetView.js +2 -4
  16. package/dist/cjs/constants.js +33 -0
  17. package/dist/cjs/hooks/useEditor.js +32 -230
  18. package/dist/cjs/hooks/useEditorEffect.js +2 -2
  19. package/dist/cjs/hooks/useEditorEventCallback.js +8 -5
  20. package/dist/cjs/hooks/useNodeViewDescriptor.js +10 -10
  21. package/dist/cjs/hooks/useReactKeys.js +1 -1
  22. package/dist/cjs/testing/editorViewTestHelpers.js +0 -2
  23. package/dist/cjs/viewdesc.js +10 -9
  24. package/dist/esm/AbstractEditorView.js +1 -0
  25. package/dist/esm/ReactEditorView.js +156 -0
  26. package/dist/esm/StaticEditorView.js +76 -0
  27. package/dist/esm/components/ChildNodeViews.js +60 -32
  28. package/dist/esm/components/CustomNodeView.js +9 -25
  29. package/dist/esm/components/DocNodeView.js +6 -15
  30. package/dist/esm/components/MarkView.js +1 -2
  31. package/dist/esm/components/NativeWidgetView.js +2 -3
  32. package/dist/esm/components/NodeView.js +1 -1
  33. package/dist/esm/components/ProseMirror.js +11 -14
  34. package/dist/esm/components/ReactNodeView.js +3 -4
  35. package/dist/esm/components/SeparatorHackView.js +1 -2
  36. package/dist/esm/components/TextNodeView.js +4 -5
  37. package/dist/esm/components/TrailingHackView.js +1 -2
  38. package/dist/esm/components/WidgetView.js +2 -4
  39. package/dist/esm/constants.js +15 -0
  40. package/dist/esm/hooks/useEditor.js +28 -219
  41. package/dist/esm/hooks/useEditorEffect.js +2 -2
  42. package/dist/esm/hooks/useEditorEventCallback.js +8 -5
  43. package/dist/esm/hooks/useNodeViewDescriptor.js +10 -10
  44. package/dist/esm/hooks/useReactKeys.js +1 -1
  45. package/dist/esm/testing/editorViewTestHelpers.js +0 -2
  46. package/dist/esm/viewdesc.js +3 -2
  47. package/dist/tsconfig.tsbuildinfo +1 -1
  48. package/dist/types/AbstractEditorView.d.ts +27 -0
  49. package/dist/types/ReactEditorView.d.ts +79 -0
  50. package/dist/types/StaticEditorView.d.ts +24 -0
  51. package/dist/types/components/ChildNodeViews.d.ts +2 -2
  52. package/dist/types/components/CustomNodeView.d.ts +2 -2
  53. package/dist/types/components/DocNodeView.d.ts +2 -5
  54. package/dist/types/components/MarkView.d.ts +2 -2
  55. package/dist/types/components/NativeWidgetView.d.ts +2 -2
  56. package/dist/types/components/NodeView.d.ts +2 -2
  57. package/dist/types/components/ReactNodeView.d.ts +2 -2
  58. package/dist/types/components/SeparatorHackView.d.ts +2 -2
  59. package/dist/types/components/TextNodeView.d.ts +4 -3
  60. package/dist/types/components/TrailingHackView.d.ts +2 -2
  61. package/dist/types/components/WidgetView.d.ts +2 -2
  62. package/dist/types/constants.d.ts +4 -0
  63. package/dist/types/contexts/EditorContext.d.ts +6 -4
  64. package/dist/types/decorations/computeDocDeco.d.ts +3 -2
  65. package/dist/types/decorations/viewDecorations.d.ts +3 -2
  66. package/dist/types/hooks/useEditor.d.ts +5 -46
  67. package/dist/types/hooks/useNodeViewDescriptor.d.ts +1 -1
  68. package/dist/types/hooks/useReactKeys.d.ts +1 -1
  69. package/dist/types/props.d.ts +26 -26
  70. package/dist/types/viewdesc.d.ts +6 -5
  71. package/package.json +6 -2
  72. package/dist/cjs/components/__tests__/ProseMirror.composition.test.js +0 -398
  73. package/dist/cjs/components/__tests__/ProseMirror.domchange.test.js +0 -270
  74. package/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js +0 -1010
  75. package/dist/cjs/components/__tests__/ProseMirror.draw.test.js +0 -337
  76. package/dist/cjs/components/__tests__/ProseMirror.node-view.test.js +0 -315
  77. package/dist/cjs/components/__tests__/ProseMirror.selection.test.js +0 -444
  78. package/dist/cjs/components/__tests__/ProseMirror.test.js +0 -382
  79. package/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js +0 -141
  80. package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -108
  81. package/dist/cjs/plugins/__tests__/reactKeys.test.js +0 -81
  82. package/dist/cjs/selection/SelectionDOMObserver.js +0 -171
  83. package/dist/cjs/selection/hasFocusAndSelection.js +0 -35
  84. package/dist/cjs/selection/selectionFromDOM.js +0 -77
  85. package/dist/cjs/selection/selectionToDOM.js +0 -226
  86. package/dist/cjs/ssr.js +0 -85
  87. package/dist/esm/components/__tests__/ProseMirror.composition.test.js +0 -395
  88. package/dist/esm/components/__tests__/ProseMirror.domchange.test.js +0 -266
  89. package/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js +0 -967
  90. package/dist/esm/components/__tests__/ProseMirror.draw.test.js +0 -294
  91. package/dist/esm/components/__tests__/ProseMirror.node-view.test.js +0 -272
  92. package/dist/esm/components/__tests__/ProseMirror.selection.test.js +0 -440
  93. package/dist/esm/components/__tests__/ProseMirror.test.js +0 -339
  94. package/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js +0 -98
  95. package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -99
  96. package/dist/esm/plugins/__tests__/reactKeys.test.js +0 -77
  97. package/dist/esm/selection/SelectionDOMObserver.js +0 -161
  98. package/dist/esm/selection/hasFocusAndSelection.js +0 -17
  99. package/dist/esm/selection/selectionFromDOM.js +0 -59
  100. package/dist/esm/selection/selectionToDOM.js +0 -196
  101. package/dist/esm/ssr.js +0 -82
  102. package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +0 -1
  103. package/dist/types/selection/SelectionDOMObserver.d.ts +0 -33
  104. package/dist/types/selection/hasFocusAndSelection.d.ts +0 -3
  105. package/dist/types/selection/selectionFromDOM.d.ts +0 -4
  106. package/dist/types/selection/selectionToDOM.d.ts +0 -9
  107. package/dist/types/ssr.d.ts +0 -19
@@ -1,294 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-non-null-assertion */ function _extends() {
2
- _extends = Object.assign || function(target) {
3
- for(var i = 1; i < arguments.length; i++){
4
- var source = arguments[i];
5
- for(var key in source){
6
- if (Object.prototype.hasOwnProperty.call(source, key)) {
7
- target[key] = source[key];
8
- }
9
- }
10
- }
11
- return target;
12
- };
13
- return _extends.apply(this, arguments);
14
- }
15
- import { Schema } from "prosemirror-model";
16
- import { Plugin } from "prosemirror-state";
17
- import { doc, h1, hr, img, p, pre, schema, strong } from "prosemirror-test-builder";
18
- import React, { forwardRef } from "react";
19
- import { tempEditor } from "../../testing/editorViewTestHelpers.js";
20
- describe("EditorView draw", ()=>{
21
- it("updates the DOM", async ()=>{
22
- const { view } = tempEditor({
23
- doc: doc(p("foo"))
24
- });
25
- view.dispatch(view.state.tr.insertText("bar"));
26
- expect(view.dom.textContent).toBe("barfoo");
27
- });
28
- it("doesn't redraw nodes after changes", async ()=>{
29
- const { view } = tempEditor({
30
- doc: doc(h1("foo<a>"), p("bar"))
31
- });
32
- const oldP = view.dom.querySelector("p");
33
- view.dispatch(view.state.tr.insertText("!"));
34
- expect(view.dom.querySelector("p")).toBe(oldP);
35
- });
36
- it("doesn't redraw nodes before changes", async ()=>{
37
- const { view } = tempEditor({
38
- doc: doc(p("foo"), h1("bar"))
39
- });
40
- const oldP = view.dom.querySelector("p");
41
- view.dispatch(view.state.tr.insertText("!", 2));
42
- expect(view.dom.querySelector("p")).toBe(oldP);
43
- });
44
- it("doesn't redraw nodes between changes", async ()=>{
45
- const { view } = tempEditor({
46
- doc: doc(p("foo"), h1("bar"), pre("baz"))
47
- });
48
- const oldP = view.dom.querySelector("p");
49
- const oldPre = view.dom.querySelector("pre");
50
- view.dispatch(view.state.tr.insertText("!", 2));
51
- expect(view.dom.querySelector("p")).toBe(oldP);
52
- expect(view.dom.querySelector("pre")).toBe(oldPre);
53
- });
54
- it("doesn't redraw siblings of a split node", async ()=>{
55
- const { view } = tempEditor({
56
- doc: doc(p("foo"), h1("bar"), pre("baz"))
57
- });
58
- const oldP = view.dom.querySelector("p");
59
- const oldPre = view.dom.querySelector("pre");
60
- view.dispatch(view.state.tr.split(8));
61
- expect(view.dom.querySelector("p")).toBe(oldP);
62
- expect(view.dom.querySelector("pre")).toBe(oldPre);
63
- });
64
- it("doesn't redraw siblings of a joined node", async ()=>{
65
- const { view } = tempEditor({
66
- doc: doc(p("foo"), h1("bar"), h1("x"), pre("baz"))
67
- });
68
- const oldP = view.dom.querySelector("p");
69
- const oldPre = view.dom.querySelector("pre");
70
- view.dispatch(view.state.tr.join(10));
71
- expect(view.dom.querySelector("p")).toBe(oldP);
72
- expect(view.dom.querySelector("pre")).toBe(oldPre);
73
- });
74
- it("doesn't redraw after a big deletion", async ()=>{
75
- const { view } = tempEditor({
76
- doc: doc(p(), p(), p(), p(), p(), p(), p(), p(), h1("!"), p(), p())
77
- });
78
- const oldH = view.dom.querySelector("h1");
79
- view.dispatch(view.state.tr.delete(2, 14));
80
- expect(view.dom.querySelector("h1")).toBe(oldH);
81
- });
82
- it("adds classes from the attributes prop", async ()=>{
83
- const { view , rerender } = tempEditor({
84
- doc: doc(p()),
85
- attributes: {
86
- class: "foo bar"
87
- }
88
- });
89
- expect(view.dom.classList.contains("foo")).toBeTruthy();
90
- expect(view.dom.classList.contains("bar")).toBeTruthy();
91
- expect(view.dom.classList.contains("ProseMirror")).toBeTruthy();
92
- rerender({
93
- attributes: {
94
- class: "baz"
95
- }
96
- });
97
- expect(!view.dom.classList.contains("foo")).toBeTruthy();
98
- expect(view.dom.classList.contains("baz")).toBeTruthy();
99
- });
100
- it("adds style from the attributes prop", async ()=>{
101
- const { view } = tempEditor({
102
- doc: doc(p()),
103
- attributes: {
104
- style: "border: 1px solid red;"
105
- },
106
- plugins: [
107
- new Plugin({
108
- props: {
109
- attributes: {
110
- style: "background: red;"
111
- }
112
- }
113
- }),
114
- new Plugin({
115
- props: {
116
- attributes: {
117
- style: "color: red;"
118
- }
119
- }
120
- })
121
- ]
122
- });
123
- expect(view.dom.style.border).toBe("1px solid red");
124
- expect(view.dom.style.backgroundColor).toBe("red");
125
- expect(view.dom.style.color).toBe("red");
126
- });
127
- it("can set other attributes", async ()=>{
128
- const { view , rerender } = tempEditor({
129
- doc: doc(p()),
130
- attributes: {
131
- spellcheck: "false",
132
- "aria-label": "hello"
133
- }
134
- });
135
- expect(view.dom.spellcheck).toBe(false);
136
- expect(view.dom.getAttribute("aria-label")).toBe("hello");
137
- rerender({
138
- attributes: {
139
- style: "background-color: yellow"
140
- }
141
- });
142
- expect(view.dom.hasAttribute("aria-label")).toBe(false);
143
- expect(view.dom.style.backgroundColor).toBe("yellow");
144
- });
145
- it("can't set the contenteditable attribute", async ()=>{
146
- const { view } = tempEditor({
147
- doc: doc(p()),
148
- attributes: {
149
- contenteditable: "false"
150
- }
151
- });
152
- expect(view.dom.contentEditable).toBe("true");
153
- });
154
- it("understands the editable prop", async ()=>{
155
- const { view , rerender } = tempEditor({
156
- doc: doc(p()),
157
- editable: ()=>false
158
- });
159
- expect(view.dom.contentEditable).toBe("false");
160
- rerender({
161
- editable: ()=>true
162
- });
163
- expect(view.dom.contentEditable).toBe("true");
164
- });
165
- it("doesn't redraw following paragraphs when a paragraph is split", async ()=>{
166
- const { view } = tempEditor({
167
- doc: doc(p("abcde"), p("fg"))
168
- });
169
- const lastPara = view.dom.lastChild;
170
- view.dispatch(view.state.tr.split(3));
171
- expect(view.dom.lastChild).toBe(lastPara);
172
- });
173
- it("doesn't greedily match nodes that have another match", async ()=>{
174
- const { view } = tempEditor({
175
- doc: doc(p("a"), p("b"), p())
176
- });
177
- const secondPara = view.dom.querySelectorAll("p")[1];
178
- view.dispatch(view.state.tr.split(2));
179
- expect(view.dom.querySelectorAll("p")[2]).toBe(secondPara);
180
- });
181
- it("creates and destroys plugin views", async ()=>{
182
- const events = [];
183
- let PluginView = class PluginView {
184
- update() {
185
- events.push("update");
186
- }
187
- destroy() {
188
- events.push("destroy");
189
- }
190
- };
191
- const plugin = new Plugin({
192
- view () {
193
- events.push("create");
194
- return new PluginView();
195
- }
196
- });
197
- const { view , unmount } = tempEditor({
198
- plugins: [
199
- plugin
200
- ]
201
- });
202
- view.dispatch(view.state.tr.insertText("u"));
203
- unmount();
204
- expect(events.join(" ")).toBe("create update destroy");
205
- });
206
- it("redraws changed node views", async ()=>{
207
- const { view , rerender } = tempEditor({
208
- doc: doc(p("foo"), hr())
209
- });
210
- expect(view.dom.querySelector("hr")).toBeTruthy();
211
- rerender({
212
- nodeViews: {
213
- horizontal_rule: /*#__PURE__*/ forwardRef(function HorizontalRule(param, ref) {
214
- let { nodeProps , ...props } = param;
215
- return /*#__PURE__*/ React.createElement("var", _extends({
216
- ref: ref
217
- }, props));
218
- })
219
- }
220
- });
221
- expect(!view.dom.querySelector("hr")).toBeTruthy();
222
- expect(view.dom.querySelector("var")).toBeTruthy();
223
- });
224
- it("doesn't get confused by merged nodes", async ()=>{
225
- const { view } = tempEditor({
226
- doc: doc(p(strong("one"), " two ", strong("three")))
227
- });
228
- view.dispatch(view.state.tr.removeMark(1, 4, schema.marks.strong));
229
- expect(view.dom.querySelectorAll("strong")).toHaveLength(1);
230
- });
231
- it("doesn't redraw too much when marks are present", async ()=>{
232
- const s = new Schema({
233
- nodes: {
234
- doc: {
235
- content: "paragraph+",
236
- marks: "m"
237
- },
238
- text: {
239
- group: "inline"
240
- },
241
- paragraph: schema.spec.nodes.get("paragraph")
242
- },
243
- marks: {
244
- m: {
245
- toDOM: ()=>[
246
- "div",
247
- {
248
- class: "m"
249
- },
250
- 0
251
- ],
252
- parseDOM: [
253
- {
254
- tag: "div.m"
255
- }
256
- ]
257
- }
258
- }
259
- });
260
- const paragraphs = [];
261
- for(let i = 1; i <= 10; i++)paragraphs.push(s.node("paragraph", null, [
262
- s.text("para " + i)
263
- ], [
264
- s.mark("m")
265
- ]));
266
- const { view } = tempEditor({
267
- // @ts-expect-error this is fine
268
- doc: s.node("doc", null, paragraphs)
269
- });
270
- const initialChildren = Array.from(view.dom.querySelectorAll("p"));
271
- const newParagraphs = [];
272
- for(let i = -6; i < 0; i++)newParagraphs.push(s.node("paragraph", null, [
273
- s.text("para " + i)
274
- ], [
275
- s.mark("m")
276
- ]));
277
- view.dispatch(view.state.tr.replaceWith(0, 8, newParagraphs));
278
- const currentChildren = Array.from(view.dom.querySelectorAll("p"));
279
- let sameAtEnd = 0;
280
- while(sameAtEnd < currentChildren.length && sameAtEnd < initialChildren.length && currentChildren[currentChildren.length - sameAtEnd - 1] == initialChildren[initialChildren.length - sameAtEnd - 1])sameAtEnd++;
281
- expect(sameAtEnd).toBe(9);
282
- });
283
- it("correctly wraps inline nodes with marks", async ()=>{
284
- const { view } = tempEditor({
285
- doc: doc(p(strong(img(), " two")))
286
- });
287
- const docDom = view.dom;
288
- const paragraphDom = docDom.firstElementChild;
289
- const strongDom = paragraphDom.firstElementChild;
290
- expect(strongDom?.tagName).toBe("STRONG");
291
- expect(strongDom?.firstElementChild?.tagName).toBe("IMG");
292
- expect(strongDom?.childNodes.item(1).textContent).toBe(" two");
293
- });
294
- });
@@ -1,272 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ function _extends() {
2
- _extends = Object.assign || function(target) {
3
- for(var i = 1; i < arguments.length; i++){
4
- var source = arguments[i];
5
- for(var key in source){
6
- if (Object.prototype.hasOwnProperty.call(source, key)) {
7
- target[key] = source[key];
8
- }
9
- }
10
- }
11
- return target;
12
- };
13
- return _extends.apply(this, arguments);
14
- }
15
- import { screen } from "@testing-library/react";
16
- import { Plugin } from "prosemirror-state";
17
- import { blockquote, br, doc, p } from "prosemirror-test-builder";
18
- import { Decoration, DecorationSet } from "prosemirror-view";
19
- import React, { forwardRef, useEffect } from "react";
20
- import { useEditorState } from "../../hooks/useEditorState.js";
21
- import { useStopEvent } from "../../hooks/useStopEvent.js";
22
- import { tempEditor } from "../../testing/editorViewTestHelpers.js";
23
- describe("nodeViews prop", ()=>{
24
- it("can replace a node's representation", async ()=>{
25
- const { view } = tempEditor({
26
- doc: doc(p("foo", br())),
27
- nodeViews: {
28
- hard_break: /*#__PURE__*/ forwardRef(function Var(props, ref) {
29
- return /*#__PURE__*/ React.createElement("var", {
30
- ref: ref
31
- }, props.children);
32
- })
33
- }
34
- });
35
- expect(view.dom.querySelector("var")).not.toBeNull();
36
- });
37
- it("can override drawing of a node's content", async ()=>{
38
- const { view } = tempEditor({
39
- doc: doc(p("foo")),
40
- nodeViews: {
41
- paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) {
42
- return /*#__PURE__*/ React.createElement("p", {
43
- ref: ref
44
- }, props.nodeProps.node.textContent.toUpperCase());
45
- })
46
- }
47
- });
48
- expect(view.dom.querySelector("p").textContent).toBe("FOO");
49
- view.dispatch(view.state.tr.insertText("a"));
50
- expect(view.dom.querySelector("p").textContent).toBe("AFOO");
51
- });
52
- // React makes this more or less trivial; the render
53
- // method of the component _is_ the update (and create)
54
- // method
55
- // eslint-disable-next-line jest/no-disabled-tests
56
- it.skip("can register its own update method", async ()=>{
57
- const { view } = tempEditor({
58
- doc: doc(p("foo")),
59
- nodeViews: {
60
- paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) {
61
- return /*#__PURE__*/ React.createElement("p", {
62
- ref: ref
63
- }, props.nodeProps.node.textContent.toUpperCase());
64
- })
65
- }
66
- });
67
- const para = view.dom.querySelector("p");
68
- view.dispatch(view.state.tr.insertText("a"));
69
- expect(view.dom.querySelector("p")).toBe(para);
70
- expect(para.textContent).toBe("AFOO");
71
- });
72
- it("allows decoration updates for node views with an update method", async ()=>{
73
- const { view , rerender } = tempEditor({
74
- doc: doc(p("foo")),
75
- nodeViews: {
76
- paragraph: /*#__PURE__*/ forwardRef(function Paragraph(param, ref) {
77
- let { children , nodeProps , ...props } = param;
78
- return /*#__PURE__*/ React.createElement("p", _extends({
79
- ref: ref
80
- }, props), children);
81
- })
82
- }
83
- });
84
- rerender({
85
- decorations (state) {
86
- return DecorationSet.create(state.doc, [
87
- Decoration.inline(2, 3, {
88
- someattr: "ok"
89
- }),
90
- Decoration.node(0, 5, {
91
- otherattr: "ok"
92
- })
93
- ]);
94
- }
95
- });
96
- expect(view.dom.querySelector("[someattr]")).not.toBeNull();
97
- expect(view.dom.querySelector("[otherattr]")).not.toBeNull();
98
- });
99
- it("can provide a contentDOM property", async ()=>{
100
- const { view } = tempEditor({
101
- doc: doc(p("foo")),
102
- nodeViews: {
103
- paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) {
104
- return(// ContentDOM is inferred from where props.children is rendered
105
- /*#__PURE__*/ React.createElement("p", {
106
- ref: ref
107
- }, props.children));
108
- })
109
- }
110
- });
111
- const para = view.dom.querySelector("p");
112
- view.dispatch(view.state.tr.insertText("a"));
113
- expect(view.dom.querySelector("p")).toBe(para);
114
- expect(para.textContent).toBe("afoo");
115
- });
116
- it("has its destroy method called", async ()=>{
117
- let destroyed = false;
118
- const { view } = tempEditor({
119
- doc: doc(p("foo", br())),
120
- nodeViews: {
121
- hard_break: /*#__PURE__*/ forwardRef(function BR(_props, ref) {
122
- // React implements "destroy methods" with effect
123
- // hooks
124
- useEffect(()=>{
125
- return ()=>{
126
- destroyed = true;
127
- };
128
- }, []);
129
- return /*#__PURE__*/ React.createElement("br", {
130
- ref: ref
131
- });
132
- })
133
- }
134
- });
135
- expect(destroyed).toBeFalsy();
136
- view.dispatch(view.state.tr.delete(3, 5));
137
- expect(destroyed).toBeTruthy();
138
- });
139
- it("can query its own position", async ()=>{
140
- let pos;
141
- const { view } = tempEditor({
142
- doc: doc(blockquote(p("abc"), p("foo", br()))),
143
- nodeViews: {
144
- hard_break: /*#__PURE__*/ forwardRef(function BR(param, ref) {
145
- let { nodeProps , children , ...props } = param;
146
- // trigger a re-render on every updated, otherwise we won't
147
- // re-render when an updated doesn't directly affect us
148
- useEditorState();
149
- pos = nodeProps.getPos();
150
- return /*#__PURE__*/ React.createElement("br", _extends({
151
- ref: ref
152
- }, props));
153
- })
154
- }
155
- });
156
- expect(pos).toBe(10);
157
- view.dispatch(view.state.tr.insertText("a"));
158
- expect(pos).toBe(11);
159
- });
160
- it("has access to outer decorations", async ()=>{
161
- const plugin = new Plugin({
162
- state: {
163
- init () {
164
- return null;
165
- },
166
- apply (tr, prev) {
167
- return tr.getMeta("setDeco") || prev;
168
- }
169
- },
170
- props: {
171
- decorations (state) {
172
- const deco = this.getState(state);
173
- return deco && DecorationSet.create(state.doc, [
174
- Decoration.inline(0, state.doc.content.size, {}, {
175
- name: deco
176
- })
177
- ]);
178
- }
179
- }
180
- });
181
- const { view } = tempEditor({
182
- doc: doc(p("foo", br())),
183
- plugins: [
184
- plugin
185
- ],
186
- nodeViews: {
187
- hard_break: /*#__PURE__*/ forwardRef(function Var(props, ref) {
188
- return /*#__PURE__*/ React.createElement("var", {
189
- ref: ref
190
- }, props.nodeProps.decorations.length ? props.nodeProps.decorations[0].spec.name : "[]");
191
- })
192
- }
193
- });
194
- expect(view.dom.querySelector("var").textContent).toBe("[]");
195
- view.dispatch(view.state.tr.setMeta("setDeco", "foo"));
196
- expect(view.dom.querySelector("var").textContent).toBe("foo");
197
- view.dispatch(view.state.tr.setMeta("setDeco", "bar"));
198
- expect(view.dom.querySelector("var").textContent).toBe("bar");
199
- });
200
- it("provides access to inner decorations in the constructor", async ()=>{
201
- tempEditor({
202
- doc: doc(p("foo")),
203
- nodeViews: {
204
- paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) {
205
- expect(props.nodeProps.innerDecorations.find().map((d)=>`${d.from}-${d.to}`).join()).toBe("1-2");
206
- return /*#__PURE__*/ React.createElement("p", {
207
- ref: ref
208
- }, props.children);
209
- })
210
- },
211
- decorations (state) {
212
- return DecorationSet.create(state.doc, [
213
- Decoration.inline(2, 3, {
214
- someattr: "ok"
215
- }),
216
- Decoration.node(0, 5, {
217
- otherattr: "ok"
218
- })
219
- ]);
220
- }
221
- });
222
- });
223
- it("provides access to inner decorations in the update method", async ()=>{
224
- let innerDecos = [];
225
- const { rerender } = tempEditor({
226
- doc: doc(p("foo")),
227
- nodeViews: {
228
- paragraph: /*#__PURE__*/ forwardRef(function Paragraph(props, ref) {
229
- innerDecos = props.nodeProps.innerDecorations.find().map((d)=>`${d.from}-${d.to}`);
230
- return /*#__PURE__*/ React.createElement("p", {
231
- ref: ref
232
- }, props.children);
233
- })
234
- }
235
- });
236
- rerender({
237
- decorations (state) {
238
- return DecorationSet.create(state.doc, [
239
- Decoration.inline(2, 3, {
240
- someattr: "ok"
241
- }),
242
- Decoration.node(0, 5, {
243
- otherattr: "ok"
244
- })
245
- ]);
246
- }
247
- });
248
- expect(innerDecos.join()).toBe("1-2");
249
- });
250
- it("can provide a stopEvent hook", async ()=>{
251
- tempEditor({
252
- doc: doc(p("input value")),
253
- nodeViews: {
254
- paragraph: /*#__PURE__*/ forwardRef(function ParagraphInput(param, ref) {
255
- let { nodeProps , children , ...props } = param;
256
- useStopEvent(()=>{
257
- return true;
258
- });
259
- return /*#__PURE__*/ React.createElement("input", _extends({
260
- ref: ref,
261
- type: "text",
262
- defaultValue: nodeProps.node.textContent
263
- }, props));
264
- })
265
- }
266
- });
267
- const input = screen.getByDisplayValue("input value");
268
- input.focus();
269
- await browser.keys("z");
270
- expect(await $(input).getValue()).toBe("input valuez");
271
- });
272
- });