@thomasfosterau/effect-richtext 0.0.0-stage → 0.1.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 (176) hide show
  1. package/LICENSE +48 -0
  2. package/README.md +118 -2
  3. package/dist/_virtual/_rolldown/runtime.js +12 -0
  4. package/dist/commands/commands.d.ts +323 -0
  5. package/dist/commands/commands.js +722 -0
  6. package/dist/commands/internal.js +43 -0
  7. package/dist/commands/keymaps.d.ts +46 -0
  8. package/dist/commands/keymaps.js +64 -0
  9. package/dist/commands.d.ts +3 -0
  10. package/dist/commands.js +3 -0
  11. package/dist/compat/commands.d.ts +250 -0
  12. package/dist/compat/commands.js +275 -0
  13. package/dist/compat/internal/core.d.ts +20 -0
  14. package/dist/compat/internal/core.js +148 -0
  15. package/dist/compat/internal/props.js +82 -0
  16. package/dist/compat/keymap.d.ts +21 -0
  17. package/dist/compat/keymap.js +38 -0
  18. package/dist/compat/model.d.ts +893 -0
  19. package/dist/compat/model.js +1212 -0
  20. package/dist/compat/orderedmap.d.ts +74 -0
  21. package/dist/compat/orderedmap.js +124 -0
  22. package/dist/compat/schema-basic.d.ts +38 -0
  23. package/dist/compat/schema-basic.js +238 -0
  24. package/dist/compat/schema-list.d.ts +81 -0
  25. package/dist/compat/schema-list.js +156 -0
  26. package/dist/compat/state.d.ts +415 -0
  27. package/dist/compat/state.js +689 -0
  28. package/dist/compat/test-builder.d.ts +98 -0
  29. package/dist/compat/test-builder.js +197 -0
  30. package/dist/compat/transform.d.ts +458 -0
  31. package/dist/compat/transform.js +803 -0
  32. package/dist/compat/view.d.ts +411 -0
  33. package/dist/compat/view.js +409 -0
  34. package/dist/dropcursor.d.ts +46 -0
  35. package/dist/dropcursor.js +176 -0
  36. package/dist/extensions/defaults.d.ts +716 -0
  37. package/dist/extensions/defaults.js +209 -0
  38. package/dist/extensions/editor.d.ts +246 -0
  39. package/dist/extensions/editor.js +271 -0
  40. package/dist/extensions/extension.d.ts +375 -0
  41. package/dist/extensions/extension.js +233 -0
  42. package/dist/extensions.d.ts +4 -0
  43. package/dist/extensions.js +4 -0
  44. package/dist/gapcursor.d.ts +66 -0
  45. package/dist/gapcursor.js +273 -0
  46. package/dist/history.d.ts +178 -0
  47. package/dist/history.js +412 -0
  48. package/dist/html.d.ts +158 -0
  49. package/dist/html.js +164 -0
  50. package/dist/inputrules.d.ts +271 -0
  51. package/dist/inputrules.js +321 -0
  52. package/dist/internal/attempt.js +15 -0
  53. package/dist/internal/json.js +29 -0
  54. package/dist/keymap/keymap.d.ts +130 -0
  55. package/dist/keymap/keymap.js +159 -0
  56. package/dist/keymap.d.ts +2 -0
  57. package/dist/keymap.js +1 -0
  58. package/dist/markdown/errors.d.ts +23 -0
  59. package/dist/markdown/errors.js +26 -0
  60. package/dist/markdown/from_markdown.d.ts +185 -0
  61. package/dist/markdown/from_markdown.js +266 -0
  62. package/dist/markdown/schema.d.ts +522 -0
  63. package/dist/markdown/schema.js +292 -0
  64. package/dist/markdown/to_markdown.d.ts +251 -0
  65. package/dist/markdown/to_markdown.js +413 -0
  66. package/dist/markdown.d.ts +5 -0
  67. package/dist/markdown.js +5 -0
  68. package/dist/model/attrsCodec.js +48 -0
  69. package/dist/model/comparedeep.js +17 -0
  70. package/dist/model/content.d.ts +232 -0
  71. package/dist/model/content.js +630 -0
  72. package/dist/model/diff.js +66 -0
  73. package/dist/model/dom.d.ts +3 -0
  74. package/dist/model/errors.d.ts +90 -0
  75. package/dist/model/errors.js +76 -0
  76. package/dist/model/fragment.d.ts +131 -0
  77. package/dist/model/fragment.js +262 -0
  78. package/dist/model/from_dom.d.ts +299 -0
  79. package/dist/model/from_dom.js +618 -0
  80. package/dist/model/json.d.ts +37 -0
  81. package/dist/model/json.js +126 -0
  82. package/dist/model/mark.d.ts +73 -0
  83. package/dist/model/mark.js +121 -0
  84. package/dist/model/node.d.ts +267 -0
  85. package/dist/model/node.js +434 -0
  86. package/dist/model/replace.d.ts +78 -0
  87. package/dist/model/replace.js +207 -0
  88. package/dist/model/resolvedpos.d.ts +196 -0
  89. package/dist/model/resolvedpos.js +305 -0
  90. package/dist/model/schema.d.ts +740 -0
  91. package/dist/model/schema.js +451 -0
  92. package/dist/model/to_dom.d.ts +169 -0
  93. package/dist/model/to_dom.js +238 -0
  94. package/dist/model.d.ts +12 -0
  95. package/dist/model.js +12 -0
  96. package/dist/placeholder.d.ts +53 -0
  97. package/dist/placeholder.js +79 -0
  98. package/dist/reactive/observer.d.ts +54 -0
  99. package/dist/reactive/observer.js +61 -0
  100. package/dist/reactive/selectors.d.ts +22 -0
  101. package/dist/reactive/selectors.js +61 -0
  102. package/dist/reactive/stateref.d.ts +72 -0
  103. package/dist/reactive/stateref.js +71 -0
  104. package/dist/reactive/streams.d.ts +83 -0
  105. package/dist/reactive/streams.js +85 -0
  106. package/dist/reactive.d.ts +16 -0
  107. package/dist/reactive.js +26 -0
  108. package/dist/schema-basic.d.ts +448 -0
  109. package/dist/schema-basic.js +269 -0
  110. package/dist/schema-list/commands.d.ts +66 -0
  111. package/dist/schema-list/commands.js +203 -0
  112. package/dist/schema-list.d.ts +92 -0
  113. package/dist/schema-list.js +100 -0
  114. package/dist/state/errors.d.ts +39 -0
  115. package/dist/state/errors.js +32 -0
  116. package/dist/state/plugin.d.ts +232 -0
  117. package/dist/state/plugin.js +82 -0
  118. package/dist/state/selection.d.ts +297 -0
  119. package/dist/state/selection.js +486 -0
  120. package/dist/state/state.d.ts +212 -0
  121. package/dist/state/state.js +489 -0
  122. package/dist/state/transaction.d.ts +145 -0
  123. package/dist/state/transaction.js +195 -0
  124. package/dist/state.d.ts +6 -0
  125. package/dist/state.js +6 -0
  126. package/dist/test-builder.d.ts +3582 -0
  127. package/dist/test-builder.js +239 -0
  128. package/dist/transform/attr_step.d.ts +60 -0
  129. package/dist/transform/attr_step.js +105 -0
  130. package/dist/transform/errors.d.ts +50 -0
  131. package/dist/transform/errors.js +35 -0
  132. package/dist/transform/map.d.ts +182 -0
  133. package/dist/transform/map.js +280 -0
  134. package/dist/transform/mark.js +98 -0
  135. package/dist/transform/mark_set_step.js +69 -0
  136. package/dist/transform/mark_step.d.ts +113 -0
  137. package/dist/transform/mark_step.js +225 -0
  138. package/dist/transform/replace.d.ts +18 -0
  139. package/dist/transform/replace.js +381 -0
  140. package/dist/transform/replace_step.d.ts +109 -0
  141. package/dist/transform/replace_step.js +175 -0
  142. package/dist/transform/step.d.ts +157 -0
  143. package/dist/transform/step.js +168 -0
  144. package/dist/transform/structure.d.ts +89 -0
  145. package/dist/transform/structure.js +350 -0
  146. package/dist/transform/transform.d.ts +248 -0
  147. package/dist/transform/transform.js +373 -0
  148. package/dist/transform.d.ts +10 -0
  149. package/dist/transform.js +10 -0
  150. package/dist/view/browser.js +39 -0
  151. package/dist/view/capturekeys.js +282 -0
  152. package/dist/view/clipboard.d.ts +8 -0
  153. package/dist/view/clipboard.js +245 -0
  154. package/dist/view/decoration.d.ts +339 -0
  155. package/dist/view/decoration.js +566 -0
  156. package/dist/view/dom.d.ts +18 -0
  157. package/dist/view/dom.js +140 -0
  158. package/dist/view/domchange.js +295 -0
  159. package/dist/view/domcoords.d.ts +22 -0
  160. package/dist/view/domcoords.js +448 -0
  161. package/dist/view/domobserver.d.ts +47 -0
  162. package/dist/view/domobserver.js +328 -0
  163. package/dist/view/errors.d.ts +18 -0
  164. package/dist/view/errors.js +21 -0
  165. package/dist/view/input.d.ts +58 -0
  166. package/dist/view/input.js +704 -0
  167. package/dist/view/selection.js +198 -0
  168. package/dist/view/view.d.ts +699 -0
  169. package/dist/view/view.js +623 -0
  170. package/dist/view/viewdesc.d.ts +236 -0
  171. package/dist/view/viewdesc.js +1205 -0
  172. package/dist/view-css.d.ts +43 -0
  173. package/dist/view-css.js +124 -0
  174. package/dist/view.d.ts +6 -0
  175. package/dist/view.js +4 -0
  176. package/package.json +206 -3
@@ -0,0 +1,1205 @@
1
+ import { DOMSerializer } from "../model/to_dom.js";
2
+ import { Fragment } from "../model/fragment.js";
3
+ import { Mark } from "../model/mark.js";
4
+ import { TextSelection } from "../state/selection.js";
5
+ import { chrome, gecko, ios, safari } from "./browser.js";
6
+ import { domIndex, isElt, isEquivalentPosition } from "./dom.js";
7
+ import * as Arr from "effect/Array";
8
+ import * as Order from "effect/Order";
9
+ // src/view/viewdesc.ts
10
+ /**
11
+ * View descriptions, node views and mark views.
12
+ *
13
+ * @since 0.1.0
14
+ */
15
+ const textOf = (node) => node.text;
16
+ const NOT_DIRTY = 0;
17
+ const CHILD_DIRTY = 1;
18
+ const CONTENT_DIRTY = 2;
19
+ const NODE_DIRTY = 3;
20
+ /** @internal */
21
+ var ViewDesc = class {
22
+ constructor(parent, children, dom, contentDOM) {
23
+ this.parent = parent;
24
+ this.children = children;
25
+ this.dom = dom;
26
+ this.contentDOM = contentDOM;
27
+ this.dirty = NOT_DIRTY;
28
+ dom.pmViewDesc = this;
29
+ }
30
+ matchesWidget(_widget) {
31
+ return false;
32
+ }
33
+ matchesMark(_mark) {
34
+ return false;
35
+ }
36
+ matchesNode(_node, _outerDeco, _innerDeco) {
37
+ return false;
38
+ }
39
+ matchesHack(_nodeName) {
40
+ return false;
41
+ }
42
+ parseRule(_addedNodes) {
43
+ return null;
44
+ }
45
+ stopEvent(_event) {
46
+ return false;
47
+ }
48
+ get size() {
49
+ let size = 0;
50
+ for (let i = 0; i < this.children.length; i++) size += this.children[i].size;
51
+ return size;
52
+ }
53
+ get border() {
54
+ return 0;
55
+ }
56
+ destroy() {
57
+ this.parent = void 0;
58
+ if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = void 0;
59
+ for (let i = 0; i < this.children.length; i++) this.children[i].destroy();
60
+ }
61
+ posBeforeChild(child) {
62
+ for (let i = 0, pos = this.posAtStart;; i++) {
63
+ const cur = this.children[i];
64
+ if (cur == child) return pos;
65
+ pos += cur.size;
66
+ }
67
+ }
68
+ get posBefore() {
69
+ return this.parent.posBeforeChild(this);
70
+ }
71
+ get posAtStart() {
72
+ return this.parent ? this.parent.posBeforeChild(this) + this.border : 0;
73
+ }
74
+ get posAfter() {
75
+ return this.posBefore + this.size;
76
+ }
77
+ get posAtEnd() {
78
+ return this.posAtStart + this.size - 2 * this.border;
79
+ }
80
+ localPosFromDOM(dom, offset, bias) {
81
+ if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {
82
+ if (bias < 0) {
83
+ let domBefore, desc;
84
+ if (dom == this.contentDOM) domBefore = dom.childNodes[offset - 1];
85
+ else {
86
+ while (dom.parentNode != this.contentDOM) dom = dom.parentNode;
87
+ domBefore = dom.previousSibling;
88
+ }
89
+ while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling;
90
+ return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart;
91
+ } else {
92
+ let domAfter, desc;
93
+ if (dom == this.contentDOM) domAfter = dom.childNodes[offset];
94
+ else {
95
+ while (dom.parentNode != this.contentDOM) dom = dom.parentNode;
96
+ domAfter = dom.nextSibling;
97
+ }
98
+ while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling;
99
+ return domAfter ? this.posBeforeChild(desc) : this.posAtEnd;
100
+ }
101
+ }
102
+ let atEnd;
103
+ if (dom == this.dom && this.contentDOM) atEnd = offset > domIndex(this.contentDOM);
104
+ else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
105
+ const rel = dom.compareDocumentPosition(this.contentDOM);
106
+ if (rel & 16) atEnd = offset > Array.from(dom.childNodes).findIndex((n) => n.contains(this.contentDOM));
107
+ else atEnd = !(rel & 4);
108
+ } else if (this.dom.firstChild) {
109
+ if (offset == 0) for (let search = dom;; search = search.parentNode) {
110
+ if (search == this.dom) {
111
+ atEnd = false;
112
+ break;
113
+ }
114
+ if (search.previousSibling) break;
115
+ }
116
+ if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) {
117
+ if (search == this.dom) {
118
+ atEnd = true;
119
+ break;
120
+ }
121
+ if (search.nextSibling) break;
122
+ }
123
+ }
124
+ return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart;
125
+ }
126
+ nearestDesc(dom, onlyNodes = false) {
127
+ for (let first = true, cur = dom; cur; cur = cur.parentNode) {
128
+ const desc = this.getDesc(cur);
129
+ let nodeDOM;
130
+ if (desc && (!onlyNodes || desc.node)) {
131
+ if (first && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) first = false;
132
+ else return desc;
133
+ }
134
+ }
135
+ }
136
+ getDesc(dom) {
137
+ const desc = dom.pmViewDesc;
138
+ for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc;
139
+ }
140
+ posFromDOM(dom, offset, bias) {
141
+ for (let scan = dom; scan; scan = scan.parentNode) {
142
+ const desc = this.getDesc(scan);
143
+ if (desc) return desc.localPosFromDOM(dom, offset, bias);
144
+ }
145
+ return -1;
146
+ }
147
+ descAt(pos) {
148
+ for (let i = 0, offset = 0; i < this.children.length; i++) {
149
+ let child = this.children[i];
150
+ const end = offset + child.size;
151
+ if (offset == pos && end != offset) {
152
+ while (!child.border && child.children.length) for (let i = 0; i < child.children.length; i++) {
153
+ const inner = child.children[i];
154
+ if (inner.size) {
155
+ child = inner;
156
+ break;
157
+ }
158
+ }
159
+ return child;
160
+ }
161
+ if (pos < end) return child.descAt(pos - offset - child.border);
162
+ offset = end;
163
+ }
164
+ }
165
+ domFromPos(pos, side) {
166
+ if (!this.contentDOM) return {
167
+ node: this.dom,
168
+ offset: 0,
169
+ atom: pos + 1
170
+ };
171
+ let i = 0, offset = 0;
172
+ for (let curPos = 0; i < this.children.length; i++) {
173
+ const child = this.children[i], end = curPos + child.size;
174
+ if (end > pos) {
175
+ offset = pos - curPos;
176
+ break;
177
+ }
178
+ curPos = end;
179
+ }
180
+ if (offset) return this.children[i].domFromPos(offset - this.children[i].border, side);
181
+ while (i > 0 && skippableBefore(this.children, i)) i--;
182
+ if (side <= 0) {
183
+ let prev, enter = true;
184
+ for (;; i--, enter = false) {
185
+ prev = i ? this.children[i - 1] : null;
186
+ if (!prev || prev.dom.parentNode == this.contentDOM) break;
187
+ }
188
+ if (prev && side && enter && !prev.border && !prev.domAtom) return prev.domFromPos(prev.size, side);
189
+ return {
190
+ node: this.contentDOM,
191
+ offset: prev ? domIndex(prev.dom) + 1 : 0
192
+ };
193
+ } else {
194
+ let next, enter = true;
195
+ for (;; i++, enter = false) {
196
+ next = i < this.children.length ? this.children[i] : null;
197
+ if (!next || next.dom.parentNode == this.contentDOM) break;
198
+ }
199
+ if (next && enter && !next.border && !next.domAtom) return next.domFromPos(0, side);
200
+ return {
201
+ node: this.contentDOM,
202
+ offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length
203
+ };
204
+ }
205
+ }
206
+ parseRange(from, to, base = 0) {
207
+ if (Arr.isReadonlyArrayEmpty(this.children)) return {
208
+ node: this.contentDOM,
209
+ from,
210
+ to,
211
+ fromOffset: 0,
212
+ toOffset: this.contentDOM.childNodes.length
213
+ };
214
+ let fromOffset = -1, toOffset = -1;
215
+ for (let offset = base, i = 0;; i++) {
216
+ const child = this.children[i], end = offset + child.size;
217
+ if (fromOffset == -1 && from <= end) {
218
+ const childBase = offset + child.border;
219
+ if (from >= childBase && to <= end - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) return child.parseRange(from, to, childBase);
220
+ from = offset;
221
+ for (let j = i; j > 0; j--) {
222
+ const prev = this.children[j - 1];
223
+ if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {
224
+ fromOffset = domIndex(prev.dom) + 1;
225
+ break;
226
+ }
227
+ from -= prev.size;
228
+ }
229
+ if (fromOffset == -1) fromOffset = 0;
230
+ }
231
+ if (fromOffset > -1 && (end > to || i == this.children.length - 1)) {
232
+ to = end;
233
+ for (let j = i + 1; j < this.children.length; j++) {
234
+ const next = this.children[j];
235
+ if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {
236
+ toOffset = domIndex(next.dom);
237
+ break;
238
+ }
239
+ to += next.size;
240
+ }
241
+ if (toOffset == -1) toOffset = this.contentDOM.childNodes.length;
242
+ break;
243
+ }
244
+ offset = end;
245
+ }
246
+ return {
247
+ node: this.contentDOM,
248
+ from,
249
+ to,
250
+ fromOffset,
251
+ toOffset
252
+ };
253
+ }
254
+ emptyChildAt(side) {
255
+ if (this.border || !this.contentDOM || !this.children.length) return false;
256
+ const child = this.children[side < 0 ? 0 : this.children.length - 1];
257
+ return child.size == 0 || child.emptyChildAt(side);
258
+ }
259
+ domAfterPos(pos) {
260
+ const { node, offset } = this.domFromPos(pos, 0);
261
+ if (node.nodeType != 1 || offset == node.childNodes.length) throw new RangeError("No node after pos " + pos);
262
+ return node.childNodes[offset];
263
+ }
264
+ setSelection(anchor, head, view, force = false) {
265
+ const from = Math.min(anchor, head), to = Math.max(anchor, head);
266
+ for (let i = 0, offset = 0; i < this.children.length; i++) {
267
+ const child = this.children[i], end = offset + child.size;
268
+ if (from > offset && to < end) return child.setSelection(anchor - offset - child.border, head - offset - child.border, view, force);
269
+ offset = end;
270
+ }
271
+ let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1);
272
+ let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1);
273
+ const domSel = view.root.getSelection();
274
+ const selRange = view.domSelectionRange();
275
+ let brKludge = false;
276
+ if ((gecko || safari) && anchor == head) {
277
+ const { node, offset } = anchorDOM;
278
+ if (node.nodeType == 3) {
279
+ brKludge = !!(offset && node.nodeValue[offset - 1] == "\n");
280
+ if (brKludge && offset == node.nodeValue.length) for (let scan = node, after; scan; scan = scan.parentNode) {
281
+ if (after = scan.nextSibling) {
282
+ if (after.nodeName == "BR") anchorDOM = headDOM = {
283
+ node: after.parentNode,
284
+ offset: domIndex(after) + 1
285
+ };
286
+ break;
287
+ }
288
+ const desc = scan.pmViewDesc;
289
+ if (desc && desc.node && desc.node.isBlock) break;
290
+ }
291
+ } else {
292
+ const prev = node.childNodes[offset - 1];
293
+ brKludge = !!prev && (prev.nodeName == "BR" || prev.contentEditable == "false");
294
+ }
295
+ }
296
+ if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode.nodeType == 1) {
297
+ const after = selRange.focusNode.childNodes[selRange.focusOffset];
298
+ if (after && after.contentEditable == "false") force = true;
299
+ }
300
+ if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) return;
301
+ let domSelExtended = false;
302
+ if ((domSel.extend || anchor == head) && !(brKludge && gecko)) {
303
+ domSel.collapse(anchorDOM.node, anchorDOM.offset);
304
+ try {
305
+ if (anchor != head) domSel.extend(headDOM.node, headDOM.offset);
306
+ domSelExtended = true;
307
+ } catch {}
308
+ }
309
+ if (!domSelExtended) {
310
+ if (anchor > head) {
311
+ const tmp = anchorDOM;
312
+ anchorDOM = headDOM;
313
+ headDOM = tmp;
314
+ }
315
+ const range = document.createRange();
316
+ range.setEnd(headDOM.node, headDOM.offset);
317
+ range.setStart(anchorDOM.node, anchorDOM.offset);
318
+ domSel.removeAllRanges();
319
+ domSel.addRange(range);
320
+ }
321
+ }
322
+ ignoreMutation(mutation) {
323
+ return !this.contentDOM && mutation.type != "selection";
324
+ }
325
+ get contentLost() {
326
+ return !!this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM);
327
+ }
328
+ markDirty(from, to) {
329
+ for (let offset = 0, i = 0; i < this.children.length; i++) {
330
+ const child = this.children[i], end = offset + child.size;
331
+ if (offset == end ? from <= end && to >= offset : from < end && to > offset) {
332
+ const startInside = offset + child.border, endInside = end - child.border;
333
+ if (from >= startInside && to <= endInside) {
334
+ this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY;
335
+ if (from == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY;
336
+ else child.markDirty(from - startInside, to - startInside);
337
+ return;
338
+ } else child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY;
339
+ }
340
+ offset = end;
341
+ }
342
+ this.dirty = CONTENT_DIRTY;
343
+ }
344
+ markParentsDirty() {
345
+ let level = 1;
346
+ for (let node = this.parent; node; node = node.parent, level++) {
347
+ const dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY;
348
+ if (node.dirty < dirty) node.dirty = dirty;
349
+ }
350
+ }
351
+ get domAtom() {
352
+ return false;
353
+ }
354
+ get ignoreForCoords() {
355
+ return false;
356
+ }
357
+ get ignoreForSelection() {
358
+ return false;
359
+ }
360
+ isText(_text) {
361
+ return false;
362
+ }
363
+ };
364
+ var WidgetViewDesc = class extends ViewDesc {
365
+ constructor(parent, widget, view, pos) {
366
+ const cell = { desc: void 0 };
367
+ let dom = widget.type.toDOM;
368
+ if (typeof dom == "function") dom = dom(view, () => {
369
+ const desc = cell.desc;
370
+ if (!desc) return pos;
371
+ if (desc.parent) return desc.parent.posBeforeChild(desc);
372
+ });
373
+ if (!widget.type.spec.raw) {
374
+ const elt = isElt(dom) ? dom : document.createElement("span");
375
+ if (elt != dom) {
376
+ elt.appendChild(dom);
377
+ dom = elt;
378
+ }
379
+ if (!elt.hasAttribute("contenteditable")) elt.contentEditable = "false";
380
+ elt.classList.add("ProseMirror-widget");
381
+ }
382
+ super(parent, [], dom, null);
383
+ this.widget = widget;
384
+ cell.desc = this;
385
+ }
386
+ matchesWidget(widget) {
387
+ return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type);
388
+ }
389
+ parseRule() {
390
+ return { ignore: true };
391
+ }
392
+ stopEvent(event) {
393
+ const stop = this.widget.spec.stopEvent;
394
+ return stop ? stop(event) : false;
395
+ }
396
+ ignoreMutation(mutation) {
397
+ return mutation.type != "selection" || this.widget.spec.ignoreSelection;
398
+ }
399
+ destroy() {
400
+ this.widget.type.destroy(this.dom);
401
+ super.destroy();
402
+ }
403
+ get domAtom() {
404
+ return true;
405
+ }
406
+ get ignoreForSelection() {
407
+ return !!this.widget.type.spec.relaxedSide;
408
+ }
409
+ get side() {
410
+ return this.widget.type.side;
411
+ }
412
+ };
413
+ /** @internal */
414
+ var CompositionViewDesc = class extends ViewDesc {
415
+ constructor(parent, dom, textDOM, text) {
416
+ super(parent, [], dom, null);
417
+ this.textDOM = textDOM;
418
+ this.text = text;
419
+ }
420
+ get size() {
421
+ return this.text.length;
422
+ }
423
+ localPosFromDOM(dom, offset) {
424
+ if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0);
425
+ return this.posAtStart + offset;
426
+ }
427
+ domFromPos(pos) {
428
+ return {
429
+ node: this.textDOM,
430
+ offset: pos
431
+ };
432
+ }
433
+ ignoreMutation(mut) {
434
+ return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue;
435
+ }
436
+ };
437
+ var MarkViewDesc = class MarkViewDesc extends ViewDesc {
438
+ constructor(parent, mark, dom, contentDOM, spec) {
439
+ super(parent, [], dom, contentDOM);
440
+ this.mark = mark;
441
+ this.spec = spec;
442
+ }
443
+ static create(parent, mark, inline, view) {
444
+ const custom = view.nodeViews[mark.type.name];
445
+ let spec = custom && custom(mark, view, inline);
446
+ if (!spec || !spec.dom) spec = DOMSerializer.renderSpecUnsafe(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs);
447
+ return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom, spec);
448
+ }
449
+ parseRule() {
450
+ if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) return null;
451
+ return {
452
+ mark: this.mark.type.name,
453
+ attrs: this.mark.attrs,
454
+ contentElement: this.contentDOM
455
+ };
456
+ }
457
+ matchesMark(mark) {
458
+ return this.dirty != NODE_DIRTY && this.mark.eq(mark);
459
+ }
460
+ markDirty(from, to) {
461
+ super.markDirty(from, to);
462
+ if (this.dirty != NOT_DIRTY) {
463
+ let parent = this.parent;
464
+ while (!parent.node) parent = parent.parent;
465
+ if (parent.dirty < this.dirty) parent.dirty = this.dirty;
466
+ this.dirty = NOT_DIRTY;
467
+ }
468
+ }
469
+ slice(from, to, view) {
470
+ const copy = MarkViewDesc.create(this.parent, this.mark, true, view);
471
+ let nodes = this.children;
472
+ const size = this.size;
473
+ if (to < size) nodes = replaceNodes(nodes, to, size, view);
474
+ if (from > 0) nodes = replaceNodes(nodes, 0, from, view);
475
+ for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy;
476
+ copy.children = nodes;
477
+ return copy;
478
+ }
479
+ ignoreMutation(mutation) {
480
+ return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation);
481
+ }
482
+ destroy() {
483
+ if (this.spec.destroy) this.spec.destroy();
484
+ super.destroy();
485
+ }
486
+ };
487
+ /** @internal */
488
+ var NodeViewDesc = class NodeViewDesc extends ViewDesc {
489
+ constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, _view, _pos) {
490
+ super(parent, [], dom, contentDOM);
491
+ this.node = node;
492
+ this.outerDeco = outerDeco;
493
+ this.innerDeco = innerDeco;
494
+ this.nodeDOM = nodeDOM;
495
+ }
496
+ static create(parent, node, outerDeco, innerDeco, view, pos) {
497
+ const custom = view.nodeViews[node.type.name];
498
+ let descObj;
499
+ const spec = custom && custom(node, view, () => {
500
+ if (!descObj) return pos;
501
+ if (descObj.parent) return descObj.parent.posBeforeChild(descObj);
502
+ }, outerDeco, innerDeco);
503
+ let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM;
504
+ if (node.isText) {
505
+ if (!dom) dom = document.createTextNode(textOf(node));
506
+ else if (dom.nodeType != 3) throw new RangeError("Text must be rendered as a DOM text node");
507
+ } else if (!dom) {
508
+ const spec = DOMSerializer.renderSpecUnsafe(document, node.type.spec.toDOM(node), null, node.attrs);
509
+ ({dom, contentDOM} = spec);
510
+ }
511
+ if (!contentDOM && !node.isText && dom.nodeName != "BR") {
512
+ if (!dom.hasAttribute("contenteditable")) dom.contentEditable = "false";
513
+ if (node.type.spec.draggable) dom.draggable = true;
514
+ }
515
+ const nodeDOM = dom;
516
+ dom = applyOuterDeco(dom, outerDeco, node);
517
+ if (spec) return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1);
518
+ else if (node.isText) return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view);
519
+ else return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1);
520
+ }
521
+ parseRule(addedNodes) {
522
+ if (this.node.type.spec.reparseInView) return null;
523
+ const rule = {
524
+ node: this.node.type.name,
525
+ attrs: this.node.attrs
526
+ };
527
+ if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full";
528
+ if (!this.contentDOM) rule.getContent = () => this.node.content;
529
+ else if (!this.contentLost) rule.contentElement = this.contentDOM;
530
+ else {
531
+ for (let i = this.children.length - 1; i >= 0; i--) {
532
+ const child = this.children[i];
533
+ if (this.dom.contains(child.dom.parentNode)) {
534
+ rule.contentElement = child.dom.parentNode;
535
+ break;
536
+ }
537
+ }
538
+ if (!rule.contentElement) {
539
+ const found = addedNodes?.find((n) => isElt(n) && (!n.parentNode || addedNodes.indexOf(n.parentNode) < 0) && this.dom.contains(n));
540
+ if (found) rule.contentElement = found;
541
+ else rule.getContent = () => Fragment.empty;
542
+ }
543
+ }
544
+ return rule;
545
+ }
546
+ matchesNode(node, outerDeco, innerDeco) {
547
+ return this.dirty == NOT_DIRTY && node.eq(this.node) && sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco);
548
+ }
549
+ get size() {
550
+ return this.node.nodeSize;
551
+ }
552
+ get border() {
553
+ return this.node.isLeaf ? 0 : 1;
554
+ }
555
+ updateChildren(view, pos) {
556
+ const inline = this.node.inlineContent;
557
+ let off = pos;
558
+ const composition = view.composing ? this.localCompositionInfo(view, pos) : null;
559
+ const localComposition = composition && composition.pos > -1 ? composition : null;
560
+ const compositionInChild = composition && composition.pos < 0;
561
+ const updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
562
+ const addBuffers = this.node.inlineContent;
563
+ let atBufferPos = addBuffers && this.node.isBlock;
564
+ iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
565
+ if (widget.spec.marks) updater.syncToMarks(widget.spec.marks, inline, view, i);
566
+ else if (widget.type.side >= 0 && !insideNode) updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.content.content[i].marks, inline, view, i);
567
+ updater.placeWidget(widget, view, off);
568
+ }, (child, outerDeco, innerDeco, i) => {
569
+ updater.syncToMarks(child.marks, inline, view, i);
570
+ if (atBufferPos && child.isAtom && !child.isText) updater.addHackNode("IMG", updater.top);
571
+ let compIndex;
572
+ if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) {} else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) {} else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off)) {} else updater.addNode(child, outerDeco, innerDeco, view, off);
573
+ off += child.nodeSize;
574
+ if (addBuffers) atBufferPos = child.isAtom && !child.isText;
575
+ });
576
+ updater.syncToMarks([], inline, view, 0);
577
+ if (this.node.isTextblock) updater.addTextblockHacks();
578
+ updater.destroyRest();
579
+ if (updater.changed || this.dirty == CONTENT_DIRTY) {
580
+ if (localComposition) this.protectLocalComposition(view, localComposition);
581
+ renderDescs(this.contentDOM, this.children, view);
582
+ if (ios) iosHacks(this.dom);
583
+ }
584
+ }
585
+ localCompositionInfo(view, pos) {
586
+ const { from, to } = view.state.selection;
587
+ if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return null;
588
+ const textNode = view.input.compositionNode;
589
+ if (!textNode || !this.dom.contains(textNode.parentNode)) return null;
590
+ if (this.node.inlineContent) {
591
+ const text = textNode.nodeValue;
592
+ const textPos = findTextInFragment(this.node.content, text, from - pos, to - pos);
593
+ return textPos < 0 ? null : {
594
+ node: textNode,
595
+ pos: textPos,
596
+ text
597
+ };
598
+ } else return {
599
+ node: textNode,
600
+ pos: -1,
601
+ text: ""
602
+ };
603
+ }
604
+ protectLocalComposition(view, { node, pos, text }) {
605
+ if (this.getDesc(node)) return;
606
+ let topNode = node;
607
+ for (;; topNode = topNode.parentNode) {
608
+ if (topNode.parentNode == this.contentDOM) break;
609
+ while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling);
610
+ while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling);
611
+ if (topNode.pmViewDesc) topNode.pmViewDesc = void 0;
612
+ }
613
+ const desc = new CompositionViewDesc(this, topNode, node, text);
614
+ view.input.compositionNodes.push(desc);
615
+ this.children = replaceNodes(this.children, pos, pos + text.length, view, desc);
616
+ }
617
+ update(node, outerDeco, innerDeco, view) {
618
+ if (this.dirty == NODE_DIRTY || !node.sameMarkup(this.node)) return false;
619
+ this.updateInner(node, outerDeco, innerDeco, view);
620
+ return true;
621
+ }
622
+ updateInner(node, outerDeco, innerDeco, view) {
623
+ this.updateOuterDeco(outerDeco);
624
+ this.node = node;
625
+ this.innerDeco = innerDeco;
626
+ if (this.contentDOM) this.updateChildren(view, this.posAtStart);
627
+ this.dirty = NOT_DIRTY;
628
+ }
629
+ updateOuterDeco(outerDeco) {
630
+ if (sameOuterDeco(outerDeco, this.outerDeco)) return;
631
+ const needsWrap = this.nodeDOM.nodeType != 1;
632
+ const oldDOM = this.dom;
633
+ this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap));
634
+ if (this.dom != oldDOM) {
635
+ oldDOM.pmViewDesc = void 0;
636
+ this.dom.pmViewDesc = this;
637
+ }
638
+ this.outerDeco = outerDeco;
639
+ }
640
+ selectNode() {
641
+ if (this.nodeDOM.nodeType == 1) {
642
+ this.nodeDOM.classList.add("ProseMirror-selectednode");
643
+ if (this.contentDOM || !this.node.type.spec.draggable) this.nodeDOM.draggable = true;
644
+ }
645
+ }
646
+ deselectNode() {
647
+ if (this.nodeDOM.nodeType == 1) {
648
+ this.nodeDOM.classList.remove("ProseMirror-selectednode");
649
+ if (this.contentDOM || !this.node.type.spec.draggable) this.nodeDOM.removeAttribute("draggable");
650
+ }
651
+ }
652
+ get domAtom() {
653
+ return this.node.isAtom;
654
+ }
655
+ };
656
+ /**
657
+ * Create a view desc for the top-level document node, to be exported
658
+ * and used by the view class.
659
+ *
660
+ * @internal
661
+ */
662
+ function docViewDesc(doc, outerDeco, innerDeco, dom, view) {
663
+ applyOuterDeco(dom, outerDeco, doc);
664
+ const docView = new NodeViewDesc(void 0, doc, outerDeco, innerDeco, dom, dom, dom, view, 0);
665
+ if (docView.contentDOM) docView.updateChildren(view, 0);
666
+ return docView;
667
+ }
668
+ var TextViewDesc = class TextViewDesc extends NodeViewDesc {
669
+ constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {
670
+ super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view, 0);
671
+ }
672
+ parseRule() {
673
+ let skip = this.nodeDOM.parentNode;
674
+ while (skip && skip != this.dom && !skip.pmIsDeco) skip = skip.parentNode;
675
+ return { skip: skip || true };
676
+ }
677
+ update(node, outerDeco, _innerDeco, view) {
678
+ if (this.dirty == NODE_DIRTY || this.dirty != NOT_DIRTY && !this.inParent() || !node.sameMarkup(this.node)) return false;
679
+ this.updateOuterDeco(outerDeco);
680
+ if ((this.dirty != NOT_DIRTY || textOf(node) != textOf(this.node)) && textOf(node) != this.nodeDOM.nodeValue) {
681
+ this.nodeDOM.nodeValue = textOf(node);
682
+ if (view.trackWrites == this.nodeDOM) view.trackWrites = null;
683
+ }
684
+ this.node = node;
685
+ this.dirty = NOT_DIRTY;
686
+ return true;
687
+ }
688
+ inParent() {
689
+ const parentDOM = this.parent.contentDOM;
690
+ for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true;
691
+ return false;
692
+ }
693
+ domFromPos(pos) {
694
+ return {
695
+ node: this.nodeDOM,
696
+ offset: pos
697
+ };
698
+ }
699
+ localPosFromDOM(dom, offset, bias) {
700
+ if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, textOf(this.node).length);
701
+ return super.localPosFromDOM(dom, offset, bias);
702
+ }
703
+ ignoreMutation(mutation) {
704
+ return mutation.type != "characterData" && mutation.type != "selection";
705
+ }
706
+ slice(from, to, view) {
707
+ const node = this.node.cut(from, to), dom = document.createTextNode(textOf(node));
708
+ return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view);
709
+ }
710
+ markDirty(from, to) {
711
+ super.markDirty(from, to);
712
+ if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length)) this.dirty = NODE_DIRTY;
713
+ }
714
+ get domAtom() {
715
+ return false;
716
+ }
717
+ isText(text) {
718
+ return textOf(this.node) == text;
719
+ }
720
+ };
721
+ var BufferHackViewDesc = class extends ViewDesc {
722
+ parseRule() {
723
+ return { ignore: true };
724
+ }
725
+ matchesHack(nodeName) {
726
+ return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName;
727
+ }
728
+ get domAtom() {
729
+ return true;
730
+ }
731
+ get ignoreForCoords() {
732
+ return this.dom.nodeName == "IMG";
733
+ }
734
+ };
735
+ function skippableBefore(children, index) {
736
+ const desc = children[index - 1];
737
+ if (!desc || desc.size) return false;
738
+ return desc instanceof BufferHackViewDesc || desc instanceof WidgetViewDesc && desc.side >= 0;
739
+ }
740
+ var CustomNodeViewDesc = class extends NodeViewDesc {
741
+ constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) {
742
+ super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos);
743
+ this.spec = spec;
744
+ }
745
+ update(node, outerDeco, innerDeco, view) {
746
+ if (this.dirty == NODE_DIRTY) return false;
747
+ if (this.spec.update && (this.node.type == node.type || this.spec.multiType)) {
748
+ const result = this.spec.update(node, outerDeco, innerDeco);
749
+ if (result) this.updateInner(node, outerDeco, innerDeco, view);
750
+ return result;
751
+ } else if (!this.contentDOM && !node.isLeaf) return false;
752
+ else return super.update(node, outerDeco, innerDeco, view);
753
+ }
754
+ selectNode() {
755
+ if (this.spec.selectNode) this.spec.selectNode();
756
+ else super.selectNode();
757
+ }
758
+ deselectNode() {
759
+ if (this.spec.deselectNode) this.spec.deselectNode();
760
+ else super.deselectNode();
761
+ }
762
+ setSelection(anchor, head, view, force) {
763
+ if (this.spec.setSelection) this.spec.setSelection(anchor, head, view.root);
764
+ else super.setSelection(anchor, head, view, force);
765
+ }
766
+ destroy() {
767
+ if (this.spec.destroy) this.spec.destroy();
768
+ super.destroy();
769
+ }
770
+ stopEvent(event) {
771
+ return this.spec.stopEvent ? this.spec.stopEvent(event) : false;
772
+ }
773
+ ignoreMutation(mutation) {
774
+ return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation);
775
+ }
776
+ };
777
+ function renderDescs(parentDOM, descs, view) {
778
+ let dom = parentDOM.firstChild, written = false;
779
+ for (let i = 0; i < descs.length; i++) {
780
+ const desc = descs[i], childDOM = desc.dom;
781
+ if (childDOM.parentNode == parentDOM) {
782
+ while (childDOM != dom) {
783
+ dom = rm(dom);
784
+ written = true;
785
+ }
786
+ dom = dom.nextSibling;
787
+ } else {
788
+ written = true;
789
+ parentDOM.insertBefore(childDOM, dom);
790
+ }
791
+ if (desc instanceof MarkViewDesc) {
792
+ const pos = dom ? dom.previousSibling : parentDOM.lastChild;
793
+ renderDescs(desc.contentDOM, desc.children, view);
794
+ dom = pos ? pos.nextSibling : parentDOM.firstChild;
795
+ }
796
+ }
797
+ while (dom) {
798
+ dom = rm(dom);
799
+ written = true;
800
+ }
801
+ if (written && view.trackWrites == parentDOM) view.trackWrites = null;
802
+ }
803
+ const OuterDecoLevel = function(nodeName) {
804
+ if (nodeName) this.nodeName = nodeName;
805
+ };
806
+ OuterDecoLevel.prototype = Object.create(null);
807
+ const noDeco = [new OuterDecoLevel()];
808
+ function computeOuterDeco(outerDeco, node, needsWrap) {
809
+ if (Arr.isReadonlyArrayEmpty(outerDeco)) return noDeco;
810
+ let top = needsWrap ? noDeco[0] : new OuterDecoLevel();
811
+ const result = [top];
812
+ for (let i = 0; i < outerDeco.length; i++) {
813
+ const attrs = outerDeco[i].type.attrs;
814
+ if (!attrs) continue;
815
+ if (attrs.nodeName) result.push(top = new OuterDecoLevel(attrs.nodeName));
816
+ for (const name in attrs) {
817
+ const val = attrs[name];
818
+ if (val == null) continue;
819
+ if (needsWrap && result.length == 1) result.push(top = new OuterDecoLevel(node.isInline ? "span" : "div"));
820
+ if (name == "class") top.class = (top.class ? top.class + " " : "") + val;
821
+ else if (name == "style") top.style = (top.style ? top.style + ";" : "") + val;
822
+ else if (name != "nodeName") top[name] = val;
823
+ }
824
+ }
825
+ return result;
826
+ }
827
+ function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) {
828
+ if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM;
829
+ let curDOM = nodeDOM;
830
+ for (let i = 0; i < curComputed.length; i++) {
831
+ const deco = curComputed[i];
832
+ let prev = prevComputed[i];
833
+ if (i) {
834
+ let parent;
835
+ if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && (parent = curDOM.parentNode) && parent.nodeName.toLowerCase() == deco.nodeName) curDOM = parent;
836
+ else {
837
+ parent = document.createElement(deco.nodeName);
838
+ parent.pmIsDeco = true;
839
+ parent.appendChild(curDOM);
840
+ prev = noDeco[0];
841
+ curDOM = parent;
842
+ }
843
+ }
844
+ patchAttributes(curDOM, prev || noDeco[0], deco);
845
+ }
846
+ return curDOM;
847
+ }
848
+ function patchAttributes(dom, prev, cur) {
849
+ for (const name in prev) if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) dom.removeAttribute(name);
850
+ for (const name in cur) if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) dom.setAttribute(name, cur[name]);
851
+ if (prev.class != cur.class) {
852
+ const prevList = prev.class ? prev.class.split(" ").filter(Boolean) : [];
853
+ const curList = cur.class ? cur.class.split(" ").filter(Boolean) : [];
854
+ for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1) dom.classList.remove(prevList[i]);
855
+ for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1) dom.classList.add(curList[i]);
856
+ if (dom.classList.item(0) === null) dom.removeAttribute("class");
857
+ }
858
+ if (prev.style != cur.style) {
859
+ if (prev.style) {
860
+ const prop = /\s*([\w\-\xa1-￿]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g;
861
+ let m;
862
+ while (m = prop.exec(prev.style)) dom.style.removeProperty(m[1]);
863
+ }
864
+ if (cur.style) dom.style.cssText += cur.style;
865
+ }
866
+ }
867
+ function applyOuterDeco(dom, deco, node) {
868
+ return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1));
869
+ }
870
+ function sameOuterDeco(a, b) {
871
+ if (a.length != b.length) return false;
872
+ for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false;
873
+ return true;
874
+ }
875
+ function rm(dom) {
876
+ const next = dom.nextSibling;
877
+ dom.parentNode.removeChild(dom);
878
+ return next;
879
+ }
880
+ var ViewTreeUpdater = class {
881
+ constructor(top, lock, view) {
882
+ this.lock = lock;
883
+ this.view = view;
884
+ this.index = 0;
885
+ this.stack = [];
886
+ this.changed = false;
887
+ this.top = top;
888
+ this.preMatch = preMatch(top.node.content, top);
889
+ }
890
+ destroyBetween(start, end) {
891
+ if (start == end) return;
892
+ for (let i = start; i < end; i++) this.top.children[i].destroy();
893
+ this.top.children.splice(start, end - start);
894
+ this.changed = true;
895
+ }
896
+ destroyRest() {
897
+ this.destroyBetween(this.index, this.top.children.length);
898
+ }
899
+ syncToMarks(marks, inline, view, parentIndex) {
900
+ let keep = 0, depth = this.stack.length >> 1;
901
+ const maxKeep = Math.min(depth, marks.length);
902
+ while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) keep++;
903
+ while (keep < depth) {
904
+ this.destroyRest();
905
+ this.top.dirty = NOT_DIRTY;
906
+ this.index = this.stack.pop();
907
+ this.top = this.stack.pop();
908
+ depth--;
909
+ }
910
+ while (depth < marks.length) {
911
+ this.stack.push(this.top, this.index + 1);
912
+ let found = -1, scanTo = this.top.children.length;
913
+ if (parentIndex < this.preMatch.index) scanTo = Math.min(this.index + 3, scanTo);
914
+ for (let i = this.index; i < scanTo; i++) {
915
+ const next = this.top.children[i];
916
+ if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) {
917
+ found = i;
918
+ break;
919
+ }
920
+ }
921
+ const cur = this.top.children.at(this.index), want = marks.at(depth);
922
+ if (found < 0 && want) {
923
+ if (cur instanceof MarkViewDesc && cur.dirty != NODE_DIRTY && cur.mark.type == want.type && cur.spec.update && !this.isLocked(cur.dom) && cur.spec.update(want)) {
924
+ cur.mark = want;
925
+ found = this.index;
926
+ this.changed = true;
927
+ }
928
+ }
929
+ if (found > -1) {
930
+ if (found > this.index) {
931
+ this.changed = true;
932
+ this.destroyBetween(this.index, found);
933
+ }
934
+ this.top = this.top.children[this.index];
935
+ } else {
936
+ const markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view);
937
+ this.top.children.splice(this.index, 0, markDesc);
938
+ this.top = markDesc;
939
+ this.changed = true;
940
+ }
941
+ this.index = 0;
942
+ depth++;
943
+ }
944
+ }
945
+ findNodeMatch(node, outerDeco, innerDeco, index) {
946
+ let found = -1, targetDesc;
947
+ if (index >= this.preMatch.index && (targetDesc = this.preMatch.matches[index - this.preMatch.index]).parent == this.top && targetDesc.matchesNode(node, outerDeco, innerDeco)) found = this.top.children.indexOf(targetDesc, this.index);
948
+ else for (let i = this.index, e = Math.min(this.top.children.length, i + 5); i < e; i++) {
949
+ const child = this.top.children[i];
950
+ if (child.matchesNode(node, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) {
951
+ found = i;
952
+ break;
953
+ }
954
+ }
955
+ if (found < 0) return false;
956
+ this.destroyBetween(this.index, found);
957
+ this.index++;
958
+ return true;
959
+ }
960
+ updateNodeAt(node, outerDeco, innerDeco, index, view) {
961
+ const child = this.top.children[index];
962
+ if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) child.dirty = CONTENT_DIRTY;
963
+ if (!child.update(node, outerDeco, innerDeco, view)) return false;
964
+ this.destroyBetween(this.index, index);
965
+ this.index++;
966
+ return true;
967
+ }
968
+ findIndexWithChild(domNode) {
969
+ for (;;) {
970
+ const parent = domNode.parentNode;
971
+ if (!parent) return -1;
972
+ if (parent == this.top.contentDOM) {
973
+ const desc = domNode.pmViewDesc;
974
+ if (desc) {
975
+ for (let i = this.index; i < this.top.children.length; i++) if (this.top.children[i] == desc) return i;
976
+ }
977
+ return -1;
978
+ }
979
+ domNode = parent;
980
+ }
981
+ }
982
+ updateNextNode(node, outerDeco, innerDeco, view, index, pos) {
983
+ for (let i = this.index; i < this.top.children.length; i++) {
984
+ const next = this.top.children[i];
985
+ if (next instanceof NodeViewDesc) {
986
+ const preMatch = this.preMatch.matched.get(next);
987
+ if (preMatch != null && preMatch != index) return false;
988
+ const nextDOM = next.dom;
989
+ let updated;
990
+ const locked = this.isLocked(nextDOM) && !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == textOf(node) && next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco));
991
+ if (!locked && next.update(node, outerDeco, innerDeco, view)) {
992
+ this.destroyBetween(this.index, i);
993
+ if (next.dom != nextDOM) this.changed = true;
994
+ this.index++;
995
+ return true;
996
+ } else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
997
+ this.destroyBetween(this.index, i);
998
+ this.top.children[this.index] = updated;
999
+ if (updated.contentDOM) {
1000
+ updated.dirty = CONTENT_DIRTY;
1001
+ updated.updateChildren(view, pos + 1);
1002
+ updated.dirty = NOT_DIRTY;
1003
+ }
1004
+ this.changed = true;
1005
+ this.index++;
1006
+ return true;
1007
+ }
1008
+ break;
1009
+ }
1010
+ }
1011
+ return false;
1012
+ }
1013
+ recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
1014
+ if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content) || !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco)) return null;
1015
+ const wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
1016
+ if (wrapper.contentDOM) {
1017
+ wrapper.children = next.children;
1018
+ next.children = [];
1019
+ for (const ch of wrapper.children) ch.parent = wrapper;
1020
+ }
1021
+ next.destroy();
1022
+ return wrapper;
1023
+ }
1024
+ addNode(node, outerDeco, innerDeco, view, pos) {
1025
+ const desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
1026
+ if (desc.contentDOM) desc.updateChildren(view, pos + 1);
1027
+ this.top.children.splice(this.index++, 0, desc);
1028
+ this.changed = true;
1029
+ }
1030
+ placeWidget(widget, view, pos) {
1031
+ const next = this.index < this.top.children.length ? this.top.children[this.index] : null;
1032
+ if (next && next.matchesWidget(widget) && (widget == next.widget || !next.widget.type.toDOM.parentNode)) this.index++;
1033
+ else {
1034
+ const desc = new WidgetViewDesc(this.top, widget, view, pos);
1035
+ this.top.children.splice(this.index++, 0, desc);
1036
+ this.changed = true;
1037
+ }
1038
+ }
1039
+ addTextblockHacks() {
1040
+ let lastChild = this.top.children[this.index - 1], parent = this.top;
1041
+ while (lastChild instanceof MarkViewDesc) {
1042
+ parent = lastChild;
1043
+ lastChild = parent.children[parent.children.length - 1];
1044
+ }
1045
+ if (!lastChild || !(lastChild instanceof TextViewDesc) || textOf(lastChild.node).endsWith("\n") || this.view.requiresGeckoHackNode && /\s$/.test(textOf(lastChild.node))) {
1046
+ if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") this.addHackNode("IMG", parent);
1047
+ this.addHackNode("BR", this.top);
1048
+ }
1049
+ }
1050
+ addHackNode(nodeName, parent) {
1051
+ if (parent == this.top && this.index < parent.children.length && parent.children[this.index].matchesHack(nodeName)) this.index++;
1052
+ else {
1053
+ const dom = document.createElement(nodeName);
1054
+ if (nodeName == "IMG") {
1055
+ dom.className = "ProseMirror-separator";
1056
+ dom.alt = "";
1057
+ }
1058
+ if (nodeName == "BR") dom.className = "ProseMirror-trailingBreak";
1059
+ const hack = new BufferHackViewDesc(this.top, [], dom, null);
1060
+ if (parent != this.top) parent.children.push(hack);
1061
+ else parent.children.splice(this.index++, 0, hack);
1062
+ this.changed = true;
1063
+ }
1064
+ }
1065
+ isLocked(node) {
1066
+ return this.lock && (node == this.lock || node.nodeType == 1 && node.contains(this.lock.parentNode));
1067
+ }
1068
+ };
1069
+ function preMatch(frag, parentDesc) {
1070
+ let curDesc = parentDesc, descI = curDesc.children.length;
1071
+ let fI = frag.childCount;
1072
+ const matched = /* @__PURE__ */ new WeakMap(), matches = [];
1073
+ outer: while (fI > 0) {
1074
+ let desc;
1075
+ for (;;) if (descI) {
1076
+ const next = curDesc.children[descI - 1];
1077
+ if (next instanceof MarkViewDesc) {
1078
+ curDesc = next;
1079
+ descI = next.children.length;
1080
+ } else {
1081
+ desc = next;
1082
+ descI--;
1083
+ break;
1084
+ }
1085
+ } else if (curDesc == parentDesc) break outer;
1086
+ else {
1087
+ descI = curDesc.parent.children.indexOf(curDesc);
1088
+ curDesc = curDesc.parent;
1089
+ }
1090
+ const node = desc.node;
1091
+ if (!node) continue;
1092
+ if (node != frag.content[fI - 1]) break;
1093
+ --fI;
1094
+ matched.set(desc, fI);
1095
+ matches.push(desc);
1096
+ }
1097
+ return {
1098
+ index: fI,
1099
+ matched,
1100
+ matches: matches.reverse()
1101
+ };
1102
+ }
1103
+ const bySide = (a, b) => Order.Number(a.type.side, b.type.side);
1104
+ function iterDeco(parent, deco, onWidget, onNode) {
1105
+ const locals = deco.locals(parent);
1106
+ let offset = 0;
1107
+ if (Arr.isReadonlyArrayEmpty(locals)) {
1108
+ for (let i = 0; i < parent.childCount; i++) {
1109
+ const child = parent.content.content[i];
1110
+ onNode(child, locals, deco.forChild(offset, child), i);
1111
+ offset += child.nodeSize;
1112
+ }
1113
+ return;
1114
+ }
1115
+ let decoIndex = 0, restNode = null;
1116
+ const active = [];
1117
+ for (let parentIndex = 0;;) {
1118
+ let widget, widgets;
1119
+ while (decoIndex < locals.length && locals[decoIndex].to == offset) {
1120
+ const next = locals[decoIndex++];
1121
+ if (next.widget) {
1122
+ if (!widget) widget = next;
1123
+ else (widgets || (widgets = [widget])).push(next);
1124
+ }
1125
+ }
1126
+ if (widget) {
1127
+ if (widgets) {
1128
+ const sorted = Arr.sort(widgets, bySide);
1129
+ for (let i = 0; i < sorted.length; i++) onWidget(sorted[i], parentIndex, !!restNode);
1130
+ } else onWidget(widget, parentIndex, !!restNode);
1131
+ }
1132
+ let child, index;
1133
+ if (restNode) {
1134
+ index = -1;
1135
+ child = restNode;
1136
+ restNode = null;
1137
+ } else if (parentIndex < parent.childCount) {
1138
+ index = parentIndex;
1139
+ child = parent.content.content[parentIndex++];
1140
+ } else break;
1141
+ for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1);
1142
+ while (decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset) active.push(locals[decoIndex++]);
1143
+ let end = offset + child.nodeSize;
1144
+ if (child.isText) {
1145
+ let cutAt = end;
1146
+ if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from;
1147
+ for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to;
1148
+ if (cutAt < end) {
1149
+ restNode = child.cut(cutAt - offset);
1150
+ child = child.cut(0, cutAt - offset);
1151
+ end = cutAt;
1152
+ index = -1;
1153
+ }
1154
+ } else while (decoIndex < locals.length && locals[decoIndex].to < end) decoIndex++;
1155
+ const outerDeco = child.isInline && !child.isLeaf ? active.filter((d) => !d.inline) : active.slice();
1156
+ onNode(child, outerDeco, deco.forChild(offset, child), index);
1157
+ offset = end;
1158
+ }
1159
+ }
1160
+ function iosHacks(dom) {
1161
+ if (dom.nodeName == "UL" || dom.nodeName == "OL") {
1162
+ const oldCSS = dom.style.cssText;
1163
+ dom.style.cssText = oldCSS + "; list-style: square !important";
1164
+ window.getComputedStyle(dom).listStyle;
1165
+ dom.style.cssText = oldCSS;
1166
+ }
1167
+ }
1168
+ function findTextInFragment(frag, text, from, to) {
1169
+ for (let i = 0, pos = 0; i < frag.childCount && pos <= to;) {
1170
+ const child = frag.content[i++], childStart = pos;
1171
+ pos += child.nodeSize;
1172
+ if (!child.isText) continue;
1173
+ let str = textOf(child);
1174
+ while (i < frag.childCount) {
1175
+ const next = frag.content[i++];
1176
+ pos += next.nodeSize;
1177
+ if (!next.isText) break;
1178
+ str += textOf(next);
1179
+ }
1180
+ if (pos >= from) {
1181
+ if (pos >= to && str.slice(to - text.length - childStart, to - childStart) == text) return to - text.length;
1182
+ const found = childStart < to ? str.lastIndexOf(text, to - childStart - 1) : -1;
1183
+ if (found >= 0 && found + text.length + childStart >= from) return childStart + found;
1184
+ if (from == to && str.length >= to + text.length - childStart && str.slice(to - childStart, to - childStart + text.length) == text) return to;
1185
+ }
1186
+ }
1187
+ return -1;
1188
+ }
1189
+ function replaceNodes(nodes, from, to, view, replacement) {
1190
+ const result = [];
1191
+ for (let i = 0, off = 0; i < nodes.length; i++) {
1192
+ const child = nodes[i], start = off, end = off += child.size;
1193
+ if (start >= to || end <= from) result.push(child);
1194
+ else {
1195
+ if (start < from) result.push(child.slice(0, from - start, view));
1196
+ if (replacement) {
1197
+ result.push(replacement);
1198
+ replacement = void 0;
1199
+ }
1200
+ if (end > to) result.push(child.slice(to - start, child.size, view));
1201
+ }
1202
+ }
1203
+ return result;
1204
+ }
1205
+ export { CompositionViewDesc, NodeViewDesc, ViewDesc, docViewDesc };