@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.
Files changed (209) hide show
  1. package/LICENSE.txt +12 -0
  2. package/README.md +705 -0
  3. package/dist/cjs/browser.js +53 -0
  4. package/dist/cjs/components/ChildNodeViews.js +376 -0
  5. package/dist/cjs/components/CursorWrapper.js +91 -0
  6. package/dist/cjs/components/CustomNodeView.js +79 -0
  7. package/dist/cjs/components/DocNodeView.js +104 -0
  8. package/dist/cjs/components/LayoutGroup.js +111 -0
  9. package/dist/cjs/components/MarkView.js +115 -0
  10. package/dist/cjs/components/NativeWidgetView.js +109 -0
  11. package/dist/cjs/components/NodeView.js +196 -0
  12. package/dist/cjs/components/NodeViewComponentProps.js +4 -0
  13. package/dist/cjs/components/OutputSpec.js +88 -0
  14. package/dist/cjs/components/ProseMirror.js +103 -0
  15. package/dist/cjs/components/ProseMirrorDoc.js +92 -0
  16. package/dist/cjs/components/SeparatorHackView.js +100 -0
  17. package/dist/cjs/components/TextNodeView.js +112 -0
  18. package/dist/cjs/components/TrailingHackView.js +90 -0
  19. package/dist/cjs/components/WidgetView.js +95 -0
  20. package/dist/cjs/components/WidgetViewComponentProps.js +4 -0
  21. package/dist/cjs/components/__tests__/ProseMirror.composition.test.js +398 -0
  22. package/dist/cjs/components/__tests__/ProseMirror.domchange.test.js +270 -0
  23. package/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js +1010 -0
  24. package/dist/cjs/components/__tests__/ProseMirror.draw.test.js +337 -0
  25. package/dist/cjs/components/__tests__/ProseMirror.node-view.test.js +315 -0
  26. package/dist/cjs/components/__tests__/ProseMirror.selection.test.js +444 -0
  27. package/dist/cjs/components/__tests__/ProseMirror.test.js +382 -0
  28. package/dist/cjs/contexts/ChildDescriptorsContext.js +19 -0
  29. package/dist/cjs/contexts/EditorContext.js +12 -0
  30. package/dist/cjs/contexts/EditorStateContext.js +12 -0
  31. package/dist/cjs/contexts/LayoutGroupContext.js +12 -0
  32. package/dist/cjs/contexts/NodeViewContext.js +12 -0
  33. package/dist/cjs/contexts/SelectNodeContext.js +12 -0
  34. package/dist/cjs/contexts/StopEventContext.js +12 -0
  35. package/dist/cjs/contexts/__tests__/DeferredLayoutEffects.test.js +141 -0
  36. package/dist/cjs/decorations/ReactWidgetType.js +58 -0
  37. package/dist/cjs/decorations/computeDocDeco.js +44 -0
  38. package/dist/cjs/decorations/internalTypes.js +4 -0
  39. package/dist/cjs/decorations/iterDeco.js +79 -0
  40. package/dist/cjs/decorations/viewDecorations.js +163 -0
  41. package/dist/cjs/dom.js +142 -0
  42. package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +108 -0
  43. package/dist/cjs/hooks/useClientOnly.js +18 -0
  44. package/dist/cjs/hooks/useComponentEventListeners.js +39 -0
  45. package/dist/cjs/hooks/useEditor.js +287 -0
  46. package/dist/cjs/hooks/useEditorEffect.js +35 -0
  47. package/dist/cjs/hooks/useEditorEventCallback.js +33 -0
  48. package/dist/cjs/hooks/useEditorEventListener.js +34 -0
  49. package/dist/cjs/hooks/useEditorState.js +16 -0
  50. package/dist/cjs/hooks/useForceUpdate.js +15 -0
  51. package/dist/cjs/hooks/useLayoutGroupEffect.js +19 -0
  52. package/dist/cjs/hooks/useNodeViewDescriptor.js +115 -0
  53. package/dist/cjs/hooks/useReactKeys.js +17 -0
  54. package/dist/cjs/hooks/useSelectNode.js +28 -0
  55. package/dist/cjs/hooks/useStopEvent.js +24 -0
  56. package/dist/cjs/index.js +53 -0
  57. package/dist/cjs/package.json +3 -0
  58. package/dist/cjs/plugins/__tests__/reactKeys.test.js +81 -0
  59. package/dist/cjs/plugins/beforeInputPlugin.js +143 -0
  60. package/dist/cjs/plugins/componentEventListeners.js +35 -0
  61. package/dist/cjs/plugins/componentEventListenersPlugin.js +35 -0
  62. package/dist/cjs/plugins/reactKeys.js +96 -0
  63. package/dist/cjs/props.js +269 -0
  64. package/dist/cjs/selection/SelectionDOMObserver.js +174 -0
  65. package/dist/cjs/selection/hasFocusAndSelection.js +35 -0
  66. package/dist/cjs/selection/selectionFromDOM.js +77 -0
  67. package/dist/cjs/selection/selectionToDOM.js +226 -0
  68. package/dist/cjs/ssr.js +85 -0
  69. package/dist/cjs/testing/editorViewTestHelpers.js +111 -0
  70. package/dist/cjs/testing/setupProseMirrorView.js +94 -0
  71. package/dist/cjs/viewdesc.js +664 -0
  72. package/dist/esm/browser.js +43 -0
  73. package/dist/esm/components/ChildNodeViews.js +318 -0
  74. package/dist/esm/components/CursorWrapper.js +40 -0
  75. package/dist/esm/components/CustomNodeView.js +28 -0
  76. package/dist/esm/components/DocNodeView.js +53 -0
  77. package/dist/esm/components/LayoutGroup.js +66 -0
  78. package/dist/esm/components/MarkView.js +64 -0
  79. package/dist/esm/components/NativeWidgetView.js +58 -0
  80. package/dist/esm/components/NodeView.js +145 -0
  81. package/dist/esm/components/NodeViewComponentProps.js +1 -0
  82. package/dist/esm/components/OutputSpec.js +38 -0
  83. package/dist/esm/components/ProseMirror.js +52 -0
  84. package/dist/esm/components/ProseMirrorDoc.js +34 -0
  85. package/dist/esm/components/SeparatorHackView.js +49 -0
  86. package/dist/esm/components/TextNodeView.js +102 -0
  87. package/dist/esm/components/TrailingHackView.js +39 -0
  88. package/dist/esm/components/WidgetView.js +44 -0
  89. package/dist/esm/components/WidgetViewComponentProps.js +1 -0
  90. package/dist/esm/components/__tests__/ProseMirror.composition.test.js +395 -0
  91. package/dist/esm/components/__tests__/ProseMirror.domchange.test.js +266 -0
  92. package/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js +967 -0
  93. package/dist/esm/components/__tests__/ProseMirror.draw.test.js +294 -0
  94. package/dist/esm/components/__tests__/ProseMirror.node-view.test.js +272 -0
  95. package/dist/esm/components/__tests__/ProseMirror.selection.test.js +440 -0
  96. package/dist/esm/components/__tests__/ProseMirror.test.js +339 -0
  97. package/dist/esm/contexts/ChildDescriptorsContext.js +9 -0
  98. package/dist/esm/contexts/EditorContext.js +7 -0
  99. package/dist/esm/contexts/EditorStateContext.js +2 -0
  100. package/dist/esm/contexts/LayoutGroupContext.js +2 -0
  101. package/dist/esm/contexts/NodeViewContext.js +2 -0
  102. package/dist/esm/contexts/SelectNodeContext.js +2 -0
  103. package/dist/esm/contexts/StopEventContext.js +2 -0
  104. package/dist/esm/contexts/__tests__/DeferredLayoutEffects.test.js +98 -0
  105. package/dist/esm/decorations/ReactWidgetType.js +40 -0
  106. package/dist/esm/decorations/computeDocDeco.js +44 -0
  107. package/dist/esm/decorations/internalTypes.js +1 -0
  108. package/dist/esm/decorations/iterDeco.js +73 -0
  109. package/dist/esm/decorations/viewDecorations.js +163 -0
  110. package/dist/esm/dom.js +105 -0
  111. package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +99 -0
  112. package/dist/esm/hooks/useClientOnly.js +8 -0
  113. package/dist/esm/hooks/useComponentEventListeners.js +54 -0
  114. package/dist/esm/hooks/useEditor.js +278 -0
  115. package/dist/esm/hooks/useEditorEffect.js +38 -0
  116. package/dist/esm/hooks/useEditorEventCallback.js +35 -0
  117. package/dist/esm/hooks/useEditorEventListener.js +28 -0
  118. package/dist/esm/hooks/useEditorState.js +8 -0
  119. package/dist/esm/hooks/useForceUpdate.js +8 -0
  120. package/dist/esm/hooks/useLayoutGroupEffect.js +9 -0
  121. package/dist/esm/hooks/useNodeViewDescriptor.js +105 -0
  122. package/dist/esm/hooks/useReactKeys.js +7 -0
  123. package/dist/esm/hooks/useSelectNode.js +18 -0
  124. package/dist/esm/hooks/useStopEvent.js +14 -0
  125. package/dist/esm/index.js +11 -0
  126. package/dist/esm/plugins/__tests__/reactKeys.test.js +77 -0
  127. package/dist/esm/plugins/beforeInputPlugin.js +133 -0
  128. package/dist/esm/plugins/componentEventListeners.js +25 -0
  129. package/dist/esm/plugins/componentEventListenersPlugin.js +25 -0
  130. package/dist/esm/plugins/reactKeys.js +81 -0
  131. package/dist/esm/props.js +251 -0
  132. package/dist/esm/selection/SelectionDOMObserver.js +164 -0
  133. package/dist/esm/selection/hasFocusAndSelection.js +17 -0
  134. package/dist/esm/selection/selectionFromDOM.js +59 -0
  135. package/dist/esm/selection/selectionToDOM.js +196 -0
  136. package/dist/esm/ssr.js +82 -0
  137. package/dist/esm/testing/editorViewTestHelpers.js +88 -0
  138. package/dist/esm/testing/setupProseMirrorView.js +76 -0
  139. package/dist/esm/viewdesc.js +654 -0
  140. package/dist/tsconfig.tsbuildinfo +1 -0
  141. package/dist/types/browser.d.ts +15 -0
  142. package/dist/types/components/ChildNodeViews.d.ts +9 -0
  143. package/dist/types/components/CursorWrapper.d.ts +5 -0
  144. package/dist/types/components/CustomNodeView.d.ts +21 -0
  145. package/dist/types/components/DocNodeView.d.ts +20 -0
  146. package/dist/types/components/LayoutGroup.d.ts +12 -0
  147. package/dist/types/components/MarkView.d.ts +9 -0
  148. package/dist/types/components/NativeWidgetView.d.ts +8 -0
  149. package/dist/types/components/NodeView.d.ts +11 -0
  150. package/dist/types/components/NodeViewComponentProps.d.ts +12 -0
  151. package/dist/types/components/OutputSpec.d.ts +8 -0
  152. package/dist/types/components/ProseMirror.d.ts +15 -0
  153. package/dist/types/components/ProseMirrorDoc.d.ts +10 -0
  154. package/dist/types/components/SeparatorHackView.d.ts +6 -0
  155. package/dist/types/components/TextNodeView.d.ts +23 -0
  156. package/dist/types/components/TrailingHackView.d.ts +6 -0
  157. package/dist/types/components/WidgetView.d.ts +8 -0
  158. package/dist/types/components/WidgetViewComponentProps.d.ts +6 -0
  159. package/dist/types/components/__tests__/ProseMirror.composition.test.d.ts +1 -0
  160. package/dist/types/components/__tests__/ProseMirror.domchange.test.d.ts +1 -0
  161. package/dist/types/components/__tests__/ProseMirror.draw-decoration.test.d.ts +1 -0
  162. package/dist/types/components/__tests__/ProseMirror.draw.test.d.ts +1 -0
  163. package/dist/types/components/__tests__/ProseMirror.node-view.test.d.ts +1 -0
  164. package/dist/types/components/__tests__/ProseMirror.selection.test.d.ts +1 -0
  165. package/dist/types/components/__tests__/ProseMirror.test.d.ts +1 -0
  166. package/dist/types/contexts/ChildDescriptorsContext.d.ts +6 -0
  167. package/dist/types/contexts/EditorContext.d.ts +14 -0
  168. package/dist/types/contexts/EditorStateContext.d.ts +2 -0
  169. package/dist/types/contexts/LayoutGroupContext.d.ts +5 -0
  170. package/dist/types/contexts/NodeViewContext.d.ts +6 -0
  171. package/dist/types/contexts/SelectNodeContext.d.ts +3 -0
  172. package/dist/types/contexts/StopEventContext.d.ts +3 -0
  173. package/dist/types/contexts/__tests__/DeferredLayoutEffects.test.d.ts +1 -0
  174. package/dist/types/decorations/ReactWidgetType.d.ts +39 -0
  175. package/dist/types/decorations/computeDocDeco.d.ts +13 -0
  176. package/dist/types/decorations/internalTypes.d.ts +16 -0
  177. package/dist/types/decorations/iterDeco.d.ts +3 -0
  178. package/dist/types/decorations/viewDecorations.d.ts +13 -0
  179. package/dist/types/dom.d.ts +22 -0
  180. package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +1 -0
  181. package/dist/types/hooks/useClientOnly.d.ts +1 -0
  182. package/dist/types/hooks/useComponentEventListeners.d.ts +33 -0
  183. package/dist/types/hooks/useEditor.d.ts +66 -0
  184. package/dist/types/hooks/useEditorEffect.d.ts +17 -0
  185. package/dist/types/hooks/useEditorEventCallback.d.ts +15 -0
  186. package/dist/types/hooks/useEditorEventListener.d.ts +8 -0
  187. package/dist/types/hooks/useEditorState.d.ts +5 -0
  188. package/dist/types/hooks/useForceUpdate.d.ts +5 -0
  189. package/dist/types/hooks/useLayoutGroupEffect.d.ts +3 -0
  190. package/dist/types/hooks/useNodeViewDescriptor.d.ts +11 -0
  191. package/dist/types/hooks/useReactKeys.d.ts +5 -0
  192. package/dist/types/hooks/useSelectNode.d.ts +1 -0
  193. package/dist/types/hooks/useStopEvent.d.ts +2 -0
  194. package/dist/types/index.d.ts +12 -0
  195. package/dist/types/plugins/__tests__/reactKeys.test.d.ts +1 -0
  196. package/dist/types/plugins/beforeInputPlugin.d.ts +3 -0
  197. package/dist/types/plugins/componentEventListeners.d.ts +4 -0
  198. package/dist/types/plugins/componentEventListenersPlugin.d.ts +4 -0
  199. package/dist/types/plugins/reactKeys.d.ts +19 -0
  200. package/dist/types/props.d.ts +1174 -0
  201. package/dist/types/selection/SelectionDOMObserver.d.ts +34 -0
  202. package/dist/types/selection/hasFocusAndSelection.d.ts +3 -0
  203. package/dist/types/selection/selectionFromDOM.d.ts +4 -0
  204. package/dist/types/selection/selectionToDOM.d.ts +9 -0
  205. package/dist/types/ssr.d.ts +19 -0
  206. package/dist/types/testing/editorViewTestHelpers.d.ts +23 -0
  207. package/dist/types/testing/setupProseMirrorView.d.ts +2 -0
  208. package/dist/types/viewdesc.d.ts +131 -0
  209. package/package.json +113 -0
@@ -0,0 +1,1010 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ // TODO: figure out whether it's possible to support native
2
+ // widgets. Right now, I'm not sure how we'd do it without
3
+ // wrapping them in another element, which would re-introduce
4
+ // all of the issues we had before with node views.
5
+ //
6
+ // For now, we've updated the factory in this file to use
7
+ // our React widgets.
8
+ "use strict";
9
+ Object.defineProperty(exports, "__esModule", {
10
+ value: true
11
+ });
12
+ const _prosemirrorModel = require("prosemirror-model");
13
+ const _prosemirrorState = require("prosemirror-state");
14
+ const _prosemirrorTestBuilder = require("prosemirror-test-builder");
15
+ const _prosemirrorView = require("prosemirror-view");
16
+ const _react = /*#__PURE__*/ _interopRequireWildcard(require("react"));
17
+ const _reactWidgetTypeJs = require("../../decorations/ReactWidgetType.js");
18
+ const _useEditorEffectJs = require("../../hooks/useEditorEffect.js");
19
+ const _editorViewTestHelpersJs = require("../../testing/editorViewTestHelpers.js");
20
+ function _extends() {
21
+ _extends = Object.assign || function(target) {
22
+ for(var i = 1; i < arguments.length; i++){
23
+ var source = arguments[i];
24
+ for(var key in source){
25
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
26
+ target[key] = source[key];
27
+ }
28
+ }
29
+ }
30
+ return target;
31
+ };
32
+ return _extends.apply(this, arguments);
33
+ }
34
+ function _getRequireWildcardCache(nodeInterop) {
35
+ if (typeof WeakMap !== "function") return null;
36
+ var cacheBabelInterop = new WeakMap();
37
+ var cacheNodeInterop = new WeakMap();
38
+ return (_getRequireWildcardCache = function(nodeInterop) {
39
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
40
+ })(nodeInterop);
41
+ }
42
+ function _interopRequireWildcard(obj, nodeInterop) {
43
+ if (!nodeInterop && obj && obj.__esModule) {
44
+ return obj;
45
+ }
46
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
47
+ return {
48
+ default: obj
49
+ };
50
+ }
51
+ var cache = _getRequireWildcardCache(nodeInterop);
52
+ if (cache && cache.has(obj)) {
53
+ return cache.get(obj);
54
+ }
55
+ var newObj = {};
56
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
57
+ for(var key in obj){
58
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
59
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
60
+ if (desc && (desc.get || desc.set)) {
61
+ Object.defineProperty(newObj, key, desc);
62
+ } else {
63
+ newObj[key] = obj[key];
64
+ }
65
+ }
66
+ }
67
+ newObj.default = obj;
68
+ if (cache) {
69
+ cache.set(obj, newObj);
70
+ }
71
+ return newObj;
72
+ }
73
+ const Widget = /*#__PURE__*/ (0, _react.forwardRef)(function Widget(param, ref) {
74
+ let { widget , getPos , ...props } = param;
75
+ return /*#__PURE__*/ _react.default.createElement("button", _extends({
76
+ ref: ref
77
+ }, props), "ω");
78
+ });
79
+ function make(str) {
80
+ if (typeof str != "string") return str;
81
+ const match = /^(\d+)(?:-(\d+))?-(.+)$/.exec(str);
82
+ if (match[3] == "widget") {
83
+ return (0, _reactWidgetTypeJs.widget)(+match[1], Widget, {
84
+ key: str
85
+ });
86
+ }
87
+ return _prosemirrorView.Decoration.inline(+match[1], +match[2], {
88
+ class: match[3]
89
+ });
90
+ }
91
+ function decoPlugin(decos) {
92
+ return new _prosemirrorState.Plugin({
93
+ state: {
94
+ init (config) {
95
+ return config.doc ? _prosemirrorView.DecorationSet.create(config.doc, decos.map(make)) : _prosemirrorView.DecorationSet.empty;
96
+ },
97
+ apply (tr, set, state) {
98
+ if (tr.docChanged) set = set.map(tr.mapping, tr.doc);
99
+ const change = tr.getMeta("updateDecorations");
100
+ if (change) {
101
+ if (change.remove) set = set.remove(change.remove);
102
+ if (change.add) set = set.add(state.doc, change.add);
103
+ }
104
+ return set;
105
+ }
106
+ },
107
+ props: {
108
+ decorations (state) {
109
+ return this.getState(state);
110
+ }
111
+ }
112
+ });
113
+ }
114
+ function updateDeco(view, add, remove) {
115
+ view.dispatch(view.state.tr.setMeta("updateDecorations", {
116
+ add,
117
+ remove
118
+ }));
119
+ }
120
+ describe("Decoration drawing", ()=>{
121
+ it("draws inline decorations", async ()=>{
122
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
123
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")),
124
+ plugins: [
125
+ decoPlugin([
126
+ "2-5-foo"
127
+ ])
128
+ ]
129
+ });
130
+ const found = view.dom.querySelector(".foo");
131
+ await expect(found).not.toBeNull();
132
+ await expect(found.textContent).toBe("oob");
133
+ });
134
+ it("draws wrapping decorations", async ()=>{
135
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
136
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
137
+ plugins: [
138
+ decoPlugin([
139
+ _prosemirrorView.Decoration.inline(1, 5, {
140
+ nodeName: "i"
141
+ })
142
+ ])
143
+ ]
144
+ });
145
+ const found = view.dom.querySelector("i");
146
+ expect(found && found.innerHTML).toBe("foo");
147
+ });
148
+ it("draws node decorations", async ()=>{
149
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
150
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("bar")),
151
+ plugins: [
152
+ decoPlugin([
153
+ _prosemirrorView.Decoration.node(5, 10, {
154
+ class: "cls"
155
+ })
156
+ ])
157
+ ]
158
+ });
159
+ const found = view.dom.querySelectorAll(".cls");
160
+ expect(found).toHaveLength(1);
161
+ expect(found[0].nodeName).toBe("P");
162
+ expect(found[0].previousSibling.nodeName).toBe("P");
163
+ });
164
+ it("can update multi-level wrapping decorations", async ()=>{
165
+ const d2 = _prosemirrorView.Decoration.inline(1, 5, {
166
+ nodeName: "i",
167
+ class: "b"
168
+ });
169
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
170
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hello")),
171
+ plugins: [
172
+ decoPlugin([
173
+ _prosemirrorView.Decoration.inline(1, 5, {
174
+ nodeName: "i",
175
+ class: "a"
176
+ }),
177
+ d2
178
+ ])
179
+ ]
180
+ });
181
+ expect(view.dom.querySelectorAll("i")).toHaveLength(2);
182
+ updateDeco(view, [
183
+ _prosemirrorView.Decoration.inline(1, 5, {
184
+ nodeName: "i",
185
+ class: "c"
186
+ })
187
+ ], [
188
+ d2
189
+ ]);
190
+ const iNodes = view.dom.querySelectorAll("i");
191
+ expect(iNodes).toHaveLength(2);
192
+ expect(Array.prototype.map.call(iNodes, (n)=>n.className).sort().join()).toBe("a,c");
193
+ });
194
+ it("draws overlapping inline decorations", async ()=>{
195
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
196
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcdef")),
197
+ plugins: [
198
+ decoPlugin([
199
+ "3-5-foo",
200
+ "4-6-bar",
201
+ "1-7-baz"
202
+ ])
203
+ ]
204
+ });
205
+ const baz = view.dom.querySelectorAll(".baz");
206
+ expect(baz).toHaveLength(5);
207
+ expect(Array.prototype.map.call(baz, (x)=>x.textContent).join("-")).toBe("ab-c-d-e-f");
208
+ function classes(n) {
209
+ return n.className.split(" ").sort().join(" ");
210
+ }
211
+ expect(classes(baz[1])).toBe("baz foo");
212
+ expect(classes(baz[2])).toBe("bar baz foo");
213
+ expect(classes(baz[3])).toBe("bar baz");
214
+ });
215
+ it("draws multiple widgets", async ()=>{
216
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
217
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")),
218
+ plugins: [
219
+ decoPlugin([
220
+ "1-widget",
221
+ "4-widget",
222
+ "7-widget"
223
+ ])
224
+ ]
225
+ });
226
+ const found = view.dom.querySelectorAll("button");
227
+ expect(found).toHaveLength(3);
228
+ expect(found[0].nextSibling.textContent).toBe("foo");
229
+ expect(found[1].nextSibling.textContent).toBe("bar");
230
+ expect(found[2].previousSibling.textContent).toBe("bar");
231
+ });
232
+ it("orders widgets by their side option", async ()=>{
233
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
234
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")),
235
+ plugins: [
236
+ decoPlugin([
237
+ (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react.forwardRef)(function B(param, ref) {
238
+ let { widget , getPos , ...props } = param;
239
+ return /*#__PURE__*/ _react.default.createElement("span", _extends({
240
+ ref: ref
241
+ }, props), "B");
242
+ }), {
243
+ key: "widget-b"
244
+ }),
245
+ (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react.forwardRef)(function A(param, ref) {
246
+ let { widget , getPos , ...props } = param;
247
+ return /*#__PURE__*/ _react.default.createElement("span", _extends({
248
+ ref: ref
249
+ }, props), "A");
250
+ }), {
251
+ side: -100,
252
+ key: "widget-a"
253
+ }),
254
+ (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react.forwardRef)(function C(param, ref) {
255
+ let { widget , getPos , ...props } = param;
256
+ return /*#__PURE__*/ _react.default.createElement("span", _extends({
257
+ ref: ref
258
+ }, props), "C");
259
+ }), {
260
+ side: 2,
261
+ key: "widget-c"
262
+ })
263
+ ])
264
+ ]
265
+ });
266
+ expect(view.dom.textContent).toBe("fooABCbar");
267
+ });
268
+ it("draws a widget in an empty node", async ()=>{
269
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
270
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)()),
271
+ plugins: [
272
+ decoPlugin([
273
+ "1-widget"
274
+ ])
275
+ ]
276
+ });
277
+ expect(view.dom.querySelectorAll("button")).toHaveLength(1);
278
+ });
279
+ it("draws widgets on node boundaries", async ()=>{
280
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
281
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))),
282
+ plugins: [
283
+ decoPlugin([
284
+ "4-widget"
285
+ ])
286
+ ]
287
+ });
288
+ expect(view.dom.querySelectorAll("button")).toHaveLength(1);
289
+ });
290
+ it("draws decorations from multiple plugins", async ()=>{
291
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
292
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))),
293
+ plugins: [
294
+ decoPlugin([
295
+ "2-widget"
296
+ ]),
297
+ decoPlugin([
298
+ "6-widget"
299
+ ])
300
+ ]
301
+ });
302
+ expect(view.dom.querySelectorAll("button")).toHaveLength(2);
303
+ });
304
+ it("calls widget destroy methods", async ()=>{
305
+ let destroyed = false;
306
+ const DestroyableWidget = /*#__PURE__*/ (0, _react.forwardRef)(function DestroyableWidget(param, ref) {
307
+ let { widget , getPos , ...props } = param;
308
+ (0, _react.useEffect)(()=>{
309
+ destroyed = true;
310
+ });
311
+ return /*#__PURE__*/ _react.default.createElement("button", _extends({
312
+ ref: ref
313
+ }, props));
314
+ });
315
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
316
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abc")),
317
+ plugins: [
318
+ decoPlugin([
319
+ (0, _reactWidgetTypeJs.widget)(2, DestroyableWidget, {
320
+ key: "destroyable-widget"
321
+ })
322
+ ])
323
+ ]
324
+ });
325
+ view.dispatch(view.state.tr.delete(1, 4));
326
+ expect(destroyed).toBeTruthy();
327
+ });
328
+ it("draws inline decorations spanning multiple parents", async ()=>{
329
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
330
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("long first ", (0, _prosemirrorTestBuilder.em)("p"), "aragraph"), (0, _prosemirrorTestBuilder.p)("two")),
331
+ plugins: [
332
+ decoPlugin([
333
+ "7-25-foo"
334
+ ])
335
+ ]
336
+ });
337
+ const foos = view.dom.querySelectorAll(".foo");
338
+ expect(foos).toHaveLength(4);
339
+ expect(foos[0].textContent).toBe("irst ");
340
+ expect(foos[1].textContent).toBe("p");
341
+ expect(foos[2].textContent).toBe("aragraph");
342
+ expect(foos[3].textContent).toBe("tw");
343
+ });
344
+ it("draws inline decorations across empty paragraphs", async ()=>{
345
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
346
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("first"), (0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)("second")),
347
+ plugins: [
348
+ decoPlugin([
349
+ "3-12-foo"
350
+ ])
351
+ ]
352
+ });
353
+ const foos = view.dom.querySelectorAll(".foo");
354
+ expect(foos).toHaveLength(2);
355
+ expect(foos[0].textContent).toBe("rst");
356
+ expect(foos[1].textContent).toBe("se");
357
+ });
358
+ it("can handle inline decorations ending at the start or end of a node", async ()=>{
359
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
360
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)(), (0, _prosemirrorTestBuilder.p)()),
361
+ plugins: [
362
+ decoPlugin([
363
+ "1-3-foo"
364
+ ])
365
+ ]
366
+ });
367
+ expect(view.dom.querySelector(".foo")).toBeNull();
368
+ });
369
+ it("can draw decorations with multiple classes", async ()=>{
370
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
371
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
372
+ plugins: [
373
+ decoPlugin([
374
+ "1-4-foo bar"
375
+ ])
376
+ ]
377
+ });
378
+ expect(view.dom.querySelectorAll(".foo")).toHaveLength(1);
379
+ expect(view.dom.querySelectorAll(".bar")).toHaveLength(1);
380
+ });
381
+ it("supports overlapping inline decorations", async ()=>{
382
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
383
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")),
384
+ plugins: [
385
+ decoPlugin([
386
+ "1-3-foo",
387
+ "2-5-bar"
388
+ ])
389
+ ]
390
+ });
391
+ const foos = view.dom.querySelectorAll(".foo");
392
+ const bars = view.dom.querySelectorAll(".bar");
393
+ expect(foos).toHaveLength(2);
394
+ expect(bars).toHaveLength(2);
395
+ expect(foos[0].textContent).toBe("f");
396
+ expect(foos[1].textContent).toBe("o");
397
+ expect(bars[0].textContent).toBe("o");
398
+ expect(bars[1].textContent).toBe("ob");
399
+ });
400
+ it("doesn't redraw when irrelevant decorations change", async ()=>{
401
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
402
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("baz")),
403
+ plugins: [
404
+ decoPlugin([
405
+ "7-8-foo"
406
+ ])
407
+ ]
408
+ });
409
+ const para2 = view.dom.lastChild;
410
+ updateDeco(view, [
411
+ make("2-3-bar")
412
+ ]);
413
+ expect(view.dom.lastChild).toBe(para2);
414
+ expect(view.dom.querySelector(".bar")).not.toBeNull();
415
+ });
416
+ it("doesn't redraw when irrelevant content changes", async ()=>{
417
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
418
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("baz")),
419
+ plugins: [
420
+ decoPlugin([
421
+ "7-8-foo"
422
+ ])
423
+ ]
424
+ });
425
+ const para2 = view.dom.lastChild;
426
+ view.dispatch(view.state.tr.delete(2, 3));
427
+ view.dispatch(view.state.tr.delete(2, 3));
428
+ expect(view.dom.lastChild).toBe(para2);
429
+ });
430
+ it("can add a widget on a node boundary", async ()=>{
431
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
432
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))),
433
+ plugins: [
434
+ decoPlugin([])
435
+ ]
436
+ });
437
+ updateDeco(view, [
438
+ make("4-widget")
439
+ ]);
440
+ expect(view.dom.querySelectorAll("button")).toHaveLength(1);
441
+ });
442
+ it("can remove a widget on a node boundary", async ()=>{
443
+ const dec = make("4-widget");
444
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
445
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo", (0, _prosemirrorTestBuilder.em)("bar"))),
446
+ plugins: [
447
+ decoPlugin([
448
+ dec
449
+ ])
450
+ ]
451
+ });
452
+ updateDeco(view, null, [
453
+ dec
454
+ ]);
455
+ expect(view.dom.querySelector("button")).toBeNull();
456
+ });
457
+ it("can remove the class from a text node", async ()=>{
458
+ const dec = make("1-4-foo");
459
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
460
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abc")),
461
+ plugins: [
462
+ decoPlugin([
463
+ dec
464
+ ])
465
+ ]
466
+ });
467
+ expect(view.dom.querySelector(".foo")).not.toBeNull();
468
+ updateDeco(view, null, [
469
+ dec
470
+ ]);
471
+ expect(view.dom.querySelector(".foo")).toBeNull();
472
+ });
473
+ it("can remove the class from part of a text node", async ()=>{
474
+ const dec = make("2-4-foo");
475
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
476
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcd")),
477
+ plugins: [
478
+ decoPlugin([
479
+ dec
480
+ ])
481
+ ]
482
+ });
483
+ expect(view.dom.querySelector(".foo")).not.toBeNull();
484
+ updateDeco(view, null, [
485
+ dec
486
+ ]);
487
+ expect(view.dom.querySelector(".foo")).toBeNull();
488
+ expect(view.dom.firstChild.innerHTML).toBe("abcd");
489
+ });
490
+ it("can change the class for part of a text node", async ()=>{
491
+ const dec = make("2-4-foo");
492
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
493
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abcd")),
494
+ plugins: [
495
+ decoPlugin([
496
+ dec
497
+ ])
498
+ ]
499
+ });
500
+ expect(view.dom.querySelector(".foo")).not.toBeNull();
501
+ updateDeco(view, [
502
+ make("2-4-bar")
503
+ ], [
504
+ dec
505
+ ]);
506
+ expect(view.dom.querySelector(".foo")).toBeNull();
507
+ expect(view.dom.querySelector(".bar")).not.toBeNull();
508
+ });
509
+ it("draws a widget added in the middle of a text node", async ()=>{
510
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
511
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
512
+ plugins: [
513
+ decoPlugin([])
514
+ ]
515
+ });
516
+ updateDeco(view, [
517
+ make("3-widget")
518
+ ]);
519
+ expect(view.dom.firstChild.textContent).toBe("foωo");
520
+ });
521
+ it("can update a text node around a widget", async ()=>{
522
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
523
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("bar")),
524
+ plugins: [
525
+ decoPlugin([
526
+ "3-widget"
527
+ ])
528
+ ]
529
+ });
530
+ view.dispatch(view.state.tr.delete(1, 2));
531
+ expect(view.dom.querySelectorAll("button")).toHaveLength(1);
532
+ expect(view.dom.firstChild.textContent).toBe("aωr");
533
+ });
534
+ it("can update a text node with an inline decoration", async ()=>{
535
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
536
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("bar")),
537
+ plugins: [
538
+ decoPlugin([
539
+ "1-3-foo"
540
+ ])
541
+ ]
542
+ });
543
+ view.dispatch(view.state.tr.delete(1, 2));
544
+ const foo = view.dom.querySelector(".foo");
545
+ expect(foo).not.toBeNull();
546
+ expect(foo.textContent).toBe("a");
547
+ expect(foo.nextSibling.textContent).toBe("r");
548
+ });
549
+ it("correctly redraws a partially decorated node when a widget is added", async ()=>{
550
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
551
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one", (0, _prosemirrorTestBuilder.em)("two"))),
552
+ plugins: [
553
+ decoPlugin([
554
+ "1-6-foo"
555
+ ])
556
+ ]
557
+ });
558
+ updateDeco(view, [
559
+ make("6-widget")
560
+ ]);
561
+ const foos = view.dom.querySelectorAll(".foo");
562
+ expect(foos).toHaveLength(2);
563
+ expect(foos[0].textContent).toBe("one");
564
+ expect(foos[1].textContent).toBe("tw");
565
+ });
566
+ it("correctly redraws when skipping split text node", async ()=>{
567
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
568
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
569
+ plugins: [
570
+ decoPlugin([
571
+ "3-widget",
572
+ "3-4-foo"
573
+ ])
574
+ ]
575
+ });
576
+ updateDeco(view, [
577
+ make("4-widget")
578
+ ]);
579
+ expect(view.dom.querySelectorAll("button")).toHaveLength(2);
580
+ });
581
+ it("drops removed node decorations from the view", async ()=>{
582
+ const deco = _prosemirrorView.Decoration.node(1, 6, {
583
+ class: "cls"
584
+ });
585
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
586
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.blockquote)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.p)("bar"))),
587
+ plugins: [
588
+ decoPlugin([
589
+ deco
590
+ ])
591
+ ]
592
+ });
593
+ updateDeco(view, null, [
594
+ deco
595
+ ]);
596
+ expect(view.dom.querySelector(".cls")).toBeNull();
597
+ });
598
+ it("can update a node's attributes without replacing the node", async ()=>{
599
+ const deco = _prosemirrorView.Decoration.node(0, 5, {
600
+ title: "title",
601
+ class: "foo"
602
+ });
603
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
604
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
605
+ plugins: [
606
+ decoPlugin([
607
+ deco
608
+ ])
609
+ ]
610
+ });
611
+ const para = view.dom.querySelector("p");
612
+ updateDeco(view, [
613
+ _prosemirrorView.Decoration.node(0, 5, {
614
+ class: "foo bar"
615
+ })
616
+ ], [
617
+ deco
618
+ ]);
619
+ expect(view.dom.querySelector("p")).toBe(para);
620
+ expect(para.className).toBe("foo bar");
621
+ expect(para.title).toBeFalsy();
622
+ });
623
+ it("can add and remove CSS custom properties from a node", async ()=>{
624
+ const deco = _prosemirrorView.Decoration.node(0, 5, {
625
+ style: "--my-custom-property:36px"
626
+ });
627
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
628
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
629
+ plugins: [
630
+ decoPlugin([
631
+ deco
632
+ ])
633
+ ]
634
+ });
635
+ expect(view.dom.querySelector("p").style.getPropertyValue("--my-custom-property")).toBe("36px");
636
+ updateDeco(view, null, [
637
+ deco
638
+ ]);
639
+ expect(view.dom.querySelector("p").style.getPropertyValue("--my-custom-property")).toBe("");
640
+ });
641
+ it("updates decorated nodes even if a widget is added before them", async ()=>{
642
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
643
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("a"), (0, _prosemirrorTestBuilder.p)("b")),
644
+ plugins: [
645
+ decoPlugin([])
646
+ ]
647
+ });
648
+ const lastP = view.dom.querySelectorAll("p")[1];
649
+ updateDeco(view, [
650
+ make("3-widget"),
651
+ _prosemirrorView.Decoration.node(3, 6, {
652
+ style: "color: red"
653
+ })
654
+ ]);
655
+ expect(lastP.style.color).toBe("red");
656
+ });
657
+ it("doesn't redraw nodes when a widget before them is replaced", async ()=>{
658
+ const w0 = make("3-widget");
659
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
660
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.h1)("a"), (0, _prosemirrorTestBuilder.p)("b")),
661
+ plugins: [
662
+ decoPlugin([
663
+ w0
664
+ ])
665
+ ]
666
+ });
667
+ const initialP = view.dom.querySelector("p");
668
+ view.dispatch(view.state.tr.setMeta("updateDecorations", {
669
+ add: [
670
+ make("3-widget")
671
+ ],
672
+ remove: [
673
+ w0
674
+ ]
675
+ }).insertText("c", 5));
676
+ expect(view.dom.querySelector("p")).toBe(initialP);
677
+ });
678
+ it("can add and remove inline style", async ()=>{
679
+ const deco = _prosemirrorView.Decoration.inline(1, 6, {
680
+ style: "color: rgba(0,10,200,.4); text-decoration: underline"
681
+ });
682
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
683
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("al", (0, _prosemirrorTestBuilder.img)(), "lo")),
684
+ plugins: [
685
+ decoPlugin([
686
+ deco
687
+ ])
688
+ ]
689
+ });
690
+ expect(view.dom.querySelector("img").style.color).toMatch(/rgba/);
691
+ expect(view.dom.querySelector("img").previousSibling.style.textDecoration).toBe("underline");
692
+ updateDeco(view, null, [
693
+ deco
694
+ ]);
695
+ expect(view.dom.querySelector("img").style.color).toBe("");
696
+ expect(view.dom.querySelector("img").style.textDecoration).toBe("");
697
+ });
698
+ it("passes decorations to a node view", async ()=>{
699
+ let current = "";
700
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
701
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo"), (0, _prosemirrorTestBuilder.hr)()),
702
+ plugins: [
703
+ decoPlugin([])
704
+ ],
705
+ nodeViews: {
706
+ horizontal_rule: /*#__PURE__*/ (0, _react.forwardRef)(function HR(param, ref) {
707
+ let { nodeProps , children , ...props } = param;
708
+ current = nodeProps.decorations.map((d)=>d.spec.name).join();
709
+ return /*#__PURE__*/ _react.default.createElement("hr", _extends({
710
+ ref: ref
711
+ }, props));
712
+ })
713
+ }
714
+ });
715
+ const a = _prosemirrorView.Decoration.node(5, 6, {}, {
716
+ name: "a"
717
+ });
718
+ updateDeco(view, [
719
+ a
720
+ ], []);
721
+ expect(current).toBe("a");
722
+ updateDeco(view, [
723
+ _prosemirrorView.Decoration.node(5, 6, {}, {
724
+ name: "b"
725
+ }),
726
+ _prosemirrorView.Decoration.node(5, 6, {}, {
727
+ name: "c"
728
+ })
729
+ ], [
730
+ a
731
+ ]);
732
+ expect(current).toBe("b,c");
733
+ });
734
+ it("draws the specified marks around a widget", async ()=>{
735
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
736
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foobar")),
737
+ plugins: [
738
+ decoPlugin([
739
+ (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react.forwardRef)(function Img(param, ref) {
740
+ let { widget , getPos , ...props } = param;
741
+ return /*#__PURE__*/ _react.default.createElement("img", _extends({}, props, {
742
+ ref: ref
743
+ }));
744
+ }), {
745
+ marks: [
746
+ _prosemirrorTestBuilder.schema.mark("em")
747
+ ],
748
+ key: "img-widget"
749
+ })
750
+ ])
751
+ ]
752
+ });
753
+ expect(view.dom.querySelector("em img")).not.toBeNull();
754
+ });
755
+ it("draws widgets inside the marks for their side", async ()=>{
756
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
757
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)((0, _prosemirrorTestBuilder.em)("foo"), (0, _prosemirrorTestBuilder.strong)("bar"))),
758
+ plugins: [
759
+ decoPlugin([
760
+ (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react.forwardRef)(function Img(param, ref) {
761
+ let { widget , getPos , ...props } = param;
762
+ return /*#__PURE__*/ _react.default.createElement("img", _extends({}, props, {
763
+ ref: ref
764
+ }));
765
+ }), {
766
+ side: -1,
767
+ key: "img-widget"
768
+ })
769
+ ]),
770
+ decoPlugin([
771
+ (0, _reactWidgetTypeJs.widget)(4, /*#__PURE__*/ (0, _react.forwardRef)(function BR(param, ref) {
772
+ let { widget , getPos , ...props } = param;
773
+ return /*#__PURE__*/ _react.default.createElement("br", _extends({}, props, {
774
+ ref: ref
775
+ }));
776
+ }), {
777
+ key: "br-widget"
778
+ })
779
+ ]),
780
+ decoPlugin([
781
+ (0, _reactWidgetTypeJs.widget)(7, /*#__PURE__*/ (0, _react.forwardRef)(function Span(param, ref) {
782
+ let { widget , getPos , ...props } = param;
783
+ return /*#__PURE__*/ _react.default.createElement("span", _extends({}, props, {
784
+ ref: ref
785
+ }));
786
+ }), {
787
+ side: 1,
788
+ key: "span-widget"
789
+ })
790
+ ])
791
+ ]
792
+ });
793
+ expect(view.dom.querySelector("em img")).not.toBeNull();
794
+ expect(view.dom.querySelector("strong img")).toBeNull();
795
+ expect(view.dom.querySelector("strong br")).not.toBeNull();
796
+ expect(view.dom.querySelector("em br")).toBeNull();
797
+ expect(view.dom.querySelector("strong span")).toBeNull();
798
+ });
799
+ it("draws decorations inside node views", async ()=>{
800
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
801
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("foo")),
802
+ nodeViews: {
803
+ paragraph: /*#__PURE__*/ (0, _react.forwardRef)(function Paragraph(param, ref) {
804
+ let { nodeProps , children , ...props } = param;
805
+ return /*#__PURE__*/ _react.default.createElement("p", _extends({
806
+ ref: ref
807
+ }, props), children);
808
+ })
809
+ },
810
+ plugins: [
811
+ decoPlugin([
812
+ (0, _reactWidgetTypeJs.widget)(2, /*#__PURE__*/ (0, _react.forwardRef)(function Img(param, ref) {
813
+ let { widget , getPos , ...props } = param;
814
+ return /*#__PURE__*/ _react.default.createElement("img", _extends({}, props, {
815
+ ref: ref
816
+ }));
817
+ }), {
818
+ key: "img-widget"
819
+ })
820
+ ])
821
+ ]
822
+ });
823
+ expect(view.dom.querySelector("img")).not.toBeNull();
824
+ });
825
+ it("can delay widget drawing to render time", async ()=>{
826
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
827
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")),
828
+ decorations (state) {
829
+ return _prosemirrorView.DecorationSet.create(state.doc, [
830
+ (0, _reactWidgetTypeJs.widget)(3, /*#__PURE__*/ (0, _react.forwardRef)(function Span(param, ref) {
831
+ let { widget , getPos , ...props } = param;
832
+ (0, _useEditorEffectJs.useEditorEffect)((view)=>{
833
+ expect(view.state).toBe(state);
834
+ });
835
+ return /*#__PURE__*/ _react.default.createElement("span", _extends({}, props, {
836
+ ref: ref
837
+ }), "!");
838
+ }), {
839
+ key: "span-widget"
840
+ })
841
+ ]);
842
+ }
843
+ });
844
+ expect(view.dom.textContent).toBe("hi!");
845
+ });
846
+ it("supports widgets querying their own position", async ()=>{
847
+ (0, _editorViewTestHelpersJs.tempEditor)({
848
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")),
849
+ decorations (state) {
850
+ return _prosemirrorView.DecorationSet.create(state.doc, [
851
+ (0, _reactWidgetTypeJs.widget)(3, /*#__PURE__*/ (0, _react.forwardRef)(function Widget(param, ref) {
852
+ let { widget , getPos , ...props } = param;
853
+ expect(getPos()).toBe(3);
854
+ return /*#__PURE__*/ _react.default.createElement("button", _extends({
855
+ ref: ref
856
+ }, props), "ω");
857
+ }), {
858
+ key: "button-widget"
859
+ })
860
+ ]);
861
+ }
862
+ });
863
+ });
864
+ it("doesn't redraw widgets with matching keys", async ()=>{
865
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
866
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")),
867
+ decorations (state) {
868
+ return _prosemirrorView.DecorationSet.create(state.doc, [
869
+ (0, _reactWidgetTypeJs.widget)(2, Widget, {
870
+ key: "myButton"
871
+ })
872
+ ]);
873
+ }
874
+ });
875
+ const widgetDOM = view.dom.querySelector("button");
876
+ view.dispatch(view.state.tr.insertText("!", 2, 2));
877
+ expect(view.dom.querySelector("button")).toBe(widgetDOM);
878
+ });
879
+ it("doesn't redraw widgets with identical specs", async ()=>{
880
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
881
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("hi")),
882
+ decorations (state) {
883
+ return _prosemirrorView.DecorationSet.create(state.doc, [
884
+ (0, _reactWidgetTypeJs.widget)(2, Widget, {
885
+ side: 1,
886
+ key: "widget"
887
+ })
888
+ ]);
889
+ }
890
+ });
891
+ const widgetDOM = view.dom.querySelector("button");
892
+ view.dispatch(view.state.tr.insertText("!", 2, 2));
893
+ expect(view.dom.querySelector("button")).toBe(widgetDOM);
894
+ });
895
+ it("doesn't get confused by split text nodes", async ()=>{
896
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
897
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("abab")),
898
+ decorations (state) {
899
+ return state.selection.from <= 1 ? null : _prosemirrorView.DecorationSet.create(view.state.doc, [
900
+ _prosemirrorView.Decoration.inline(1, 2, {
901
+ class: "foo"
902
+ }),
903
+ _prosemirrorView.Decoration.inline(3, 4, {
904
+ class: "foo"
905
+ })
906
+ ]);
907
+ }
908
+ });
909
+ view.dispatch(view.state.tr.setSelection(_prosemirrorState.TextSelection.create(view.state.doc, 5)));
910
+ expect(view.dom.textContent).toBe("abab");
911
+ });
912
+ it("only draws inline decorations on the innermost level", async ()=>{
913
+ const s = new _prosemirrorModel.Schema({
914
+ nodes: {
915
+ doc: {
916
+ content: "(text | thing)*"
917
+ },
918
+ text: {},
919
+ thing: {
920
+ inline: true,
921
+ content: "text*",
922
+ toDOM: ()=>[
923
+ "strong",
924
+ 0
925
+ ],
926
+ parseDOM: [
927
+ {
928
+ tag: "strong"
929
+ }
930
+ ]
931
+ }
932
+ }
933
+ });
934
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
935
+ doc: s.node("doc", null, [
936
+ s.text("abc"),
937
+ s.node("thing", null, [
938
+ s.text("def")
939
+ ]),
940
+ s.text("ghi")
941
+ ]),
942
+ decorations: (s)=>_prosemirrorView.DecorationSet.create(s.doc, [
943
+ _prosemirrorView.Decoration.inline(1, 10, {
944
+ class: "dec"
945
+ })
946
+ ])
947
+ });
948
+ const styled = view.dom.querySelectorAll(".dec");
949
+ expect(styled).toHaveLength(3);
950
+ expect(Array.prototype.map.call(styled, (n)=>n.textContent).join()).toBe("bc,def,gh");
951
+ expect(styled[1].parentNode.nodeName).toBe("STRONG");
952
+ });
953
+ it("can handle nodeName decoration overlapping with classes", async ()=>{
954
+ const { view } = (0, _editorViewTestHelpersJs.tempEditor)({
955
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")),
956
+ plugins: [
957
+ decoPlugin([
958
+ _prosemirrorView.Decoration.inline(2, 13, {
959
+ class: "foo"
960
+ }),
961
+ _prosemirrorView.Decoration.inline(5, 8, {
962
+ nodeName: "em"
963
+ })
964
+ ])
965
+ ]
966
+ });
967
+ expect(view.dom.firstChild.innerHTML).toBe('o<span class="foo">ne </span><em class="foo">two</em><span class="foo"> thre</span>e');
968
+ });
969
+ it("can handle combining decorations from parent editors in child editors", async ()=>{
970
+ let decosFromFirstEditor;
971
+ let { view } = (0, _editorViewTestHelpersJs.tempEditor)({
972
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")),
973
+ plugins: [
974
+ decoPlugin([
975
+ _prosemirrorView.Decoration.inline(2, 13, {
976
+ class: "foo"
977
+ })
978
+ ]),
979
+ decoPlugin([
980
+ _prosemirrorView.Decoration.inline(2, 13, {
981
+ class: "bar"
982
+ })
983
+ ])
984
+ ],
985
+ nodeViews: {
986
+ paragraph: /*#__PURE__*/ (0, _react.forwardRef)(function Paragraph(param, ref) {
987
+ let { nodeProps , children , ...props } = param;
988
+ decosFromFirstEditor = nodeProps.innerDecorations;
989
+ return /*#__PURE__*/ _react.default.createElement("p", _extends({
990
+ ref: ref
991
+ }, props), children);
992
+ })
993
+ }
994
+ });
995
+ ({ view } = (0, _editorViewTestHelpersJs.tempEditor)({
996
+ doc: (0, _prosemirrorTestBuilder.doc)((0, _prosemirrorTestBuilder.p)("one two three")),
997
+ plugins: [
998
+ decoPlugin([
999
+ _prosemirrorView.Decoration.inline(1, 12, {
1000
+ class: "baz"
1001
+ })
1002
+ ])
1003
+ ],
1004
+ decorations: ()=>decosFromFirstEditor
1005
+ }));
1006
+ expect(view.dom.querySelectorAll(".foo")).toHaveLength(1);
1007
+ expect(view.dom.querySelectorAll(".bar")).toHaveLength(1);
1008
+ expect(view.dom.querySelectorAll(".baz")).toHaveLength(1);
1009
+ });
1010
+ });