@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,280 @@
1
+ import * as Option from "effect/Option";
2
+ import * as S from "effect/Schema";
3
+ // src/transform/map.ts
4
+ /**
5
+ * Position maps: `StepMap`, `Mapping` and `MapResult`.
6
+ *
7
+ * @since 0.1.0
8
+ */
9
+ const encodeRanges = S.encodeSync(S.fromJsonString(S.Array(S.Number)));
10
+ const lower16 = 65535;
11
+ const factor16 = Math.pow(2, 16);
12
+ const makeRecover = (index, offset) => index + offset * factor16;
13
+ const recoverIndex = (value) => value & lower16;
14
+ const recoverOffset = (value) => (value - (value & lower16)) / factor16;
15
+ const DEL_BEFORE = 1;
16
+ const DEL_AFTER = 2;
17
+ const DEL_ACROSS = 4;
18
+ const DEL_SIDE = 8;
19
+ /**
20
+ * An object representing a mapped position with extra information.
21
+ *
22
+ * @since 0.1.0
23
+ * @category models
24
+ */
25
+ var MapResult = class {
26
+ /** @internal */
27
+ constructor(pos, delInfo, recover) {
28
+ this.pos = pos;
29
+ this.delInfo = delInfo;
30
+ this.recover = recover;
31
+ }
32
+ /**
33
+ * Tells you whether the position was deleted, that is, whether the
34
+ * step removed the token on the side queried (via the `assoc`)
35
+ * argument from the document.
36
+ */
37
+ get deleted() {
38
+ return (this.delInfo & DEL_SIDE) > 0;
39
+ }
40
+ /** Tells you whether the token before the mapped position was deleted. */
41
+ get deletedBefore() {
42
+ return (this.delInfo & 5) > 0;
43
+ }
44
+ /** True when the token after the mapped position was deleted. */
45
+ get deletedAfter() {
46
+ return (this.delInfo & 6) > 0;
47
+ }
48
+ /**
49
+ * Tells whether any of the steps mapped through deletes across the
50
+ * position (including both the token before and after the position).
51
+ */
52
+ get deletedAcross() {
53
+ return (this.delInfo & DEL_ACROSS) > 0;
54
+ }
55
+ };
56
+ /**
57
+ * A map describing the deletions and insertions made by a step, which
58
+ * can be used to find the correspondence between positions in the
59
+ * pre-step version of a document and the same position in the
60
+ * post-step version.
61
+ *
62
+ * @since 0.1.0
63
+ * @category models
64
+ */
65
+ var StepMap = class StepMap {
66
+ /**
67
+ * Create a position map. The modifications to the document are
68
+ * represented as an array of numbers, in which each group of three
69
+ * represents a modified chunk as `[start, oldSize, newSize]`.
70
+ */
71
+ constructor(ranges, inverted = false) {
72
+ this.ranges = ranges;
73
+ this.inverted = inverted;
74
+ if (!ranges.length && StepMap.empty) return StepMap.empty;
75
+ }
76
+ /** @internal */
77
+ recover(value) {
78
+ let diff = 0;
79
+ const index = recoverIndex(value);
80
+ if (!this.inverted) for (let i = 0; i < index; i++) diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1];
81
+ return this.ranges[index * 3] + diff + recoverOffset(value);
82
+ }
83
+ mapResult(pos, assoc = 1) {
84
+ return this._map(pos, assoc, false);
85
+ }
86
+ map(pos, assoc = 1) {
87
+ return this._map(pos, assoc, true);
88
+ }
89
+ /** @internal */
90
+ _map(pos, assoc, simple) {
91
+ let diff = 0;
92
+ const oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
93
+ for (let i = 0; i < this.ranges.length; i += 3) {
94
+ const start = this.ranges[i] - (this.inverted ? diff : 0);
95
+ if (start > pos) break;
96
+ const oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize;
97
+ if (pos <= end) {
98
+ const side = !oldSize ? assoc : pos === start ? -1 : pos === end ? 1 : assoc;
99
+ const result = start + diff + (side < 0 ? 0 : newSize);
100
+ if (simple) return result;
101
+ const recover = pos === (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start);
102
+ let del = 0;
103
+ if (oldSize) {
104
+ del |= pos === start ? DEL_AFTER : pos === end ? DEL_BEFORE : DEL_ACROSS;
105
+ if (assoc < 0 ? pos !== start : pos !== end) del |= DEL_SIDE;
106
+ }
107
+ return new MapResult(result, del, recover);
108
+ }
109
+ diff += newSize - oldSize;
110
+ }
111
+ return simple ? pos + diff : new MapResult(pos + diff, 0, null);
112
+ }
113
+ /** @internal */
114
+ touches(pos, recover) {
115
+ let diff = 0;
116
+ const index = recoverIndex(recover);
117
+ const oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
118
+ for (let i = 0; i < this.ranges.length; i += 3) {
119
+ const start = this.ranges[i] - (this.inverted ? diff : 0);
120
+ if (start > pos) break;
121
+ const oldSize = this.ranges[i + oldIndex];
122
+ if (pos <= start + oldSize && i === index * 3) return true;
123
+ diff += this.ranges[i + newIndex] - oldSize;
124
+ }
125
+ return false;
126
+ }
127
+ /** Calls the given function on each of the changed ranges included in this map. */
128
+ forEach(f) {
129
+ const oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
130
+ for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {
131
+ const start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff);
132
+ const oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex];
133
+ f(oldStart, oldStart + oldSize, newStart, newStart + newSize);
134
+ diff += newSize - oldSize;
135
+ }
136
+ }
137
+ /**
138
+ * Create an inverted version of this map. The result can be used to
139
+ * map positions in the post-step document to the pre-step document.
140
+ */
141
+ invert() {
142
+ return new StepMap(this.ranges, !this.inverted);
143
+ }
144
+ /** @internal */
145
+ toString() {
146
+ return (this.inverted ? "-" : "") + encodeRanges(this.ranges);
147
+ }
148
+ /**
149
+ * Create a map that moves all positions by offset `n` (which may be
150
+ * negative). This can be useful when applying steps meant for a
151
+ * sub-document to a larger document, or vice-versa.
152
+ */
153
+ static offset(n) {
154
+ return n === 0 ? StepMap.empty : new StepMap(n < 0 ? [
155
+ 0,
156
+ -n,
157
+ 0
158
+ ] : [
159
+ 0,
160
+ 0,
161
+ n
162
+ ]);
163
+ }
164
+ static {
165
+ this.empty = new StepMap([]);
166
+ }
167
+ };
168
+ /**
169
+ * A mapping represents a pipeline of zero or more step maps. It has
170
+ * special provisions for losslessly handling mapping positions through
171
+ * a series of steps in which some steps are inverted versions of
172
+ * earlier steps. (This comes up when ‘rebasing’ steps for collaboration
173
+ * or history management.)
174
+ *
175
+ * Mappings are mutable: `appendMap` and friends modify the mapping in
176
+ * place.
177
+ *
178
+ * @since 0.1.0
179
+ * @category models
180
+ */
181
+ var Mapping = class Mapping {
182
+ /** Create a new mapping with the given position maps. */
183
+ constructor(maps, mirror, from = 0, to = maps ? maps.length : 0) {
184
+ this.mirror = mirror;
185
+ this.from = from;
186
+ this.to = to;
187
+ this._maps = maps || [];
188
+ this.ownData = !(maps || mirror);
189
+ }
190
+ /** The step maps in this mapping. */
191
+ get maps() {
192
+ return this._maps;
193
+ }
194
+ /** Create a mapping that maps only through a part of this one. */
195
+ slice(from = 0, to = this.maps.length) {
196
+ return new Mapping(this._maps, this.mirror, from, to);
197
+ }
198
+ /**
199
+ * Add a step map to the end of this mapping. If `mirrors` is given,
200
+ * it should be the index of the step map that is the mirror image of
201
+ * this one.
202
+ */
203
+ appendMap(map, mirrors) {
204
+ if (!this.ownData) {
205
+ this._maps = this._maps.slice();
206
+ this.mirror = this.mirror && this.mirror.slice();
207
+ this.ownData = true;
208
+ }
209
+ this.to = this._maps.push(map);
210
+ if (mirrors != null) this.setMirror(this._maps.length - 1, mirrors);
211
+ }
212
+ /** Add all the step maps in a given mapping to this one (preserving mirroring information). */
213
+ appendMapping(mapping) {
214
+ for (let i = 0, startSize = this._maps.length; i < mapping._maps.length; i++) {
215
+ const mirr = mapping.getMirrorOrUndefined(i);
216
+ this.appendMap(mapping._maps[i], mirr != null && mirr < i ? startSize + mirr : void 0);
217
+ }
218
+ }
219
+ /**
220
+ * Finds the offset of the step map that mirrors the map at the given
221
+ * offset, in this mapping (as per the second argument to
222
+ * `appendMap`).
223
+ */
224
+ getMirror(n) {
225
+ return Option.fromUndefinedOr(this.getMirrorOrUndefined(n));
226
+ }
227
+ /** @internal */
228
+ getMirrorOrUndefined(n) {
229
+ if (this.mirror) {
230
+ for (let i = 0; i < this.mirror.length; i++) if (this.mirror[i] === n) return this.mirror[i + (i % 2 ? -1 : 1)];
231
+ }
232
+ }
233
+ /** Record that the maps at offsets `n` and `m` mirror each other. */
234
+ setMirror(n, m) {
235
+ if (!this.mirror) this.mirror = [];
236
+ this.mirror.push(n, m);
237
+ }
238
+ /** Append the inverse of the given mapping to this one. */
239
+ appendMappingInverted(mapping) {
240
+ for (let i = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i >= 0; i--) {
241
+ const mirr = mapping.getMirrorOrUndefined(i);
242
+ this.appendMap(mapping._maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : void 0);
243
+ }
244
+ }
245
+ /** Create an inverted version of this mapping. */
246
+ invert() {
247
+ const inverse = new Mapping();
248
+ inverse.appendMappingInverted(this);
249
+ return inverse;
250
+ }
251
+ /** Map a position through this mapping. */
252
+ map(pos, assoc = 1) {
253
+ if (this.mirror) return this._map(pos, assoc, true);
254
+ for (let i = this.from; i < this.to; i++) pos = this._maps[i].map(pos, assoc);
255
+ return pos;
256
+ }
257
+ /** Map a position through this mapping, returning a mapping result. */
258
+ mapResult(pos, assoc = 1) {
259
+ return this._map(pos, assoc, false);
260
+ }
261
+ /** @internal */
262
+ _map(pos, assoc, simple) {
263
+ let delInfo = 0;
264
+ for (let i = this.from; i < this.to; i++) {
265
+ const result = this._maps[i].mapResult(pos, assoc);
266
+ if (result.recover != null) {
267
+ const corr = this.getMirrorOrUndefined(i);
268
+ if (corr != null && corr > i && corr < this.to) {
269
+ i = corr;
270
+ pos = this._maps[corr].recover(result.recover);
271
+ continue;
272
+ }
273
+ }
274
+ delInfo |= result.delInfo;
275
+ pos = result.pos;
276
+ }
277
+ return simple ? pos : new MapResult(pos, delInfo, null);
278
+ }
279
+ };
280
+ export { MapResult, Mapping, StepMap };
@@ -0,0 +1,98 @@
1
+ import { Fragment } from "../model/fragment.js";
2
+ import { MarkType } from "../model/schema.js";
3
+ import { Slice } from "../model/replace.js";
4
+ import { pushMarkStep } from "./mark_set_step.js";
5
+ import { AddMarkStep, RemoveMarkStep } from "./mark_step.js";
6
+ import { ReplaceStep } from "./replace_step.js";
7
+ import * as Option from "effect/Option";
8
+ // src/transform/mark.ts
9
+ /**
10
+ * Mark-related transform implementations.
11
+ *
12
+ * @internal
13
+ */
14
+ /** @internal */
15
+ function addMark(tr, from, to, mark) {
16
+ const added = [];
17
+ tr.doc.nodesBetween(from, to, (node, pos, parent) => {
18
+ if (!node.isInline) return;
19
+ const marks = node.marks;
20
+ if (!mark.isInSet(marks) && Option.isSome(parent) && parent.value.type.allowsMarkType(mark.type)) {
21
+ const start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to);
22
+ pushMarkStep(AddMarkStep, start, end, mark, added);
23
+ }
24
+ });
25
+ added.forEach((s) => tr.stepUnsafe(s));
26
+ }
27
+ /** @internal */
28
+ function removeMark(tr, from, to, mark) {
29
+ const matched = [];
30
+ let step = 0;
31
+ tr.doc.nodesBetween(from, to, (node, pos) => {
32
+ if (!node.isInline || !node.isAtom) return;
33
+ step++;
34
+ let toRemove = null;
35
+ if (mark instanceof MarkType) {
36
+ let set = node.marks, found;
37
+ const list = [];
38
+ while (found = mark.findInSet(set)) {
39
+ list.push(found);
40
+ set = found.removeFromSet(set);
41
+ }
42
+ if (list.length) toRemove = list;
43
+ } else if (mark) {
44
+ if (mark.isInSet(node.marks)) toRemove = [mark];
45
+ } else toRemove = node.marks;
46
+ if (toRemove && toRemove.length) {
47
+ const end = Math.min(pos + node.nodeSize, to);
48
+ for (let i = 0; i < toRemove.length; i++) {
49
+ const style = toRemove[i];
50
+ let found;
51
+ for (let j = 0; j < matched.length; j++) {
52
+ const m = matched[j];
53
+ if (m.step === step - 1 && style.eq(m.style)) found = m;
54
+ }
55
+ if (found) {
56
+ found.to = end;
57
+ found.step = step;
58
+ } else matched.push({
59
+ style,
60
+ from: Math.max(pos, from),
61
+ to: end,
62
+ step
63
+ });
64
+ }
65
+ }
66
+ });
67
+ matched.forEach((m) => tr.stepUnsafe(new RemoveMarkStep(m.from, m.to, m.style)));
68
+ }
69
+ /** @internal */
70
+ function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch, clearNewlines = true) {
71
+ const node = tr.doc.nodeAtOrNull(pos);
72
+ const replSteps = [];
73
+ let cur = pos + 1;
74
+ for (let i = 0; i < node.childCount; i++) {
75
+ const child = node.content.content[i], end = cur + child.nodeSize;
76
+ const allowed = match.matchTypeOrNull(child.type);
77
+ if (!allowed) replSteps.push(new ReplaceStep(cur, end, Slice.empty));
78
+ else {
79
+ match = allowed;
80
+ for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type)) tr.stepUnsafe(new RemoveMarkStep(cur, end, child.marks[j]));
81
+ if (clearNewlines && child.isText && parentType.whitespace !== "pre") {
82
+ let m, slice;
83
+ const newline = /\r?\n|\r/g;
84
+ while (m = newline.exec(child.text)) {
85
+ if (!slice) slice = new Slice(Fragment.from(parentType.schema.textUnsafe(" ", parentType.allowedMarks(child.marks))), 0, 0);
86
+ replSteps.push(new ReplaceStep(cur + m.index, cur + m.index + m[0].length, slice));
87
+ }
88
+ }
89
+ }
90
+ cur = end;
91
+ }
92
+ if (!match.validEnd) {
93
+ const fill = match.fillBeforeOrNull(Fragment.empty, true);
94
+ tr.replaceUnsafe(cur, cur, new Slice(fill, 0, 0));
95
+ }
96
+ for (let i = replSteps.length - 1; i >= 0; i--) tr.stepUnsafe(replSteps[i]);
97
+ }
98
+ export { addMark, clearIncompatible, removeMark };
@@ -0,0 +1,69 @@
1
+ import { JSONError } from "../model/errors.js";
2
+ import { Step, StepResult } from "./step.js";
3
+ import * as Arr from "effect/Array";
4
+ import * as Option from "effect/Option";
5
+ // src/transform/mark_set_step.ts
6
+ /**
7
+ * Internal helpers for mark steps: `pushMarkStep` and the `MarkSetStep`
8
+ * that inverting a mark step can produce. Not part of the public API
9
+ * (prosemirror-transform keeps both private too).
10
+ *
11
+ * Ported from prosemirror-transform 1.12.3 / 1.12.4 (MIT, Marijn Haverbeke and others).
12
+ *
13
+ * @internal
14
+ */
15
+ /**
16
+ * Append a mark step to `target`, extending the last step instead when
17
+ * it is of the same class, carries an equal mark, and ends at `from`.
18
+ *
19
+ * @internal
20
+ */
21
+ function pushMarkStep(cls, from, to, mark, target) {
22
+ const last = target.at(-1);
23
+ if (last && last instanceof cls && last.to === from && last.mark.eq(mark)) target[target.length - 1] = new cls(last.from, to, mark);
24
+ else target.push(new cls(from, to, mark));
25
+ }
26
+ /**
27
+ * A group of mark steps applied as one, produced when inverting a mark
28
+ * step needs more than one step. Serialized as `"markSet"`.
29
+ *
30
+ * @internal
31
+ */
32
+ var MarkSetStep = class MarkSetStep extends Step {
33
+ constructor(steps) {
34
+ super();
35
+ this.steps = steps;
36
+ }
37
+ apply(doc) {
38
+ return this.steps.reduce((result, step) => result.docOrNull === null ? result : step.apply(result.docOrNull), StepResult.ok(doc));
39
+ }
40
+ invert(doc) {
41
+ return new MarkSetStep(this.steps.map((s) => s.invert(doc)));
42
+ }
43
+ map(mapping) {
44
+ const result = Arr.getSomes(this.steps.map((step) => step.map(mapping)));
45
+ return result.length ? Option.some(new MarkSetStep(result)) : Option.none();
46
+ }
47
+ toJSON() {
48
+ return {
49
+ stepType: "markSet",
50
+ steps: this.steps.map((s) => s.toJSON())
51
+ };
52
+ }
53
+ /** @internal */
54
+ static fromJSONUnsafe(schema, json) {
55
+ if (!Array.isArray(json.steps) || !json.steps.every((s) => s && (s.stepType === "addMark" || s.stepType === "removeMark"))) throw new JSONError({ message: "Invalid JSON for MarkSetStep" });
56
+ return new MarkSetStep(json.steps.map((s) => Step.fromJSONUnsafe(schema, s)));
57
+ }
58
+ };
59
+ Step.jsonID("markSet", MarkSetStep);
60
+ /**
61
+ * The single step in `steps`, or a `MarkSetStep` grouping them.
62
+ *
63
+ * @internal
64
+ */
65
+ const markStepGroup = (steps) => {
66
+ const [only] = steps;
67
+ return steps.length === 1 && only ? only : new MarkSetStep(steps);
68
+ };
69
+ export { MarkSetStep, markStepGroup, pushMarkStep };
@@ -0,0 +1,113 @@
1
+ import { AnySchema } from "../model/schema.js";
2
+ import { Mark } from "../model/mark.js";
3
+ import { Node } from "../model/node.js";
4
+ import "../model.js";
5
+ import { Mappable } from "./map.js";
6
+ import { Step, StepJSON, StepResult } from "./step.js";
7
+ import * as Option from "effect/Option";
8
+ /**
9
+ * Add a mark to all inline content between two positions.
10
+ *
11
+ * @since 0.1.0
12
+ * @category steps
13
+ */
14
+ export declare class AddMarkStep<Sc extends AnySchema = AnySchema> extends Step<Sc> {
15
+ /** The start of the marked range. */
16
+ readonly from: number;
17
+ /** The end of the marked range. */
18
+ readonly to: number;
19
+ /** The mark to add. */
20
+ readonly mark: Mark<Sc>;
21
+ /** Create a mark step. */
22
+ constructor(
23
+ /** The start of the marked range. */
24
+ from: number,
25
+ /** The end of the marked range. */
26
+ to: number,
27
+ /** The mark to add. */
28
+ mark: Mark<Sc>);
29
+ apply(doc: Node<Sc>): StepResult<Sc>;
30
+ invert(doc: Node<Sc>): Step<Sc>;
31
+ map(mapping: Mappable): Option.Option<Step<Sc>>;
32
+ merge(other: Step<Sc>): Option.Option<Step<Sc>>;
33
+ toJSON(): StepJSON;
34
+ /** @internal */
35
+ static fromJSONUnsafe<Sc extends AnySchema>(schema: Sc, json: any): AddMarkStep<Sc>;
36
+ }
37
+ /**
38
+ * Remove a mark from all inline content between two positions.
39
+ *
40
+ * @since 0.1.0
41
+ * @category steps
42
+ */
43
+ export declare class RemoveMarkStep<Sc extends AnySchema = AnySchema> extends Step<Sc> {
44
+ /** The start of the unmarked range. */
45
+ readonly from: number;
46
+ /** The end of the unmarked range. */
47
+ readonly to: number;
48
+ /** The mark to remove. */
49
+ readonly mark: Mark<Sc>;
50
+ /** Create a mark-removing step. */
51
+ constructor(
52
+ /** The start of the unmarked range. */
53
+ from: number,
54
+ /** The end of the unmarked range. */
55
+ to: number,
56
+ /** The mark to remove. */
57
+ mark: Mark<Sc>);
58
+ apply(doc: Node<Sc>): StepResult<Sc>;
59
+ invert(doc: Node<Sc>): Step<Sc>;
60
+ map(mapping: Mappable): Option.Option<Step<Sc>>;
61
+ merge(other: Step<Sc>): Option.Option<Step<Sc>>;
62
+ toJSON(): StepJSON;
63
+ /** @internal */
64
+ static fromJSONUnsafe<Sc extends AnySchema>(schema: Sc, json: any): RemoveMarkStep<Sc>;
65
+ }
66
+ /**
67
+ * Add a mark to a specific node.
68
+ *
69
+ * @since 0.1.0
70
+ * @category steps
71
+ */
72
+ export declare class AddNodeMarkStep<Sc extends AnySchema = AnySchema> extends Step<Sc> {
73
+ /** The position of the target node. */
74
+ readonly pos: number;
75
+ /** The mark to add. */
76
+ readonly mark: Mark<Sc>;
77
+ /** Create a node mark step. */
78
+ constructor(
79
+ /** The position of the target node. */
80
+ pos: number,
81
+ /** The mark to add. */
82
+ mark: Mark<Sc>);
83
+ apply(doc: Node<Sc>): StepResult<Sc>;
84
+ invert(doc: Node<Sc>): Step<Sc>;
85
+ map(mapping: Mappable): Option.Option<Step<Sc>>;
86
+ toJSON(): StepJSON;
87
+ /** @internal */
88
+ static fromJSONUnsafe<Sc extends AnySchema>(schema: Sc, json: any): AddNodeMarkStep<Sc>;
89
+ }
90
+ /**
91
+ * Remove a mark from a specific node.
92
+ *
93
+ * @since 0.1.0
94
+ * @category steps
95
+ */
96
+ export declare class RemoveNodeMarkStep<Sc extends AnySchema = AnySchema> extends Step<Sc> {
97
+ /** The position of the target node. */
98
+ readonly pos: number;
99
+ /** The mark to remove. */
100
+ readonly mark: Mark<Sc>;
101
+ /** Create a mark-removing step. */
102
+ constructor(
103
+ /** The position of the target node. */
104
+ pos: number,
105
+ /** The mark to remove. */
106
+ mark: Mark<Sc>);
107
+ apply(doc: Node<Sc>): StepResult<Sc>;
108
+ invert(doc: Node<Sc>): Step<Sc>;
109
+ map(mapping: Mappable): Option.Option<Step<Sc>>;
110
+ toJSON(): StepJSON;
111
+ /** @internal */
112
+ static fromJSONUnsafe<Sc extends AnySchema>(schema: Sc, json: any): RemoveNodeMarkStep<Sc>;
113
+ }