@thomasfosterau/effect-richtext 0.0.0 → 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 +117 -1
  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 +200 -4
@@ -0,0 +1,448 @@
1
+ import { gecko, safari, webkit } from "./browser.js";
2
+ import { caretFromPoint, nodeSize, parentNode, textRange } from "./dom.js";
3
+ // src/view/domcoords.ts
4
+ function windowRect(doc) {
5
+ const vp = doc.defaultView && doc.defaultView.visualViewport;
6
+ if (vp) return {
7
+ left: 0,
8
+ right: vp.width,
9
+ top: 0,
10
+ bottom: vp.height
11
+ };
12
+ return {
13
+ left: 0,
14
+ right: doc.documentElement.clientWidth,
15
+ top: 0,
16
+ bottom: doc.documentElement.clientHeight
17
+ };
18
+ }
19
+ function getSide(value, side) {
20
+ return typeof value == "number" ? value : value[side];
21
+ }
22
+ function clientRect(node) {
23
+ const rect = node.getBoundingClientRect();
24
+ const scaleX = rect.width / node.offsetWidth || 1;
25
+ const scaleY = rect.height / node.offsetHeight || 1;
26
+ return {
27
+ left: rect.left,
28
+ right: rect.left + node.clientWidth * scaleX,
29
+ top: rect.top,
30
+ bottom: rect.top + node.clientHeight * scaleY
31
+ };
32
+ }
33
+ /** @internal */
34
+ function scrollRectIntoView(view, rect, startDOM) {
35
+ if (!nonZero(rect) && rect.left == 0) return;
36
+ const scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5;
37
+ const doc = view.dom.ownerDocument;
38
+ for (let parent = startDOM || view.dom;;) {
39
+ if (!parent) break;
40
+ if (parent.nodeType != 1) {
41
+ parent = parentNode(parent);
42
+ continue;
43
+ }
44
+ const elt = parent;
45
+ const atTop = elt == doc.body;
46
+ const bounding = atTop ? windowRect(doc) : clientRect(elt);
47
+ let moveX = 0, moveY = 0;
48
+ if (rect.top < bounding.top + getSide(scrollThreshold, "top")) moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top"));
49
+ else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom");
50
+ if (rect.left < bounding.left + getSide(scrollThreshold, "left")) moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left"));
51
+ else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) moveX = rect.right - bounding.right + getSide(scrollMargin, "right");
52
+ if (moveX || moveY) {
53
+ if (atTop) doc.defaultView.scrollBy(moveX, moveY);
54
+ else {
55
+ const startX = elt.scrollLeft, startY = elt.scrollTop;
56
+ if (moveY) elt.scrollTop += moveY;
57
+ if (moveX) elt.scrollLeft += moveX;
58
+ const dX = elt.scrollLeft - startX, dY = elt.scrollTop - startY;
59
+ rect = {
60
+ left: rect.left - dX,
61
+ top: rect.top - dY,
62
+ right: rect.right - dX,
63
+ bottom: rect.bottom - dY
64
+ };
65
+ }
66
+ }
67
+ const pos = atTop ? "fixed" : getComputedStyle(parent).position;
68
+ if (/^(fixed|sticky)$/.test(pos)) break;
69
+ parent = pos == "absolute" ? parent.offsetParent : parentNode(parent);
70
+ }
71
+ }
72
+ /** @internal */
73
+ function storeScrollPos(view) {
74
+ const rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top);
75
+ let refDOM, refTop;
76
+ for (let x = (rect.left + rect.right) / 2, y = startY + 1; y < Math.min(innerHeight, rect.bottom); y += 5) {
77
+ const dom = view.root.elementFromPoint(x, y);
78
+ if (!dom || dom == view.dom || !view.dom.contains(dom)) continue;
79
+ const localRect = dom.getBoundingClientRect();
80
+ if (localRect.top >= startY - 20) {
81
+ refDOM = dom;
82
+ refTop = localRect.top;
83
+ break;
84
+ }
85
+ }
86
+ return {
87
+ refDOM,
88
+ refTop,
89
+ stack: scrollStack(view.dom)
90
+ };
91
+ }
92
+ function scrollStack(dom) {
93
+ const stack = [], doc = dom.ownerDocument;
94
+ for (let cur = dom; cur; cur = parentNode(cur)) {
95
+ stack.push({
96
+ dom: cur,
97
+ top: cur.scrollTop,
98
+ left: cur.scrollLeft
99
+ });
100
+ if (dom == doc) break;
101
+ }
102
+ return stack;
103
+ }
104
+ /** @internal */
105
+ function resetScrollPos({ refDOM, refTop, stack }) {
106
+ const newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0;
107
+ restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop);
108
+ }
109
+ function restoreScrollStack(stack, dTop) {
110
+ for (let i = 0; i < stack.length; i++) {
111
+ const { dom, left, top } = stack[i];
112
+ if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop;
113
+ if (dom.scrollLeft != left) dom.scrollLeft = left;
114
+ }
115
+ }
116
+ let preventScrollSupported = null;
117
+ /** @internal */
118
+ function focusPreventScroll(dom) {
119
+ if (dom.setActive) return dom.setActive();
120
+ if (preventScrollSupported) return dom.focus(preventScrollSupported);
121
+ const stored = scrollStack(dom);
122
+ dom.focus(preventScrollSupported == null ? { get preventScroll() {
123
+ preventScrollSupported = { preventScroll: true };
124
+ return true;
125
+ } } : void 0);
126
+ if (!preventScrollSupported) {
127
+ preventScrollSupported = false;
128
+ restoreScrollStack(stored, 0);
129
+ }
130
+ }
131
+ function findOffsetInNode(node, coords) {
132
+ let closest, dxClosest = 2e8, coordsClosest;
133
+ let offset = 0;
134
+ let rowBot = coords.top, rowTop = coords.top;
135
+ let firstBelow, coordsBelow;
136
+ for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
137
+ let rects;
138
+ if (child.nodeType == 1) rects = child.getClientRects();
139
+ else if (child.nodeType == 3) rects = textRange(child).getClientRects();
140
+ else continue;
141
+ for (let i = 0; i < rects.length; i++) {
142
+ const rect = rects[i];
143
+ if (rect.top <= rowBot && rect.bottom >= rowTop) {
144
+ rowBot = Math.max(rect.bottom, rowBot);
145
+ rowTop = Math.min(rect.top, rowTop);
146
+ const dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0;
147
+ if (dx < dxClosest) {
148
+ closest = child;
149
+ dxClosest = dx;
150
+ coordsClosest = dx && closest.nodeType == 3 ? {
151
+ left: rect.right < coords.left ? rect.right : rect.left,
152
+ top: coords.top
153
+ } : coords;
154
+ if (child.nodeType == 1 && dx) offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
155
+ continue;
156
+ }
157
+ } else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) {
158
+ firstBelow = child;
159
+ coordsBelow = {
160
+ left: Math.max(rect.left, Math.min(rect.right, coords.left)),
161
+ top: rect.top
162
+ };
163
+ }
164
+ if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) offset = childIndex + 1;
165
+ }
166
+ }
167
+ if (!closest && firstBelow) {
168
+ closest = firstBelow;
169
+ coordsClosest = coordsBelow;
170
+ dxClosest = 0;
171
+ }
172
+ if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest);
173
+ if (!closest || dxClosest && closest.nodeType == 1) return {
174
+ node,
175
+ offset
176
+ };
177
+ return findOffsetInNode(closest, coordsClosest);
178
+ }
179
+ function findOffsetInText(node, coords) {
180
+ const len = node.nodeValue.length;
181
+ const range = document.createRange();
182
+ let result;
183
+ for (let i = 0; i < len; i++) {
184
+ range.setEnd(node, i + 1);
185
+ range.setStart(node, i);
186
+ const rect = singleRect(range, 1);
187
+ if (rect.top == rect.bottom) continue;
188
+ if (inRect(coords, rect)) {
189
+ result = {
190
+ node,
191
+ offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)
192
+ };
193
+ break;
194
+ }
195
+ }
196
+ range.detach();
197
+ return result || {
198
+ node,
199
+ offset: 0
200
+ };
201
+ }
202
+ function inRect(coords, rect) {
203
+ return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1;
204
+ }
205
+ function targetKludge(dom, coords) {
206
+ const parent = dom.parentNode;
207
+ if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) return parent;
208
+ return dom;
209
+ }
210
+ function posFromElement(view, elt, coords) {
211
+ const { node, offset } = findOffsetInNode(elt, coords);
212
+ let bias = -1;
213
+ if (node.nodeType == 1 && !node.firstChild) {
214
+ const rect = node.getBoundingClientRect();
215
+ bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1;
216
+ }
217
+ return view.docView.posFromDOM(node, offset, bias);
218
+ }
219
+ function posFromCaret(view, node, offset, coords) {
220
+ let outsideBlock = -1;
221
+ for (let cur = node, sawBlock = false;;) {
222
+ if (cur == view.dom) break;
223
+ const desc = view.docView.nearestDesc(cur, true);
224
+ let rect;
225
+ if (!desc) return null;
226
+ if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) && ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
227
+ if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
228
+ if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore;
229
+ else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter;
230
+ sawBlock = true;
231
+ }
232
+ if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) return (desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2) ? desc.posBefore : desc.posAfter;
233
+ }
234
+ cur = desc.dom.parentNode;
235
+ }
236
+ return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node, offset, -1);
237
+ }
238
+ function elementFromPoint(element, coords, box) {
239
+ const len = element.childNodes.length;
240
+ if (len && box.top < box.bottom) for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {
241
+ const child = element.childNodes[i];
242
+ if (child.nodeType == 1) {
243
+ const rects = child.getClientRects();
244
+ for (let j = 0; j < rects.length; j++) {
245
+ const rect = rects[j];
246
+ if (inRect(coords, rect)) return elementFromPoint(child, coords, rect);
247
+ }
248
+ }
249
+ if ((i = (i + 1) % len) == startI) break;
250
+ }
251
+ return element;
252
+ }
253
+ /** @internal */
254
+ function posAtCoords(view, coords) {
255
+ const doc = view.dom.ownerDocument;
256
+ let node, offset = 0;
257
+ const caret = caretFromPoint(doc, coords.left, coords.top);
258
+ if (caret) ({node, offset} = caret);
259
+ let elt = (view.root.elementFromPoint ? view.root : doc).elementFromPoint(coords.left, coords.top);
260
+ let pos;
261
+ if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {
262
+ const box = view.dom.getBoundingClientRect();
263
+ if (!inRect(coords, box)) return null;
264
+ elt = elementFromPoint(view.dom, coords, box);
265
+ if (!elt) return null;
266
+ }
267
+ if (safari) {
268
+ for (let p = elt; node && p; p = parentNode(p)) if (p.draggable) node = void 0;
269
+ }
270
+ elt = targetKludge(elt, coords);
271
+ if (node) {
272
+ if (gecko && node.nodeType == 1) {
273
+ offset = Math.min(offset, node.childNodes.length);
274
+ if (offset < node.childNodes.length) {
275
+ const next = node.childNodes[offset];
276
+ let box;
277
+ if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && box.bottom > coords.top) offset++;
278
+ }
279
+ }
280
+ let prev;
281
+ if (webkit && offset && node.nodeType == 1 && (prev = node.childNodes[offset - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) offset--;
282
+ if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && coords.top > node.lastChild.getBoundingClientRect().bottom) pos = view.state.doc.content.size;
283
+ else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") pos = posFromCaret(view, node, offset, coords);
284
+ }
285
+ if (pos == null) pos = posFromElement(view, elt, coords);
286
+ const desc = view.docView.nearestDesc(elt, true);
287
+ return {
288
+ pos,
289
+ inside: desc ? desc.posAtStart - desc.border : -1
290
+ };
291
+ }
292
+ function nonZero(rect) {
293
+ return rect.top < rect.bottom || rect.left < rect.right;
294
+ }
295
+ function singleRect(target, bias) {
296
+ const rects = target.getClientRects();
297
+ if (rects.length) {
298
+ const first = rects[bias < 0 ? 0 : rects.length - 1];
299
+ if (nonZero(first)) return first;
300
+ }
301
+ return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect();
302
+ }
303
+ const BIDI = /[֐-״؀-ۿ܀-ࢬ]/;
304
+ /** @internal */
305
+ function coordsAtPos(view, pos, side) {
306
+ const { atom, node, offset } = view.docView.domFromPos(pos, side < 0 ? -1 : 1);
307
+ const supportEmptyRange = webkit || gecko;
308
+ if (node.nodeType == 3) {
309
+ if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) {
310
+ const rect = singleRect(textRange(node, offset, offset), side);
311
+ if (gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {
312
+ const rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1);
313
+ if (rectBefore.top == rect.top) {
314
+ const rectAfter = singleRect(textRange(node, offset, offset + 1), -1);
315
+ if (rectAfter.top != rect.top) return flattenV(rectAfter, rectAfter.left < rectBefore.left);
316
+ }
317
+ }
318
+ return rect;
319
+ } else {
320
+ let from = offset, to = offset, takeSide = side < 0 ? 1 : -1;
321
+ if (side < 0 && !offset) {
322
+ to++;
323
+ takeSide = -1;
324
+ } else if (side >= 0 && offset == node.nodeValue.length) {
325
+ from--;
326
+ takeSide = 1;
327
+ } else if (side < 0) from--;
328
+ else to++;
329
+ return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
330
+ }
331
+ }
332
+ if (!view.state.doc.resolveUnsafe(pos - (atom || 0)).parent.inlineContent) {
333
+ if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
334
+ const before = node.childNodes[offset - 1];
335
+ if (before.nodeType == 1) return flattenH(before.getBoundingClientRect(), false);
336
+ }
337
+ if (atom == null && offset < nodeSize(node)) {
338
+ const after = node.childNodes[offset];
339
+ if (after.nodeType == 1) return flattenH(after.getBoundingClientRect(), true);
340
+ }
341
+ return flattenH(node.getBoundingClientRect(), side >= 0);
342
+ }
343
+ if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
344
+ const before = node.childNodes[offset - 1];
345
+ const target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1)) : before.nodeType == 1 && (before.nodeName != "BR" || !before.nextSibling) ? before : null;
346
+ if (target) return flattenV(singleRect(target, 1), false);
347
+ }
348
+ if (atom == null && offset < nodeSize(node)) {
349
+ let after = node.childNodes[offset];
350
+ while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords) after = after.nextSibling;
351
+ const target = !after ? null : after.nodeType == 3 ? textRange(after, 0, supportEmptyRange ? 0 : 1) : after.nodeType == 1 ? after : null;
352
+ if (target) return flattenV(singleRect(target, -1), true);
353
+ }
354
+ return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0);
355
+ }
356
+ function flattenV(rect, left) {
357
+ if (rect.width == 0) return rect;
358
+ const x = left ? rect.left : rect.right;
359
+ return {
360
+ top: rect.top,
361
+ bottom: rect.bottom,
362
+ left: x,
363
+ right: x
364
+ };
365
+ }
366
+ function flattenH(rect, top) {
367
+ if (rect.height == 0) return rect;
368
+ const y = top ? rect.top : rect.bottom;
369
+ return {
370
+ top: y,
371
+ bottom: y,
372
+ left: rect.left,
373
+ right: rect.right
374
+ };
375
+ }
376
+ function withFlushedState(view, state, f) {
377
+ const viewState = view.state, active = view.root.activeElement;
378
+ if (viewState != state) view.updateState(state);
379
+ if (active != view.dom) view.focus();
380
+ try {
381
+ return f();
382
+ } finally {
383
+ if (viewState != state) view.updateState(viewState);
384
+ if (active != view.dom && active) active.focus();
385
+ }
386
+ }
387
+ function endOfTextblockVertical(view, state, dir) {
388
+ const sel = state.selection;
389
+ const $pos = dir == "up" ? sel.$from : sel.$to;
390
+ return withFlushedState(view, state, () => {
391
+ let { node: dom } = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1);
392
+ for (;;) {
393
+ const nearest = view.docView.nearestDesc(dom, true);
394
+ if (!nearest) break;
395
+ if (nearest.node.isBlock) {
396
+ dom = nearest.contentDOM || nearest.dom;
397
+ break;
398
+ }
399
+ dom = nearest.dom.parentNode;
400
+ }
401
+ const coords = coordsAtPos(view, $pos.pos, 1);
402
+ for (let child = dom.firstChild; child; child = child.nextSibling) {
403
+ let boxes;
404
+ if (child.nodeType == 1) boxes = child.getClientRects();
405
+ else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects();
406
+ else continue;
407
+ for (let i = 0; i < boxes.length; i++) {
408
+ const box = boxes[i];
409
+ if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) return false;
410
+ }
411
+ }
412
+ return true;
413
+ });
414
+ }
415
+ const maybeRTL = /[֐-ࢬ]/;
416
+ function endOfTextblockHorizontal(view, state, dir) {
417
+ const { $head } = state.selection;
418
+ if (!$head.parent.isTextblock) return false;
419
+ const offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size;
420
+ const sel = view.domSelection();
421
+ if (!sel) return $head.pos == $head.start() || $head.pos == $head.end();
422
+ if (!maybeRTL.test($head.parent.textContent) || !sel.modify) return dir == "left" || dir == "backward" ? atStart : atEnd;
423
+ return withFlushedState(view, state, () => {
424
+ const { anchorNode, anchorOffset, focusNode: oldNode, focusOffset: oldOff } = view.domSelectionRange();
425
+ const oldBidiLevel = sel.caretBidiLevel;
426
+ sel.modify("move", dir, "character");
427
+ const parentDOM = $head.depth ? view.docView.domAfterPos($head.beforeUnsafe()) : view.dom;
428
+ const { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange();
429
+ const result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff;
430
+ try {
431
+ sel.collapse(anchorNode, anchorOffset);
432
+ if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) sel.extend(oldNode, oldOff);
433
+ } catch {}
434
+ if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel;
435
+ return result;
436
+ });
437
+ }
438
+ let cachedState = null;
439
+ let cachedDir = null;
440
+ let cachedResult = false;
441
+ /** @internal */
442
+ function endOfTextblock(view, state, dir) {
443
+ if (cachedState == state && cachedDir == dir) return cachedResult;
444
+ cachedState = state;
445
+ cachedDir = dir;
446
+ return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir);
447
+ }
448
+ export { coordsAtPos, endOfTextblock, focusPreventScroll, posAtCoords, resetScrollPos, scrollRectIntoView, storeScrollPos };
@@ -0,0 +1,47 @@
1
+ import { DOMNode, DOMSelectionRange } from "./dom.js";
2
+ import { EditorView } from "./view.js";
3
+ type AnyView = EditorView<any, any, any>;
4
+ declare class SelectionState {
5
+ anchorNode: DOMNode | null;
6
+ anchorOffset: number;
7
+ focusNode: DOMNode | null;
8
+ focusOffset: number;
9
+ set(sel: DOMSelectionRange): void;
10
+ clear(): void;
11
+ eq(sel: DOMSelectionRange): boolean;
12
+ }
13
+ /** @internal */
14
+ export declare class DOMObserver {
15
+ readonly view: AnyView;
16
+ readonly handleDOMChange: (from: number, to: number, typeOver: boolean, added: Array<DOMNode>) => void;
17
+ queue: Array<MutationRecord>;
18
+ flushingSoon: number;
19
+ observer: MutationObserver | null;
20
+ currentSelection: SelectionState;
21
+ onCharData: ((e: Event) => void) | null;
22
+ suppressingSelectionUpdates: boolean;
23
+ lastChangedTextNode: Text | null;
24
+ constructor(view: AnyView, handleDOMChange: (from: number, to: number, typeOver: boolean, added: Array<DOMNode>) => void);
25
+ flushSoon(): void;
26
+ forceFlush(): void;
27
+ start(): void;
28
+ stop(): void;
29
+ connectSelection(): void;
30
+ disconnectSelection(): void;
31
+ suppressSelectionUpdates(): void;
32
+ onSelectionChange(): void;
33
+ setCurSelection(): void;
34
+ ignoreSelectionChange(sel: DOMSelectionRange): boolean;
35
+ pendingRecords(): MutationRecord[];
36
+ flush(): void;
37
+ registerMutation(mut: MutationRecord, added: Array<DOMNode>): {
38
+ from: number;
39
+ to: number;
40
+ typeOver?: never;
41
+ } | {
42
+ from: number;
43
+ to: number;
44
+ typeOver: boolean;
45
+ } | null;
46
+ }
47
+ export {};