@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,1212 @@
1
+ import { Fragment as Fragment$1 } from "../model/fragment.js";
2
+ import { ContentMatch as ContentMatch$1 } from "../model/content.js";
3
+ import { Mark as Mark$1 } from "../model/mark.js";
4
+ import { Slice as Slice$1 } from "../model/replace.js";
5
+ import { DOMParser as DOMParser$1 } from "../model/from_dom.js";
6
+ import { NodeRange as NodeRange$1, ResolvedPos as ResolvedPos$1 } from "../model/resolvedpos.js";
7
+ import { Node as Node$1, TextNode as TextNode$1 } from "../model/node.js";
8
+ import { DocSchema, MarkType as MarkType$1, NodeType as NodeType$1 } from "../model/schema.js";
9
+ import { DOMSerializer as DOMSerializer$1 } from "../model/to_dom.js";
10
+ import { CORE, ReplaceError, adopt, guard, link, registerWrapper, setEmptyCoreArray, unwrap, unwrapArray, wrap, wrapArray } from "./internal/core.js";
11
+ import { OrderedMap } from "./orderedmap.js";
12
+ import * as Option from "effect/Option";
13
+ // src/compat/model.ts
14
+ /**
15
+ * A `prosemirror-model`-compatible facade over `@thomasfosterau/effect-richtext/model`.
16
+ *
17
+ * The classes exported here have the API of their ProseMirror
18
+ * counterparts (nullable results instead of `Option`, exceptions
19
+ * instead of `Effect` failures, string content expressions,
20
+ * `OrderedMap` specs, `new Schema(spec)`), and delegate all work to
21
+ * the core objects they wrap. Wrapping is identity-preserving: the same
22
+ * core object always yields the same facade. Use `toCore` / `fromCore`
23
+ * to move between this API and the Effect API.
24
+ *
25
+ * Ported API surface from prosemirror-model (MIT, Marijn Haverbeke and others).
26
+ *
27
+ * @since 0.1.0
28
+ */
29
+ const ORIGINAL = Symbol.for("effect-richtext/compat/original");
30
+ /** @internal */
31
+ const fragmentInput = (content) => {
32
+ if (content == null) return content;
33
+ if (Array.isArray(content)) return unwrapArray(content);
34
+ return unwrap(content);
35
+ };
36
+ const marksInput = (marks) => marks == null ? marks : unwrapArray(marks);
37
+ const nullable = (o) => wrap(Option.getOrNull(o));
38
+ /**
39
+ * This class represents a node in the tree that makes up a ProseMirror
40
+ * document.
41
+ *
42
+ * @since 0.1.0
43
+ * @category models
44
+ */
45
+ var Node = class {
46
+ /** @internal */
47
+ constructor(type, attrs, content, marks = Mark.none) {
48
+ link(this, new Node$1(type[CORE], attrs, content ? content[CORE] : null, unwrapArray(marks)));
49
+ }
50
+ /** The type of node that this is. */
51
+ get type() {
52
+ return wrap(this[CORE].type);
53
+ }
54
+ /** An object mapping attribute names to values. */
55
+ get attrs() {
56
+ return this[CORE].attrs;
57
+ }
58
+ /** A container holding the node's children. */
59
+ get content() {
60
+ return wrap(this[CORE].content);
61
+ }
62
+ /** The marks (things like whether it is emphasized or part of a link) applied to this node. */
63
+ get marks() {
64
+ return wrapArray(this[CORE].marks);
65
+ }
66
+ /** For text nodes, this contains the node's text content. */
67
+ get text() {}
68
+ /** The array of this node's child nodes. */
69
+ get children() {
70
+ return wrapArray(this[CORE].content.content);
71
+ }
72
+ /** The size of this node, as defined by the integer-based indexing scheme. */
73
+ get nodeSize() {
74
+ return this[CORE].nodeSize;
75
+ }
76
+ /** The number of children that the node has. */
77
+ get childCount() {
78
+ return this[CORE].childCount;
79
+ }
80
+ /** Get the child node at the given index. Raises an error when the index is out of range. */
81
+ child(index) {
82
+ return wrap(guard(() => this[CORE].childUnsafe(index)));
83
+ }
84
+ /** Get the child node at the given index, if it exists. */
85
+ maybeChild(index) {
86
+ return wrap(this[CORE].content.content[index] ?? null);
87
+ }
88
+ /** Call `f` for every child node. */
89
+ forEach(f) {
90
+ this[CORE].forEach((node, offset, index) => f(wrap(node), offset, index));
91
+ }
92
+ /** Invoke a callback for all descendant nodes recursively overlapping the given two positions. */
93
+ nodesBetween(from, to, f, startPos = 0) {
94
+ this[CORE].nodesBetween(from, to, visitor(f), startPos);
95
+ }
96
+ /** Call the given callback for every descendant node. */
97
+ descendants(f) {
98
+ this[CORE].descendants(visitor(f));
99
+ }
100
+ /** Concatenates all the text nodes found in this fragment and its children. */
101
+ get textContent() {
102
+ return this[CORE].textContent;
103
+ }
104
+ /** Get all text between positions `from` and `to`. */
105
+ textBetween(from, to, blockSeparator, leafText) {
106
+ return this[CORE].textBetween(from, to, blockSeparator, leafTextInput(leafText));
107
+ }
108
+ /** Returns this node's first child, or `null` if there are no children. */
109
+ get firstChild() {
110
+ return nullable(this[CORE].firstChild);
111
+ }
112
+ /** Returns this node's last child, or `null` if there are no children. */
113
+ get lastChild() {
114
+ return nullable(this[CORE].lastChild);
115
+ }
116
+ /** Test whether two nodes represent the same piece of document. */
117
+ eq(other) {
118
+ return this === other || this[CORE].eq(other[CORE]);
119
+ }
120
+ /** Compare the markup (type, attributes, and marks) of this node to those of another. */
121
+ sameMarkup(other) {
122
+ return this[CORE].sameMarkup(other[CORE]);
123
+ }
124
+ /** Check whether this node's markup correspond to the given type, attributes, and marks. */
125
+ hasMarkup(type, attrs, marks) {
126
+ return this[CORE].hasMarkup(type[CORE], attrs, marksInput(marks));
127
+ }
128
+ /** Create a new node with the same markup as this node, containing the given content. */
129
+ copy(content = null) {
130
+ return wrap(this[CORE].copy(content && content[CORE]));
131
+ }
132
+ /** Create a copy of this node, with the given set of marks instead of the node's own marks. */
133
+ mark(marks) {
134
+ return wrap(this[CORE].mark(unwrapArray(marks)));
135
+ }
136
+ /** Create a copy of this node with only the content between the given positions. */
137
+ cut(from, to) {
138
+ return wrap(this[CORE].cut(from, to));
139
+ }
140
+ /** Cut out the part of the document between the given positions, and return it as a `Slice` object. */
141
+ slice(from, to = this.content.size, includeParents = false) {
142
+ return wrap(guard(() => this[CORE].sliceUnsafe(from, to, includeParents)));
143
+ }
144
+ /** Replace the part of the document between the given positions with the given slice. */
145
+ replace(from, to, slice) {
146
+ return wrap(guard(() => this[CORE].replaceUnsafe(from, to, slice[CORE])));
147
+ }
148
+ /** Find the node directly after the given position. */
149
+ nodeAt(pos) {
150
+ return wrap(this[CORE].nodeAtOrNull(pos));
151
+ }
152
+ /** Find the (direct) child node after the given offset, if any. */
153
+ childAfter(pos) {
154
+ const { index, node, offset } = guard(() => this[CORE].childAfter(pos));
155
+ return {
156
+ node: nullable(node),
157
+ index,
158
+ offset
159
+ };
160
+ }
161
+ /** Find the (direct) child node before the given offset, if any. */
162
+ childBefore(pos) {
163
+ const { index, node, offset } = guard(() => this[CORE].childBefore(pos));
164
+ return {
165
+ node: nullable(node),
166
+ index,
167
+ offset
168
+ };
169
+ }
170
+ /** Resolve the given position in the document. */
171
+ resolve(pos) {
172
+ return wrap(guard(() => this[CORE].resolveUnsafe(pos)));
173
+ }
174
+ /** @internal */
175
+ resolveNoCache(pos) {
176
+ return wrap(guard(() => this[CORE].resolveNoCache(pos)));
177
+ }
178
+ /** Test whether a given mark or mark type occurs in this document between the two given positions. */
179
+ rangeHasMark(from, to, type) {
180
+ return this[CORE].rangeHasMark(from, to, type[CORE]);
181
+ }
182
+ /** True when this is a block (non-inline node). */
183
+ get isBlock() {
184
+ return this[CORE].isBlock;
185
+ }
186
+ /** True when this is a textblock node, a block node with inline content. */
187
+ get isTextblock() {
188
+ return this[CORE].isTextblock;
189
+ }
190
+ /** True when this node allows inline content. */
191
+ get inlineContent() {
192
+ return this[CORE].inlineContent;
193
+ }
194
+ /** True when this is an inline node. */
195
+ get isInline() {
196
+ return this[CORE].isInline;
197
+ }
198
+ /** True when this is a text node. */
199
+ get isText() {
200
+ return this[CORE].isText;
201
+ }
202
+ /** True when this is a leaf node. */
203
+ get isLeaf() {
204
+ return this[CORE].isLeaf;
205
+ }
206
+ /** True when this is an atom. */
207
+ get isAtom() {
208
+ return this[CORE].isAtom;
209
+ }
210
+ /** Return a string representation of this node for debugging purposes. */
211
+ toString() {
212
+ return this[CORE].toString();
213
+ }
214
+ /** Get the content match in this node at the given index. */
215
+ contentMatchAt(index) {
216
+ return wrap(guard(() => this[CORE].contentMatchAtUnsafe(index)));
217
+ }
218
+ /**
219
+ * Test whether replacing the range between `from` and `to` (by child
220
+ * index) with the given replacement fragment would leave the node's
221
+ * content valid.
222
+ */
223
+ canReplace(from, to, replacement = Fragment.empty, start = 0, end) {
224
+ return guard(() => this[CORE].canReplace(from, to, replacement[CORE], start, end));
225
+ }
226
+ /** Test whether replacing the range `from` to `to` (by index) with a node of the given type would be valid. */
227
+ canReplaceWith(from, to, type, marks) {
228
+ return guard(() => this[CORE].canReplaceWith(from, to, type[CORE], marksInput(marks)));
229
+ }
230
+ /** Test whether the given node's content could be appended to this node. */
231
+ canAppend(other) {
232
+ return guard(() => this[CORE].canAppend(other[CORE]));
233
+ }
234
+ /** Check whether this node and its descendants conform to the schema, and raise an exception when they do not. */
235
+ check() {
236
+ guard(() => this[CORE].checkUnsafe());
237
+ }
238
+ /** Return a JSON-serializeable representation of this node. */
239
+ toJSON() {
240
+ return this[CORE].toJSON();
241
+ }
242
+ /** Deserialize a node from its JSON representation. */
243
+ static fromJSON(schema, json) {
244
+ return wrap(guard(() => schema[CORE].nodeFromJSONUnsafe(json)));
245
+ }
246
+ };
247
+ /** @internal */
248
+ var TextNode = class extends Node {
249
+ get text() {
250
+ return this[CORE].text;
251
+ }
252
+ /** @internal */
253
+ withText(text) {
254
+ return wrap(this[CORE].withText(text));
255
+ }
256
+ };
257
+ const visitor = (f) => (node, pos, parent, index) => f(wrap(node), pos, nullable(parent), index);
258
+ const leafTextInput = (leafText) => typeof leafText === "function" ? (node) => leafText(wrap(node)) : leafText;
259
+ registerWrapper(Node$1, (core) => adopt(Node.prototype, core));
260
+ registerWrapper(TextNode$1, (core) => adopt(TextNode.prototype, core));
261
+ /**
262
+ * A fragment represents a node's collection of child nodes.
263
+ *
264
+ * @since 0.1.0
265
+ * @category models
266
+ */
267
+ var Fragment = class Fragment {
268
+ /** @internal */
269
+ constructor(content, size) {
270
+ link(this, new Fragment$1(unwrapArray(content), size));
271
+ }
272
+ /** The child nodes in this fragment. */
273
+ get content() {
274
+ return wrapArray(this[CORE].content);
275
+ }
276
+ /** The size of the fragment, which is the total of the size of its content nodes. */
277
+ get size() {
278
+ return this[CORE].size;
279
+ }
280
+ /** Invoke a callback for all descendant nodes between the given two positions. */
281
+ nodesBetween(from, to, f, nodeStart = 0, parent) {
282
+ this[CORE].nodesBetween(from, to, visitor(f), nodeStart, parent && parent[CORE]);
283
+ }
284
+ /** Call the given callback for every descendant node. */
285
+ descendants(f) {
286
+ this[CORE].descendants(visitor(f));
287
+ }
288
+ /** Extract the text between `from` and `to`. */
289
+ textBetween(from, to, blockSeparator, leafText) {
290
+ return this[CORE].textBetween(from, to, blockSeparator, leafTextInput(leafText));
291
+ }
292
+ /** Create a new fragment containing the combined content of this fragment and the other. */
293
+ append(other) {
294
+ return wrap(this[CORE].append(other[CORE]));
295
+ }
296
+ /** Cut out the sub-fragment between the two given positions. */
297
+ cut(from, to) {
298
+ return wrap(this[CORE].cut(from, to));
299
+ }
300
+ /** @internal */
301
+ cutByIndex(from, to) {
302
+ return wrap(this[CORE].cutByIndex(from, to));
303
+ }
304
+ /** Create a new fragment in which the node at the given index is replaced by the given node. */
305
+ replaceChild(index, node) {
306
+ return wrap(this[CORE].replaceChild(index, node[CORE]));
307
+ }
308
+ /** Create a new fragment by prepending the given node to this fragment. */
309
+ addToStart(node) {
310
+ return wrap(this[CORE].addToStart(node[CORE]));
311
+ }
312
+ /** Create a new fragment by appending the given node to this fragment. */
313
+ addToEnd(node) {
314
+ return wrap(this[CORE].addToEnd(node[CORE]));
315
+ }
316
+ /** Compare this fragment to another one. */
317
+ eq(other) {
318
+ return this[CORE].eq(other[CORE]);
319
+ }
320
+ /** The first child of the fragment, or `null` if it is empty. */
321
+ get firstChild() {
322
+ return nullable(this[CORE].firstChild);
323
+ }
324
+ /** The last child of the fragment, or `null` if it is empty. */
325
+ get lastChild() {
326
+ return nullable(this[CORE].lastChild);
327
+ }
328
+ /** The number of child nodes in this fragment. */
329
+ get childCount() {
330
+ return this[CORE].childCount;
331
+ }
332
+ /** Get the child node at the given index. Raise an error when the index is out of range. */
333
+ child(index) {
334
+ return wrap(guard(() => this[CORE].childUnsafe(index)));
335
+ }
336
+ /** Get the child node at the given index, if it exists. */
337
+ maybeChild(index) {
338
+ return wrap(this[CORE].content[index] ?? null);
339
+ }
340
+ /** Call `f` for every child node in this fragment. */
341
+ forEach(f) {
342
+ this[CORE].forEach((node, offset, index) => f(wrap(node), offset, index));
343
+ }
344
+ /** Find the first position at which this fragment and another fragment differ, or `null` if they are the same. */
345
+ findDiffStart(other, pos = 0) {
346
+ return Option.getOrNull(this[CORE].findDiffStart(other[CORE], pos));
347
+ }
348
+ /** Find the first position, searching from the end, at which this fragment and the given fragment differ. */
349
+ findDiffEnd(other, pos = this.size, otherPos = other.size) {
350
+ return Option.getOrNull(this[CORE].findDiffEnd(other[CORE], pos, otherPos));
351
+ }
352
+ /** @internal */
353
+ findIndex(pos) {
354
+ return guard(() => this[CORE].findIndex(pos));
355
+ }
356
+ /** Return a debugging string that describes this fragment. */
357
+ toString() {
358
+ return this[CORE].toString();
359
+ }
360
+ /** @internal */
361
+ toStringInner() {
362
+ return this[CORE].toStringInner();
363
+ }
364
+ /** Create a JSON-serializeable representation of this fragment. */
365
+ toJSON() {
366
+ return this[CORE].toJSON();
367
+ }
368
+ /** Deserialize a fragment from its JSON representation. */
369
+ static fromJSON(schema, value) {
370
+ if (!value) return Fragment.empty;
371
+ if (!Array.isArray(value)) throw new RangeError("Invalid input for Fragment.fromJSON");
372
+ return wrap(guard(() => Fragment$1.fromArray(value.map((v) => schema[CORE].nodeFromJSONUnsafe(v)))));
373
+ }
374
+ /** Build a fragment from an array of nodes. */
375
+ static fromArray(array) {
376
+ return wrap(Fragment$1.fromArray(unwrapArray(array)));
377
+ }
378
+ /** Create a fragment from something that can be interpreted as a set of nodes. */
379
+ static from(nodes) {
380
+ return wrap(guard(() => Fragment$1.from(fragmentInput(nodes))));
381
+ }
382
+ };
383
+ registerWrapper(Fragment$1, (core) => adopt(Fragment.prototype, core));
384
+ Fragment.empty = wrap(Fragment$1.empty);
385
+ /**
386
+ * A mark is a piece of information that can be attached to a node.
387
+ *
388
+ * @since 0.1.0
389
+ * @category models
390
+ */
391
+ var Mark = class Mark {
392
+ /** @internal */
393
+ constructor(type, attrs) {
394
+ link(this, new Mark$1(type[CORE], attrs));
395
+ }
396
+ /** The type of this mark. */
397
+ get type() {
398
+ return wrap(this[CORE].type);
399
+ }
400
+ /** The attributes associated with this mark. */
401
+ get attrs() {
402
+ return this[CORE].attrs;
403
+ }
404
+ /** Given a set of marks, create a new set which contains this one as well. */
405
+ addToSet(set) {
406
+ return wrapArray(this[CORE].addToSet(unwrapArray(set)));
407
+ }
408
+ /** Remove this mark from the given set. */
409
+ removeFromSet(set) {
410
+ return wrapArray(this[CORE].removeFromSet(unwrapArray(set)));
411
+ }
412
+ /** Test whether this mark is in the given set of marks. */
413
+ isInSet(set) {
414
+ return this[CORE].isInSet(unwrapArray(set));
415
+ }
416
+ /** Test whether this mark has the same type and attributes as another mark. */
417
+ eq(other) {
418
+ return this === other || this[CORE].eq(other[CORE]);
419
+ }
420
+ /** Convert this mark to a JSON-serializeable representation. */
421
+ toJSON() {
422
+ return this[CORE].toJSON();
423
+ }
424
+ /** @internal */
425
+ toString() {
426
+ return this[CORE].toString();
427
+ }
428
+ /** Deserialize a mark from JSON. */
429
+ static fromJSON(schema, json) {
430
+ return wrap(guard(() => schema[CORE].markFromJSONUnsafe(json)));
431
+ }
432
+ /** Test whether two sets of marks are identical. */
433
+ static sameSet(a, b) {
434
+ return a === b || Mark$1.sameSet(unwrapArray(a), unwrapArray(b));
435
+ }
436
+ /** Create a properly sorted mark set from null, a single mark, or an unsorted array of marks. */
437
+ static setFrom(marks) {
438
+ return wrapArray(Mark$1.setFrom(marks instanceof Mark ? marks[CORE] : marksInput(marks)));
439
+ }
440
+ };
441
+ registerWrapper(Mark$1, (core) => adopt(Mark.prototype, core));
442
+ Mark.none = wrapArray(Mark$1.none);
443
+ setEmptyCoreArray(Mark$1.none);
444
+ /**
445
+ * A slice represents a piece cut out of a larger document.
446
+ *
447
+ * @since 0.1.0
448
+ * @category models
449
+ */
450
+ var Slice = class {
451
+ /** Create a slice. */
452
+ constructor(content, openStart, openEnd) {
453
+ link(this, new Slice$1(content[CORE], openStart, openEnd));
454
+ }
455
+ /** The slice's content. */
456
+ get content() {
457
+ return wrap(this[CORE].content);
458
+ }
459
+ /** The open depth at the start of the fragment. */
460
+ get openStart() {
461
+ return this[CORE].openStart;
462
+ }
463
+ /** The open depth at the end. */
464
+ get openEnd() {
465
+ return this[CORE].openEnd;
466
+ }
467
+ /** The size this slice would add when inserted into a document. */
468
+ get size() {
469
+ return this[CORE].size;
470
+ }
471
+ /** @internal */
472
+ insertAt(pos, fragment) {
473
+ return wrap(guard(() => this[CORE].insertAt(pos, fragment[CORE])));
474
+ }
475
+ /** @internal */
476
+ removeBetween(from, to) {
477
+ return wrap(guard(() => this[CORE].removeBetween(from, to)));
478
+ }
479
+ /** Tests whether this slice is equal to another slice. */
480
+ eq(other) {
481
+ return this[CORE].eq(other[CORE]);
482
+ }
483
+ /** @internal */
484
+ toString() {
485
+ return this[CORE].toString();
486
+ }
487
+ /** Convert a slice to a JSON-serializable representation. */
488
+ toJSON() {
489
+ return this[CORE].toJSON();
490
+ }
491
+ /** Deserialize a slice from its JSON representation. */
492
+ static fromJSON(schema, json) {
493
+ return wrap(guard(() => Slice$1.fromJSONUnsafe(schema[CORE], json)));
494
+ }
495
+ /** Create a slice from a fragment by taking the maximum possible open value on both side of the fragment. */
496
+ static maxOpen(fragment, openIsolating = true) {
497
+ return wrap(Slice$1.maxOpen(fragment[CORE], openIsolating));
498
+ }
499
+ };
500
+ registerWrapper(Slice$1, (core) => adopt(Slice.prototype, core));
501
+ Slice.empty = wrap(Slice$1.empty);
502
+ /**
503
+ * You can resolve a position to get more information about it.
504
+ *
505
+ * @since 0.1.0
506
+ * @category models
507
+ */
508
+ var ResolvedPos = class {
509
+ /** @internal */
510
+ constructor(pos, path, parentOffset) {
511
+ link(this, new ResolvedPos$1(pos, path.map((x, i) => i % 3 === 0 ? unwrap(x) : x), parentOffset));
512
+ }
513
+ /** The position that was resolved. */
514
+ get pos() {
515
+ return this[CORE].pos;
516
+ }
517
+ /** @internal */
518
+ get path() {
519
+ return this._path ??= this[CORE].path.map((x, i) => i % 3 === 0 ? wrap(x) : x);
520
+ }
521
+ /** The offset this position has into its parent node. */
522
+ get parentOffset() {
523
+ return this[CORE].parentOffset;
524
+ }
525
+ /** The number of levels the parent node is from the root. */
526
+ get depth() {
527
+ return this[CORE].depth;
528
+ }
529
+ /** The parent node that the position points into. */
530
+ get parent() {
531
+ return wrap(this[CORE].parent);
532
+ }
533
+ /** The root node in which the position was resolved. */
534
+ get doc() {
535
+ return wrap(this[CORE].doc);
536
+ }
537
+ /** The ancestor node at the given level. */
538
+ node(depth) {
539
+ return wrap(this[CORE].node(depth));
540
+ }
541
+ /** The index into the ancestor at the given level. */
542
+ index(depth) {
543
+ return this[CORE].index(depth);
544
+ }
545
+ /** The index pointing after this position into the ancestor at the given level. */
546
+ indexAfter(depth) {
547
+ return this[CORE].indexAfter(depth);
548
+ }
549
+ /** The (absolute) position at the start of the node at the given level. */
550
+ start(depth) {
551
+ return this[CORE].start(depth);
552
+ }
553
+ /** The (absolute) position at the end of the node at the given level. */
554
+ end(depth) {
555
+ return this[CORE].end(depth);
556
+ }
557
+ /** The (absolute) position directly before the wrapping node at the given level. */
558
+ before(depth) {
559
+ return guard(() => this[CORE].beforeUnsafe(depth));
560
+ }
561
+ /** The (absolute) position directly after the wrapping node at the given level. */
562
+ after(depth) {
563
+ return guard(() => this[CORE].afterUnsafe(depth));
564
+ }
565
+ /** When this position points into a text node, this returns the distance between the position and the start of the text node. */
566
+ get textOffset() {
567
+ return this[CORE].textOffset;
568
+ }
569
+ /** Get the node directly after the position, if any. */
570
+ get nodeAfter() {
571
+ return wrap(this[CORE].nodeAfterOrNull);
572
+ }
573
+ /** Get the node directly before the position, if any. */
574
+ get nodeBefore() {
575
+ return wrap(this[CORE].nodeBeforeOrNull);
576
+ }
577
+ /** Get the position at the given index in the parent node at the given depth. */
578
+ posAtIndex(index, depth) {
579
+ return this[CORE].posAtIndex(index, depth);
580
+ }
581
+ /** Get the marks at this position. */
582
+ marks() {
583
+ return wrapArray(this[CORE].marks());
584
+ }
585
+ /** Get the marks after the current position, if any, except those that are non-inclusive and not present at position `$end`. */
586
+ marksAcross($end) {
587
+ const marks = this[CORE].marksAcrossOrNull($end[CORE]);
588
+ return marks && wrapArray(marks);
589
+ }
590
+ /** The depth up to which this position and the given (non-resolved) position share the same parent nodes. */
591
+ sharedDepth(pos) {
592
+ return this[CORE].sharedDepth(pos);
593
+ }
594
+ /** Returns a range based on the place where this position and the given position diverge around block content. */
595
+ blockRange(other = this, pred) {
596
+ return wrap(this[CORE].blockRangeOrNull(other[CORE], pred && ((node) => pred(wrap(node)))));
597
+ }
598
+ /** Query whether the given position shares the same parent node. */
599
+ sameParent(other) {
600
+ return this[CORE].sameParent(other[CORE]);
601
+ }
602
+ /** Return the greater of this and the given position. */
603
+ max(other) {
604
+ return wrap(this[CORE].max(other[CORE]));
605
+ }
606
+ /** Return the smaller of this and the given position. */
607
+ min(other) {
608
+ return wrap(this[CORE].min(other[CORE]));
609
+ }
610
+ /** @internal */
611
+ toString() {
612
+ return this[CORE].toString();
613
+ }
614
+ /** @internal */
615
+ static resolve(doc, pos) {
616
+ return wrap(guard(() => ResolvedPos$1.resolve(doc[CORE], pos)));
617
+ }
618
+ /** @internal */
619
+ static resolveCached(doc, pos) {
620
+ return wrap(guard(() => ResolvedPos$1.resolveCached(doc[CORE], pos)));
621
+ }
622
+ };
623
+ registerWrapper(ResolvedPos$1, (core) => adopt(ResolvedPos.prototype, core));
624
+ /**
625
+ * Represents a flat range of content, i.e. one that starts and ends in
626
+ * the same node.
627
+ *
628
+ * @since 0.1.0
629
+ * @category models
630
+ */
631
+ var NodeRange = class {
632
+ /** Construct a node range. */
633
+ constructor($from, $to, depth) {
634
+ link(this, new NodeRange$1($from[CORE], $to[CORE], depth));
635
+ }
636
+ /** A resolved position along the start of the content. */
637
+ get $from() {
638
+ return wrap(this[CORE].$from);
639
+ }
640
+ /** A position along the end of the content. */
641
+ get $to() {
642
+ return wrap(this[CORE].$to);
643
+ }
644
+ /** The depth of the node that this range points into. */
645
+ get depth() {
646
+ return this[CORE].depth;
647
+ }
648
+ /** The position at the start of the range. */
649
+ get start() {
650
+ return this[CORE].start;
651
+ }
652
+ /** The position at the end of the range. */
653
+ get end() {
654
+ return this[CORE].end;
655
+ }
656
+ /** The parent node that the range points into. */
657
+ get parent() {
658
+ return wrap(this[CORE].parent);
659
+ }
660
+ /** The start index of the range in the parent node. */
661
+ get startIndex() {
662
+ return this[CORE].startIndex;
663
+ }
664
+ /** The end index of the range in the parent node. */
665
+ get endIndex() {
666
+ return this[CORE].endIndex;
667
+ }
668
+ };
669
+ registerWrapper(NodeRange$1, (core) => adopt(NodeRange.prototype, core));
670
+ /**
671
+ * Instances of this class represent a match state of a node type's
672
+ * content expression.
673
+ *
674
+ * @since 0.1.0
675
+ * @category models
676
+ */
677
+ var ContentMatch = class {
678
+ /** @internal */
679
+ constructor(validEnd) {
680
+ link(this, new ContentMatch$1(validEnd));
681
+ }
682
+ /** True when this match state represents a valid end of the node. */
683
+ get validEnd() {
684
+ return this[CORE].validEnd;
685
+ }
686
+ /** @internal */
687
+ get next() {
688
+ return this[CORE].next.map(wrapEdge);
689
+ }
690
+ /** @internal */
691
+ static parse(string, nodeTypes) {
692
+ const types = {};
693
+ for (const name in nodeTypes) types[name] = nodeTypes[name][CORE];
694
+ return wrap(guard(() => ContentMatch$1.compile(string, types, "")));
695
+ }
696
+ /** Match a node type, returning a match after that node if successful. */
697
+ matchType(type) {
698
+ return wrap(this[CORE].matchTypeOrNull(type[CORE]));
699
+ }
700
+ /** Try to match a fragment. Returns the resulting match when successful. */
701
+ matchFragment(frag, start = 0, end = frag.childCount) {
702
+ return wrap(this[CORE].matchFragmentOrNull(frag[CORE], start, end));
703
+ }
704
+ /** @internal */
705
+ get inlineContent() {
706
+ return this[CORE].inlineContent;
707
+ }
708
+ /** Get the first matching node type at this match position that can be generated. */
709
+ get defaultType() {
710
+ return wrap(this[CORE].defaultTypeOrNull);
711
+ }
712
+ /** @internal */
713
+ compatible(other) {
714
+ return this[CORE].compatible(other[CORE]);
715
+ }
716
+ /** Try to match the given fragment, and if that fails, see if it can be made to match by inserting nodes in front of it. */
717
+ fillBefore(after, toEnd = false, startIndex = 0) {
718
+ return wrap(this[CORE].fillBeforeOrNull(after[CORE], toEnd, startIndex));
719
+ }
720
+ /** Find a set of wrapping node types that would allow a node of the given type to appear at this position. */
721
+ findWrapping(target) {
722
+ const found = this[CORE].findWrappingOrNull(target[CORE]);
723
+ return found && wrapArray(found);
724
+ }
725
+ /** The number of outgoing edges this node has in the finite automaton that describes the content expression. */
726
+ get edgeCount() {
727
+ return this[CORE].edgeCount;
728
+ }
729
+ /** Get the _n_th outgoing edge from this node in the finite automaton that describes the content expression. */
730
+ edge(n) {
731
+ const edge = this[CORE].next[n];
732
+ if (!edge) throw new RangeError(`There's no ${n}th edge in this content match`);
733
+ return wrapEdge(edge);
734
+ }
735
+ /** @internal */
736
+ toString() {
737
+ return this[CORE].toString();
738
+ }
739
+ };
740
+ const wrapEdge = (edge) => ({
741
+ type: wrap(edge.type),
742
+ next: wrap(edge.next)
743
+ });
744
+ registerWrapper(ContentMatch$1, (core) => adopt(ContentMatch.prototype, core));
745
+ ContentMatch.empty = wrap(ContentMatch$1.empty);
746
+ const translateRule = (rule) => {
747
+ if (!rule.getContent && !rule.clearMark) return rule;
748
+ const copy = {
749
+ ...rule,
750
+ [ORIGINAL]: rule
751
+ };
752
+ if (rule.getContent) copy.getContent = (dom, schema) => unwrap(rule.getContent(dom, wrap(schema)));
753
+ if (rule.clearMark) copy.clearMark = (mark) => rule.clearMark(wrap(mark));
754
+ return copy;
755
+ };
756
+ const translateNodeSpec = (spec) => {
757
+ const copy = {
758
+ ...spec,
759
+ [ORIGINAL]: spec
760
+ };
761
+ if (spec.toDOM) copy.toDOM = (node) => spec.toDOM(wrap(node));
762
+ if (spec.toDebugString) copy.toDebugString = (node) => spec.toDebugString(wrap(node));
763
+ if (spec.leafText) copy.leafText = (node) => spec.leafText(wrap(node));
764
+ if (spec.parseDOM) copy.parseDOM = spec.parseDOM.map(translateRule);
765
+ return copy;
766
+ };
767
+ const translateMarkSpec = (spec) => {
768
+ const copy = {
769
+ ...spec,
770
+ [ORIGINAL]: spec
771
+ };
772
+ if (spec.toDOM) copy.toDOM = (mark, inline) => spec.toDOM(wrap(mark), inline);
773
+ if (spec.parseDOM) copy.parseDOM = spec.parseDOM.map(translateRule);
774
+ return copy;
775
+ };
776
+ const originalSpec = (spec) => spec[ORIGINAL] ?? spec;
777
+ /**
778
+ * Node types are objects allocated once per `Schema` and used to tag
779
+ * `Node` instances.
780
+ *
781
+ * @since 0.1.0
782
+ * @category models
783
+ */
784
+ var NodeType = class {
785
+ /** The name the node type has in this schema. */
786
+ get name() {
787
+ return this[CORE].name;
788
+ }
789
+ /** A link back to the `Schema` the node type belongs to. */
790
+ get schema() {
791
+ return wrap(this[CORE].schema);
792
+ }
793
+ /** The spec that this type is based on. */
794
+ get spec() {
795
+ return originalSpec(this[CORE].spec);
796
+ }
797
+ /** @internal */
798
+ get groups() {
799
+ return this[CORE].groups;
800
+ }
801
+ /** @internal */
802
+ get attrs() {
803
+ return this[CORE].attrs;
804
+ }
805
+ /** @internal */
806
+ get defaultAttrs() {
807
+ return this[CORE].defaultAttrs;
808
+ }
809
+ /** True if this is a block type. */
810
+ get isBlock() {
811
+ return this[CORE].isBlock;
812
+ }
813
+ /** True if this is the text node type. */
814
+ get isText() {
815
+ return this[CORE].isText;
816
+ }
817
+ /** True if this node type has inline content. */
818
+ get inlineContent() {
819
+ return this[CORE].inlineContent;
820
+ }
821
+ /** The starting match of the node type's content expression. */
822
+ get contentMatch() {
823
+ return wrap(this[CORE].contentMatch);
824
+ }
825
+ /** The set of marks allowed in this node. `null` means all marks are allowed. */
826
+ get markSet() {
827
+ const set = this[CORE].markSet;
828
+ return set && wrapArray(set);
829
+ }
830
+ /** True if this is an inline type. */
831
+ get isInline() {
832
+ return this[CORE].isInline;
833
+ }
834
+ /** True if this is a textblock type, a block that contains inline content. */
835
+ get isTextblock() {
836
+ return this[CORE].isTextblock;
837
+ }
838
+ /** True for node types that allow no content. */
839
+ get isLeaf() {
840
+ return this[CORE].isLeaf;
841
+ }
842
+ /** True when this node is an atom, i.e. when it does not have directly editable content. */
843
+ get isAtom() {
844
+ return this[CORE].isAtom;
845
+ }
846
+ /** Return true when this node type is part of the given group. */
847
+ isInGroup(group) {
848
+ return this[CORE].isInGroup(group);
849
+ }
850
+ /** The node type's whitespace option. */
851
+ get whitespace() {
852
+ return this[CORE].whitespace;
853
+ }
854
+ /** Tells you whether this node type has any required attributes. */
855
+ hasRequiredAttrs() {
856
+ return this[CORE].hasRequiredAttrs();
857
+ }
858
+ /** Indicates whether this node allows some of the same content as the given node type. */
859
+ compatibleContent(other) {
860
+ return this[CORE].compatibleContent(other[CORE]);
861
+ }
862
+ /** @internal */
863
+ computeAttrs(attrs) {
864
+ return guard(() => this[CORE].computeAttrs(attrs));
865
+ }
866
+ /** Create a `Node` of this type. */
867
+ create(attrs = null, content, marks) {
868
+ return wrap(guard(() => this[CORE].createUnsafe(attrs, fragmentInput(content), marksInput(marks))));
869
+ }
870
+ /** Like `create`, but check the given content against the node type's content restrictions. */
871
+ createChecked(attrs = null, content, marks) {
872
+ return wrap(guard(() => this[CORE].createCheckedUnsafe(attrs, fragmentInput(content), marksInput(marks))));
873
+ }
874
+ /** Like `create`, but see if it is necessary to add nodes to the start or end of the given fragment to make it fit the node. */
875
+ createAndFill(attrs = null, content, marks) {
876
+ return wrap(guard(() => this[CORE].createAndFillOrNull(attrs, fragmentInput(content), marksInput(marks))));
877
+ }
878
+ /** Returns true if the given fragment is valid content for this node type. */
879
+ validContent(content) {
880
+ return this[CORE].validContent(content[CORE]);
881
+ }
882
+ /** @internal */
883
+ checkContent(content) {
884
+ guard(() => this[CORE].checkContent(content[CORE]));
885
+ }
886
+ /** @internal */
887
+ checkAttrs(attrs) {
888
+ guard(() => this[CORE].checkAttrs(attrs));
889
+ }
890
+ /** Check whether the given mark type is allowed in this node. */
891
+ allowsMarkType(markType) {
892
+ return this[CORE].allowsMarkType(markType[CORE]);
893
+ }
894
+ /** Test whether the given set of marks are allowed in this node. */
895
+ allowsMarks(marks) {
896
+ return this[CORE].allowsMarks(unwrapArray(marks));
897
+ }
898
+ /** Removes the marks that are not allowed in this node from the given set. */
899
+ allowedMarks(marks) {
900
+ return wrapArray(this[CORE].allowedMarks(unwrapArray(marks)));
901
+ }
902
+ /** @internal */
903
+ toString() {
904
+ return this[CORE].toString();
905
+ }
906
+ };
907
+ registerWrapper(NodeType$1, (core) => adopt(NodeType.prototype, core));
908
+ /**
909
+ * Like nodes, marks (which are associated with nodes to signify things
910
+ * like emphasis or being part of a link) are tagged with type objects,
911
+ * which are instantiated once per `Schema`.
912
+ *
913
+ * @since 0.1.0
914
+ * @category models
915
+ */
916
+ var MarkType = class {
917
+ /** The name of the mark type. */
918
+ get name() {
919
+ return this[CORE].name;
920
+ }
921
+ /** @internal */
922
+ get rank() {
923
+ return this[CORE].rank;
924
+ }
925
+ /** The schema that this mark type instance is part of. */
926
+ get schema() {
927
+ return wrap(this[CORE].schema);
928
+ }
929
+ /** The spec on which the type is based. */
930
+ get spec() {
931
+ return originalSpec(this[CORE].spec);
932
+ }
933
+ /** @internal */
934
+ get attrs() {
935
+ return this[CORE].attrs;
936
+ }
937
+ /** @internal */
938
+ get excluded() {
939
+ return wrapArray(this[CORE].excluded);
940
+ }
941
+ /** @internal */
942
+ get instance() {
943
+ return nullable(this[CORE].instance);
944
+ }
945
+ /** Create a mark of this type. */
946
+ create(attrs = null) {
947
+ return wrap(guard(() => this[CORE].createUnsafe(attrs ?? void 0)));
948
+ }
949
+ /** When there is a mark of this type in the given set, a new set without it is returned. */
950
+ removeFromSet(set) {
951
+ return wrapArray(this[CORE].removeFromSet(unwrapArray(set)));
952
+ }
953
+ /** Tests whether there is a mark of this type in the given set. */
954
+ isInSet(set) {
955
+ return wrap(this[CORE].findInSet(unwrapArray(set)));
956
+ }
957
+ /** @internal */
958
+ checkAttrs(attrs) {
959
+ guard(() => this[CORE].checkAttrs(attrs));
960
+ }
961
+ /** Queries whether a given mark type is excluded by this one. */
962
+ excludes(other) {
963
+ return this[CORE].excludes(other[CORE]);
964
+ }
965
+ /** @internal */
966
+ toString() {
967
+ return this[CORE].toString();
968
+ }
969
+ };
970
+ registerWrapper(MarkType$1, (core) => adopt(MarkType.prototype, core));
971
+ /**
972
+ * A document schema. Holds node and mark type objects for the nodes and
973
+ * marks that may occur in conforming documents, and provides
974
+ * functionality for creating and deserializing such documents.
975
+ *
976
+ * @since 0.1.0
977
+ * @category models
978
+ */
979
+ var Schema = class {
980
+ /** Construct a schema from a schema specification. */
981
+ constructor(spec) {
982
+ const instanceSpec = {};
983
+ for (const prop in spec) instanceSpec[prop] = spec[prop];
984
+ instanceSpec.nodes = OrderedMap.from(spec.nodes);
985
+ instanceSpec.marks = OrderedMap.from(spec.marks || {});
986
+ const nodes = {}, marks = {};
987
+ instanceSpec.nodes.forEach((name, s) => {
988
+ nodes[name] = translateNodeSpec(s);
989
+ });
990
+ instanceSpec.marks.forEach((name, s) => {
991
+ marks[name] = translateMarkSpec(s);
992
+ });
993
+ const core = guard(() => DocSchema.makeUnsafe({
994
+ nodes,
995
+ marks,
996
+ topNode: spec.topNode
997
+ }));
998
+ link(this, core);
999
+ initSchema(this, core, instanceSpec);
1000
+ }
1001
+ /** Create a node in this schema. */
1002
+ node(type, attrs = null, content, marks) {
1003
+ return wrap(guard(() => this[CORE].nodeUnsafe(typeof type === "string" ? type : type[CORE], attrs, fragmentInput(content), marksInput(marks))));
1004
+ }
1005
+ /** Create a text node in the schema. Empty text nodes are not allowed. */
1006
+ text(text, marks) {
1007
+ return wrap(guard(() => this[CORE].textUnsafe(text, marksInput(marks))));
1008
+ }
1009
+ /** Create a mark with the given type and attributes. */
1010
+ mark(type, attrs) {
1011
+ return wrap(guard(() => this[CORE].markUnsafe(typeof type === "string" ? type : type[CORE], attrs ?? void 0)));
1012
+ }
1013
+ /** Deserialize a node from its JSON representation. */
1014
+ nodeFromJSON(json) {
1015
+ return wrap(guard(() => this[CORE].nodeFromJSONUnsafe(json)));
1016
+ }
1017
+ /** Deserialize a mark from its JSON representation. */
1018
+ markFromJSON(json) {
1019
+ return wrap(guard(() => this[CORE].markFromJSONUnsafe(json)));
1020
+ }
1021
+ /** @internal */
1022
+ nodeType(name) {
1023
+ return wrap(guard(() => this[CORE].nodeType(name)));
1024
+ }
1025
+ };
1026
+ function initSchema(schema, core, spec) {
1027
+ const nodes = Object.create(null);
1028
+ for (const name in core.nodes) nodes[name] = wrap(core.nodes[name]);
1029
+ const marks = Object.create(null);
1030
+ for (const name in core.marks) marks[name] = wrap(core.marks[name]);
1031
+ schema.spec = spec;
1032
+ schema.nodes = nodes;
1033
+ schema.marks = marks;
1034
+ schema.linebreakReplacement = nullable(core.linebreakReplacement);
1035
+ schema.topNodeType = wrap(core.topNodeType);
1036
+ schema.cached = Object.create(null);
1037
+ schema.nodeFromJSON = schema.nodeFromJSON.bind(schema);
1038
+ schema.markFromJSON = schema.markFromJSON.bind(schema);
1039
+ }
1040
+ registerWrapper(DocSchema, (core) => {
1041
+ const schema = adopt(Schema.prototype, core);
1042
+ const nodes = {}, marks = {};
1043
+ for (const name in core.spec.nodes) nodes[name] = originalSpec(core.spec.nodes[name]);
1044
+ for (const name in core.spec.marks) marks[name] = originalSpec(core.spec.marks[name]);
1045
+ initSchema(schema, core, {
1046
+ ...core.spec,
1047
+ nodes: OrderedMap.from(nodes),
1048
+ marks: OrderedMap.from(marks)
1049
+ });
1050
+ return schema;
1051
+ });
1052
+ /** @internal */
1053
+ const parseOptions = (options) => {
1054
+ if (!options) return {};
1055
+ const result = { ...options };
1056
+ if (options.topNode) result.topNode = options.topNode[CORE];
1057
+ if (options.topMatch) result.topMatch = options.topMatch[CORE];
1058
+ if (options.context) result.context = options.context[CORE];
1059
+ if (options.ruleFromNode) {
1060
+ const f = options.ruleFromNode;
1061
+ result.ruleFromNode = (node) => {
1062
+ const rule = f(node);
1063
+ return rule && translateRule(rule);
1064
+ };
1065
+ }
1066
+ return result;
1067
+ };
1068
+ /**
1069
+ * A DOM parser represents a strategy for parsing DOM content into a
1070
+ * ProseMirror document conforming to a given schema.
1071
+ *
1072
+ * @since 0.1.0
1073
+ * @category models
1074
+ */
1075
+ var DOMParser = class {
1076
+ /** Create a parser that targets the given schema, using the given parsing rules. */
1077
+ constructor(schema, rules) {
1078
+ this._rules = rules;
1079
+ link(this, guard(() => new DOMParser$1(schema[CORE], rules.map(translateRule))));
1080
+ }
1081
+ /** The schema into which the parser parses. */
1082
+ get schema() {
1083
+ return wrap(this[CORE].schema);
1084
+ }
1085
+ /** The set of parse rules that the parser uses, in order of precedence. */
1086
+ get rules() {
1087
+ return this._rules ?? this[CORE].rules.map(originalSpec);
1088
+ }
1089
+ /** @internal */
1090
+ get tags() {
1091
+ return this[CORE].tags.map(originalSpec);
1092
+ }
1093
+ /** @internal */
1094
+ get styles() {
1095
+ return this[CORE].styles.map(originalSpec);
1096
+ }
1097
+ /** Parse a document from the content of a DOM node. */
1098
+ parse(dom, options) {
1099
+ return wrap(guard(() => this[CORE].parseUnsafe(dom, parseOptions(options))));
1100
+ }
1101
+ /** Parses the content of the given DOM node, like `parse`, and returns a slice open at the sides. */
1102
+ parseSlice(dom, options) {
1103
+ return wrap(guard(() => this[CORE].parseSliceUnsafe(dom, parseOptions(options))));
1104
+ }
1105
+ /** @internal */
1106
+ matchTag(dom, context, after) {
1107
+ return Option.getOrNull(this[CORE].matchTag(dom, context, after));
1108
+ }
1109
+ /** @internal */
1110
+ matchStyle(prop, value, context, after) {
1111
+ return Option.getOrNull(this[CORE].matchStyle(prop, value, context, after));
1112
+ }
1113
+ /** @internal */
1114
+ static schemaRules(schema) {
1115
+ return DOMParser$1.schemaRules(schema[CORE]).map((rule) => {
1116
+ const original = rule[ORIGINAL];
1117
+ if (!original) return rule;
1118
+ const result = Object.assign({}, original);
1119
+ if (rule.node !== void 0) result.node = rule.node;
1120
+ if (rule.mark !== void 0) result.mark = rule.mark;
1121
+ return result;
1122
+ });
1123
+ }
1124
+ /** Construct a DOM parser using the parsing rules listed in a schema's node specs, reordered by priority. */
1125
+ static fromSchema(schema) {
1126
+ return wrap(DOMParser$1.fromSchema(schema[CORE]));
1127
+ }
1128
+ };
1129
+ registerWrapper(DOMParser$1, (core) => adopt(DOMParser.prototype, core));
1130
+ /**
1131
+ * A DOM serializer knows how to convert ProseMirror nodes and marks of
1132
+ * various types to DOM nodes.
1133
+ *
1134
+ * @since 0.1.0
1135
+ * @category models
1136
+ */
1137
+ var DOMSerializer = class DOMSerializer {
1138
+ /** Create a serializer. */
1139
+ constructor(nodes, marks) {
1140
+ this.nodes = nodes;
1141
+ this.marks = marks;
1142
+ const coreNodes = {};
1143
+ for (const name in nodes) {
1144
+ const f = nodes[name];
1145
+ if (f) coreNodes[name] = (node) => f(wrap(node));
1146
+ }
1147
+ const coreMarks = {};
1148
+ for (const name in marks) {
1149
+ const f = marks[name];
1150
+ coreMarks[name] = f ? (mark, inline) => f(wrap(mark), inline) : f;
1151
+ }
1152
+ link(this, new DOMSerializer$1(coreNodes, coreMarks));
1153
+ }
1154
+ /** Serialize the content of this fragment to a DOM fragment. */
1155
+ serializeFragment(fragment, options = {}, target) {
1156
+ return guard(() => this[CORE].serializeFragment(fragment[CORE], options, target));
1157
+ }
1158
+ /** Serialize this node to a DOM node. */
1159
+ serializeNode(node, options = {}) {
1160
+ return guard(() => this[CORE].serializeNode(node[CORE], options));
1161
+ }
1162
+ /** @internal */
1163
+ serializeMark(mark, inline, options = {}) {
1164
+ return guard(() => this[CORE].serializeMarkOrNull(mark[CORE], inline, options));
1165
+ }
1166
+ /** Render an output spec to a DOM node. */
1167
+ static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
1168
+ return guard(() => DOMSerializer$1.renderSpecUnsafe(doc, structure, xmlNS, blockArraysIn));
1169
+ }
1170
+ /** Build a serializer using the `toDOM` properties in a schema's node and mark specs. */
1171
+ static fromSchema(schema) {
1172
+ return schema.cached.domSerializer || (schema.cached.domSerializer = new DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema)));
1173
+ }
1174
+ /** Gather the serializers in a schema's node specs into an object. */
1175
+ static nodesFromSchema(schema) {
1176
+ const result = gatherToDOM(schema.nodes);
1177
+ if (!result.text) result.text = (node) => node.text;
1178
+ return result;
1179
+ }
1180
+ /** Gather the serializers in a schema's mark specs into an object. */
1181
+ static marksFromSchema(schema) {
1182
+ return gatherToDOM(schema.marks);
1183
+ }
1184
+ };
1185
+ function gatherToDOM(obj) {
1186
+ const result = {};
1187
+ for (const name in obj) {
1188
+ const toDOM = obj[name].spec.toDOM;
1189
+ if (toDOM) result[name] = toDOM;
1190
+ }
1191
+ return result;
1192
+ }
1193
+ registerWrapper(DOMSerializer$1, (core) => {
1194
+ const serializer = adopt(DOMSerializer.prototype, core);
1195
+ const nodes = {};
1196
+ for (const name in core.nodes) nodes[name] = (node) => core.nodes[name](node[CORE]);
1197
+ const marks = {};
1198
+ for (const name in core.marks) {
1199
+ const f = core.marks[name];
1200
+ if (f) marks[name] = (mark, inline) => f(mark[CORE], inline);
1201
+ }
1202
+ serializer.nodes = nodes;
1203
+ serializer.marks = marks;
1204
+ return serializer;
1205
+ });
1206
+ function toCore(value) {
1207
+ return Array.isArray(value) ? unwrapArray(value) : unwrap(value);
1208
+ }
1209
+ function fromCore(value) {
1210
+ return Array.isArray(value) ? wrapArray(value) : wrap(value);
1211
+ }
1212
+ export { ContentMatch, DOMParser, DOMSerializer, Fragment, Mark, MarkType, Node, NodeRange, NodeType, OrderedMap, ReplaceError, ResolvedPos, Schema, Slice, TextNode, fragmentInput, fromCore, parseOptions, toCore };