@jbpark/live-editor 1.10.0 → 1.12.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.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { _ as DRAGGABLE_ITEMS, b as __toESM, d as require_lib$1, f as require_lib, g as DEFAULT_TEMPLATE, p as BINDING_PROP } from "./document-DJDRM79h.mjs";
2
- import { a as detectTypeScript, c as generateSections, d as replaceSections, i as compile, l as getCachedScriptBlob, n as clearCompilationCache, o as extractSections, r as cn, s as generateSection, t as baseModules, u as preloadScripts } from "./utils-D1tlgtgj.mjs";
3
- import { _ as parseArrayExpression, c as extract, d as getCurrentValue, f as parseBinding, g as extractObjectProperties, h as extractNodeValue, i as replaceIds, l as nanoid, m as createNodeFromValue, n as clone, o as update, p as arrayExpressionToCode, r as fillIds, t as validateBindingValue, u as findEditableChildren, v as parseValue, y as generateCode } from "./ast-DiVN0l7x.mjs";
4
- import { generateTailwindCSS } from "./utils/tailwind/index.mjs";
1
+ import { _ as DEFAULT_TEMPLATE, f as require_lib$1, m as BINDING_PROP, n as createSectionPreviewCache, p as require_lib, v as DRAGGABLE_ITEMS, x as __toESM } from "./document-DocoSXLT.mjs";
2
+ import { a as detectTypeScript, d as replaceSections, i as compile, l as getCachedScriptBlob, n as clearCompilationCache, o as extractSections, r as cn, s as generateSection, t as baseModules, u as preloadScripts } from "./utils-DP9WPbBJ.mjs";
3
+ import { _ as parseArrayExpression, c as extract, d as getCurrentValue, f as parseBinding, g as extractObjectProperties, h as extractNodeValue, i as replaceIds, l as nanoid, m as createNodeFromValue, n as clone, o as update, p as arrayExpressionToCode, r as fillIds, t as validateBindingValue, u as findEditableChildren, v as parseValue, y as generateCode } from "./ast-9E8pNi7j.mjs";
4
+ import { t as generateTailwindCSS } from "./tailwind-CzPhj3D9.mjs";
5
5
  import "@jbpark/ui-kit/style.css";
6
6
  import React, { createContext, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
7
7
  import { Button, Card, Checkbox, ColorPicker, DatePicker, Drawer, Input, Select, Space, Toast, Typography, Upload } from "@jbpark/ui-kit";
@@ -9,7 +9,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { DndContext, DragOverlay, PointerSensor, closestCenter, useDndContext, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
10
10
  import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
11
11
  import { SortableContext, arrayMove, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
12
- import { useDebouncedValue, useEventListener, useMultiSelect, useMutationObserver, useResizeObserver, useResponsiveSize } from "@jbpark/use-hooks";
12
+ import { useDebounce, useDebouncedValue, useEventListener, useMultiSelect, useMutationObserver, useResizeObserver, useResponsiveSize } from "@jbpark/use-hooks";
13
13
  import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Bell, Bookmark, Calendar, Camera, Check, ChevronDown, ChevronRight, Clock, Copy, Download, Edit, Eye, Filter, Heart, Home, Image, Info, LayoutGrid, Link, Mail, Map as Map$1, Menu, MessageCircle, Phone, Plus, Search, Settings, Share, ShoppingCart, Star, Trash, Upload as Upload$1, User, X } from "lucide-react";
14
14
  import { v4 } from "uuid";
15
15
  import { createPortal } from "react-dom";
@@ -24,7 +24,6 @@ import prettierPluginTypeScript from "prettier/plugins/typescript";
24
24
  import Placeholder from "@tiptap/extension-placeholder";
25
25
  import { EditorContent, useEditor } from "@tiptap/react";
26
26
  import StarterKit from "@tiptap/starter-kit";
27
-
28
27
  //#region src/components/context/states.ts
29
28
  const PreviewContext = createContext(void 0);
30
29
  const ErrorContext = createContext(void 0);
@@ -38,7 +37,6 @@ const useError = () => {
38
37
  if (context === void 0) throw new Error("useError must be used within <Live> (ContextProvider)");
39
38
  return context;
40
39
  };
41
-
42
40
  //#endregion
43
41
  //#region src/components/context/context.tsx
44
42
  const ContextProvider = ({ children }) => {
@@ -69,7 +67,39 @@ const ContextProvider = ({ children }) => {
69
67
  })
70
68
  });
71
69
  };
72
-
70
+ //#endregion
71
+ //#region src/components/frame/measure.ts
72
+ const computeProbeHeight = (scrollContainerClientHeight, wrapperInsets) => {
73
+ const usable = scrollContainerClientHeight - wrapperInsets;
74
+ return usable > 0 ? usable : null;
75
+ };
76
+ const isVisuallyHidden = (computed) => computed.visibility === "hidden" || computed.opacity === "0";
77
+ const parseTranslateY = (transform) => {
78
+ if (!transform || transform === "none") return 0;
79
+ const translateYMatch = transform.match(/translateY\(\s*([+-]?\d*\.?\d+)/);
80
+ if (translateYMatch?.[1]) return parseFloat(translateYMatch[1]);
81
+ const translateMatch = transform.match(/translate\([^,]+,\s*([+-]?\d*\.?\d+)/);
82
+ if (translateMatch?.[1]) return parseFloat(translateMatch[1]);
83
+ const matrixMatch = transform.match(/matrix\(\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*([+-]?\d*\.?\d+)/);
84
+ return matrixMatch?.[1] ? parseFloat(matrixMatch[1]) : 0;
85
+ };
86
+ const estimatePositionedElementHeight = (offsetHeight, transform, probeHeight) => {
87
+ const offsetY = parseTranslateY(transform);
88
+ return Math.min(offsetY + offsetHeight, probeHeight);
89
+ };
90
+ //#endregion
91
+ //#region src/components/frame/viewport-units.ts
92
+ const UNIT_MAP = {
93
+ vh: "cqh",
94
+ svh: "cqh",
95
+ lvh: "cqh",
96
+ dvh: "cqh",
97
+ vmin: "cqmin",
98
+ vmax: "cqmax"
99
+ };
100
+ const UNITS_PATTERN = Object.keys(UNIT_MAP).sort((a, b) => b.length - a.length).join("|");
101
+ const VIEWPORT_UNIT_RE = new RegExp(`(?<![\\w.-])(-?(?:\\d+\\.?\\d*|\\.\\d+))(${UNITS_PATTERN})(?![a-zA-Z0-9_-])`, "gi");
102
+ const convertViewportUnits = (css) => css.replace(VIEWPORT_UNIT_RE, (_match, number, unit) => number + UNIT_MAP[unit.toLowerCase()]);
73
103
  //#endregion
74
104
  //#region src/components/frame/iframe.tsx
75
105
  const EMPTY_STRING_ARRAY = [];
@@ -113,7 +143,7 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
113
143
  const fragment = doc.createDocumentFragment();
114
144
  newStyles.forEach((content) => {
115
145
  const style = doc.createElement("style");
116
- style.textContent = content;
146
+ style.textContent = convertViewportUnits(content);
117
147
  fragment.appendChild(style);
118
148
  });
119
149
  doc.head.appendChild(fragment);
@@ -187,7 +217,8 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
187
217
  styleEl.id = styleId;
188
218
  doc.head.appendChild(styleEl);
189
219
  }
190
- if (styleEl.textContent !== css) styleEl.textContent = css;
220
+ const convertedCss = convertViewportUnits(css);
221
+ if (styleEl.textContent !== convertedCss) styleEl.textContent = convertedCss;
191
222
  });
192
223
  for (let index = styles.length; index < prevStyleCountRef.current; index++) doc.getElementById(`injected-style-${index}`)?.remove();
193
224
  prevStyleCountRef.current = styles.length;
@@ -205,50 +236,74 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
205
236
  for (let index = stylesheets.length; index < prevStylesheetCountRef.current; index++) doc.getElementById(`injected-stylesheet-${index}`)?.remove();
206
237
  prevStylesheetCountRef.current = stylesheets.length;
207
238
  }, [styles, stylesheets]);
239
+ const CONTAINER_STYLE_ID = "autoheight-container";
240
+ const ensureContainerStyle = (doc, probeHeight) => {
241
+ let styleEl = doc.getElementById(CONTAINER_STYLE_ID);
242
+ if (!styleEl) {
243
+ styleEl = doc.createElement("style");
244
+ styleEl.id = CONTAINER_STYLE_ID;
245
+ doc.head?.appendChild(styleEl);
246
+ }
247
+ styleEl.textContent = `html { container-type: size !important; height: ${probeHeight}px !important; }`;
248
+ };
249
+ const MEASUREMENT_OVERRIDE_STYLE_ID = "autoheight-measurement-overrides";
250
+ const withMeasurementOverrides = (doc, measure) => {
251
+ let styleEl = doc.getElementById(MEASUREMENT_OVERRIDE_STYLE_ID);
252
+ if (!styleEl) {
253
+ styleEl = doc.createElement("style");
254
+ styleEl.id = MEASUREMENT_OVERRIDE_STYLE_ID;
255
+ styleEl.media = "not all";
256
+ styleEl.textContent = [
257
+ "*, *::before, *::after { transition: none !important; }",
258
+ "html, body { scrollbar-width: none !important; }",
259
+ "html::-webkit-scrollbar, body::-webkit-scrollbar { display: none !important; }"
260
+ ].join("\n");
261
+ doc.head?.appendChild(styleEl);
262
+ }
263
+ styleEl.media = "all";
264
+ measure();
265
+ styleEl.media = "not all";
266
+ };
208
267
  const updateHeight = useCallback(() => {
209
268
  if (!shouldAutoHeight || !mountNode || !iframeRef.current) return;
210
269
  const iframe = iframeRef.current;
270
+ const doc = iframe.contentDocument;
271
+ const win = doc?.defaultView;
272
+ if (!doc || !win) return;
211
273
  const scrollParent = iframe.closest("[data-frame-container]");
212
- const savedScrollTop = scrollParent?.scrollTop ?? 0;
213
- iframe.style.height = "0px";
214
- let childrenHeight = 0;
215
- Array.from(mountNode.children).forEach((child) => {
216
- const el = child;
217
- childrenHeight = Math.max(childrenHeight, el.scrollHeight);
218
- });
219
- const win = iframe.contentDocument?.defaultView;
220
- mountNode.querySelectorAll("[data-floating-ui-focusable]").forEach((popup) => {
221
- if (popup.offsetHeight > 0) {
222
- let offsetY = 0;
223
- const transform = popup.style.transform;
224
- if (transform) {
225
- const match = transform.match(/translate\([^,]+,\s*([+-]?\d+(?:\.\d+)?)/);
226
- if (match?.[1]) offsetY = parseFloat(match[1]);
227
- }
228
- const estimatedHeight = offsetY + popup.offsetHeight;
229
- childrenHeight = Math.max(childrenHeight, estimatedHeight);
230
- }
231
- });
232
- if (win) Array.from(mountNode.children).forEach((child) => {
233
- const el = child;
234
- const style = win.getComputedStyle(el);
235
- if (style.position === "fixed" || style.position === "absolute") {
236
- if (el.offsetHeight > 0) {
237
- let offsetY = 0;
238
- const transform = el.style.transform;
239
- if (transform) {
240
- const match = transform.match(/translate\([^,]+,\s*([+-]?\d+(?:\.\d+)?)/);
241
- if (match?.[1]) offsetY = parseFloat(match[1]);
242
- }
243
- const estimatedHeight = offsetY + el.offsetHeight;
244
- childrenHeight = Math.max(childrenHeight, estimatedHeight);
274
+ let probeHeight;
275
+ if (!scrollParent) probeHeight = 812;
276
+ else {
277
+ let wrapperInsets = 0;
278
+ let node = iframe.parentElement;
279
+ while (node && node !== scrollParent) {
280
+ const style = win.getComputedStyle(node);
281
+ wrapperInsets += parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth) + parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
282
+ node = node.parentElement;
283
+ }
284
+ const computed = computeProbeHeight(scrollParent.clientHeight, wrapperInsets);
285
+ if (computed === null) return;
286
+ probeHeight = computed;
287
+ }
288
+ let contentHeight = 0;
289
+ withMeasurementOverrides(doc, () => {
290
+ ensureContainerStyle(doc, probeHeight);
291
+ contentHeight = mountNode.scrollHeight;
292
+ mountNode.querySelectorAll("*").forEach((el) => {
293
+ const style = win.getComputedStyle(el);
294
+ if (isVisuallyHidden(style)) return;
295
+ if ((style.position === "fixed" || style.position === "absolute") && el.offsetHeight > 0) {
296
+ const estimatedHeight = estimatePositionedElementHeight(el.offsetHeight, style.transform, probeHeight);
297
+ contentHeight = Math.max(contentHeight, estimatedHeight);
245
298
  }
246
- }
299
+ });
247
300
  });
248
- const contentHeight = Math.max(mountNode.scrollHeight, childrenHeight);
249
301
  if (contentHeight > 0) iframe.style.height = `${Math.ceil(contentHeight)}px`;
250
- if (scrollParent) scrollParent.scrollTop = savedScrollTop;
251
302
  }, [shouldAutoHeight, mountNode]);
303
+ useEffect(() => {
304
+ if (shouldAutoHeight) return;
305
+ iframeRef.current?.contentDocument?.getElementById(CONTAINER_STYLE_ID)?.remove();
306
+ }, [shouldAutoHeight]);
252
307
  useEffect(() => {
253
308
  updateHeight();
254
309
  }, [updateHeight]);
@@ -287,7 +342,6 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
287
342
  children: content
288
343
  });
289
344
  };
290
-
291
345
  //#endregion
292
346
  //#region src/components/frame/shadow.tsx
293
347
  const Shadow = ({ children }) => {
@@ -298,7 +352,8 @@ const Shadow = ({ children }) => {
298
352
  const [hostContainer, setHostContainer] = useState(null);
299
353
  useLayoutEffect(() => {
300
354
  if (!hostRef.current) return;
301
- setHostContainer(hostRef.current.closest("[data-frame-container]"));
355
+ const container = hostRef.current.closest("[data-frame-container]");
356
+ setHostContainer(container);
302
357
  let shadowRoot = shadowRootRef.current;
303
358
  if (!shadowRoot) {
304
359
  shadowRoot = hostRef.current.shadowRoot || hostRef.current.attachShadow({ mode: "open" });
@@ -321,7 +376,6 @@ const Shadow = ({ children }) => {
321
376
  children: renderTarget && createPortal(children(hostContainer), renderTarget)
322
377
  });
323
378
  };
324
-
325
379
  //#endregion
326
380
  //#region src/components/frame/frame.tsx
327
381
  const Frame = ({ mode, children, ...restProps }) => {
@@ -332,7 +386,6 @@ const Frame = ({ mode, children, ...restProps }) => {
332
386
  children
333
387
  });
334
388
  };
335
-
336
389
  //#endregion
337
390
  //#region src/components/dnd/draggable.tsx
338
391
  const DraggableItem = ({ item, children }) => {
@@ -363,7 +416,6 @@ const DefaultDraggableItem = ({ item, onAdd }) => /* @__PURE__ */ jsx(DraggableI
363
416
  children: item.name
364
417
  })
365
418
  });
366
-
367
419
  //#endregion
368
420
  //#region src/components/dnd/droppable.tsx
369
421
  const Droppable = ({ children, className }) => {
@@ -385,7 +437,6 @@ const Droppable = ({ children, className }) => {
385
437
  })]
386
438
  });
387
439
  };
388
-
389
440
  //#endregion
390
441
  //#region src/components/dnd/renderer.tsx
391
442
  const Renderer = ({ preview, headers, modules, frame, provider }) => {
@@ -422,7 +473,6 @@ const Renderer = ({ preview, headers, modules, frame, provider }) => {
422
473
  });
423
474
  };
424
475
  var renderer_default = memo(Renderer);
425
-
426
476
  //#endregion
427
477
  //#region src/components/dnd/sortable.tsx
428
478
  const Sortable = ({ id, children, selected, onClick, onDelete: _onDelete, onCopy: _onCopy }) => {
@@ -466,7 +516,6 @@ const Sortable = ({ id, children, selected, onClick, onDelete: _onDelete, onCopy
466
516
  ]
467
517
  });
468
518
  };
469
-
470
519
  //#endregion
471
520
  //#region src/components/dnd/overlay.tsx
472
521
  const Overlay = ({ sections, renderProps }) => {
@@ -491,10 +540,10 @@ const Overlay = ({ sections, renderProps }) => {
491
540
  }
492
541
  return null;
493
542
  };
494
-
495
543
  //#endregion
496
544
  //#region node_modules/.pnpm/@marijn+find-cluster-break@1.0.3/node_modules/@marijn/find-cluster-break/src/index.js
497
- let rangeFrom = [], rangeTo = [];
545
+ let rangeFrom = [];
546
+ let rangeTo = [];
498
547
  (() => {
499
548
  let numbers = "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map((s) => s ? parseInt(s, 36) : 1);
500
549
  for (let i = 0, n = 0; i < numbers.length; i++) (i % 2 ? rangeTo : rangeFrom).push(n = n + numbers[i]);
@@ -562,7 +611,6 @@ function surrogateHigh(ch) {
562
611
  function codePointSize(code) {
563
612
  return code < 65536 ? 1 : 2;
564
613
  }
565
-
566
614
  //#endregion
567
615
  //#region node_modules/.pnpm/@codemirror+state@6.7.1/node_modules/@codemirror/state/dist/index.js
568
616
  /**
@@ -877,7 +925,7 @@ var TextNode = class TextNode extends Text {
877
925
  return chunked.length == 1 ? chunked[0] : new TextNode(chunked, length);
878
926
  }
879
927
  };
880
- Text.empty = /* @__PURE__ */ new TextLeaf([""], 0);
928
+ Text.empty = /*@__PURE__*/ new TextLeaf([""], 0);
881
929
  function textLength(text) {
882
930
  let length = -1;
883
931
  for (let line of text) length += line.length + 1;
@@ -1011,12 +1059,13 @@ var LineCursor = class {
1011
1059
  } else if (done) {
1012
1060
  this.done = true;
1013
1061
  this.value = "";
1014
- } else if (lineBreak) if (this.afterBreak) this.value = "";
1015
- else {
1016
- this.afterBreak = true;
1017
- this.next();
1018
- }
1019
- else {
1062
+ } else if (lineBreak) {
1063
+ if (this.afterBreak) this.value = "";
1064
+ else {
1065
+ this.afterBreak = true;
1066
+ this.next();
1067
+ }
1068
+ } else {
1020
1069
  this.value = value;
1021
1070
  this.afterBreak = false;
1022
1071
  }
@@ -1074,7 +1123,7 @@ const DefaultSplit = /\r\n?|\n/;
1074
1123
  /**
1075
1124
  Distinguishes different ways in which positions can be mapped.
1076
1125
  */
1077
- var MapMode = /* @__PURE__ */ (function(MapMode) {
1126
+ var MapMode = /*@__PURE__*/ (function(MapMode) {
1078
1127
  /**
1079
1128
  Map a position to a valid new position, even when its context
1080
1129
  was deleted.
@@ -2047,7 +2096,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
2047
2096
  }
2048
2097
  };
2049
2098
  }
2050
- const initField = /* @__PURE__ */ Facet.define({ static: true });
2099
+ const initField = /*@__PURE__*/ Facet.define({ static: true });
2051
2100
  /**
2052
2101
  Fields can store additional information in an editor state, and
2053
2102
  keep it in sync with the rest of the state.
@@ -2149,11 +2198,30 @@ final ordering of extensions is determined by first sorting by
2149
2198
  precedence and then by order within each precedence.
2150
2199
  */
2151
2200
  const Prec = {
2152
- highest: /* @__PURE__ */ prec(Prec_.highest),
2153
- high: /* @__PURE__ */ prec(Prec_.high),
2154
- default: /* @__PURE__ */ prec(Prec_.default),
2155
- low: /* @__PURE__ */ prec(Prec_.low),
2156
- lowest: /* @__PURE__ */ prec(Prec_.lowest)
2201
+ /**
2202
+ The highest precedence level, for extensions that should end up
2203
+ near the start of the precedence ordering.
2204
+ */
2205
+ highest: /*@__PURE__*/ prec(Prec_.highest),
2206
+ /**
2207
+ A higher-than-default precedence, for extensions that should
2208
+ come before those with default precedence.
2209
+ */
2210
+ high: /*@__PURE__*/ prec(Prec_.high),
2211
+ /**
2212
+ The default precedence, which is also used for extensions
2213
+ without an explicit precedence.
2214
+ */
2215
+ default: /*@__PURE__*/ prec(Prec_.default),
2216
+ /**
2217
+ A lower-than-default precedence.
2218
+ */
2219
+ low: /*@__PURE__*/ prec(Prec_.low),
2220
+ /**
2221
+ The lowest precedence level. Meant for things that should end up
2222
+ near the end of the extension order.
2223
+ */
2224
+ lowest: /*@__PURE__*/ prec(Prec_.lowest)
2157
2225
  };
2158
2226
  var PrecExtension = class {
2159
2227
  constructor(inner, prec) {
@@ -2257,7 +2325,8 @@ var Configuration = class Configuration {
2257
2325
  dynamicSlots.push((a) => dynamicFacetSlot(a, facet, providers));
2258
2326
  }
2259
2327
  }
2260
- return new Configuration(base, newCompartments, dynamicSlots.map((f) => f(address)), address, staticValues, facets);
2328
+ let dynamic = dynamicSlots.map((f) => f(address));
2329
+ return new Configuration(base, newCompartments, dynamic, address, staticValues, facets);
2261
2330
  }
2262
2331
  };
2263
2332
  function flatten(extension, compartments, newCompartments) {
@@ -2314,19 +2383,19 @@ function ensureAddr(state, addr) {
2314
2383
  function getAddr(state, addr) {
2315
2384
  return addr & 1 ? state.config.staticValues[addr >> 1] : state.values[addr >> 1];
2316
2385
  }
2317
- const languageData = /* @__PURE__ */ Facet.define();
2318
- const allowMultipleSelections = /* @__PURE__ */ Facet.define({
2386
+ const languageData = /*@__PURE__*/ Facet.define();
2387
+ const allowMultipleSelections = /*@__PURE__*/ Facet.define({
2319
2388
  combine: (values) => values.some((v) => v),
2320
2389
  static: true
2321
2390
  });
2322
- const lineSeparator = /* @__PURE__ */ Facet.define({
2391
+ const lineSeparator = /*@__PURE__*/ Facet.define({
2323
2392
  combine: (values) => values.length ? values[0] : void 0,
2324
2393
  static: true
2325
2394
  });
2326
- const changeFilter = /* @__PURE__ */ Facet.define();
2327
- const transactionFilter = /* @__PURE__ */ Facet.define();
2328
- const transactionExtender = /* @__PURE__ */ Facet.define();
2329
- const readOnly = /* @__PURE__ */ Facet.define({ combine: (values) => values.length ? values[0] : false });
2395
+ const changeFilter = /*@__PURE__*/ Facet.define();
2396
+ const transactionFilter = /*@__PURE__*/ Facet.define();
2397
+ const transactionExtender = /*@__PURE__*/ Facet.define();
2398
+ const readOnly = /*@__PURE__*/ Facet.define({ combine: (values) => values.length ? values[0] : false });
2330
2399
  /**
2331
2400
  Annotations are tagged values that are used to add metadata to
2332
2401
  transactions in an extensible way. They should be used to model
@@ -2441,11 +2510,11 @@ the editor. Doing this will discard any extensions
2441
2510
  the content of [reconfigured](https://codemirror.net/6/docs/ref/#state.Compartment.reconfigure)
2442
2511
  compartments.
2443
2512
  */
2444
- StateEffect.reconfigure = /* @__PURE__ */ StateEffect.define();
2513
+ StateEffect.reconfigure = /*@__PURE__*/ StateEffect.define();
2445
2514
  /**
2446
2515
  Append extensions to the top-level configuration of the editor.
2447
2516
  */
2448
- StateEffect.appendConfig = /* @__PURE__ */ StateEffect.define();
2517
+ StateEffect.appendConfig = /*@__PURE__*/ StateEffect.define();
2449
2518
  /**
2450
2519
  Changes to the editor state are grouped into transactions.
2451
2520
  Typically, a user action creates a single transaction, which may
@@ -2547,7 +2616,7 @@ var Transaction = class Transaction {
2547
2616
  Annotation used to store transaction timestamps. Automatically
2548
2617
  added to every transaction, holding `Date.now()`.
2549
2618
  */
2550
- Transaction.time = /* @__PURE__ */ Annotation.define();
2619
+ Transaction.time = /*@__PURE__*/ Annotation.define();
2551
2620
  /**
2552
2621
  Annotation used to associate a transaction with a user interface
2553
2622
  event. Holds a string identifying the event, using a
@@ -2574,19 +2643,19 @@ information. The events used by the core libraries are:
2574
2643
  Use [`isUserEvent`](https://codemirror.net/6/docs/ref/#state.Transaction.isUserEvent) to check
2575
2644
  whether the annotation matches a given event.
2576
2645
  */
2577
- Transaction.userEvent = /* @__PURE__ */ Annotation.define();
2646
+ Transaction.userEvent = /*@__PURE__*/ Annotation.define();
2578
2647
  /**
2579
2648
  Annotation indicating whether a transaction should be added to
2580
2649
  the undo history or not.
2581
2650
  */
2582
- Transaction.addToHistory = /* @__PURE__ */ Annotation.define();
2651
+ Transaction.addToHistory = /*@__PURE__*/ Annotation.define();
2583
2652
  /**
2584
2653
  Annotation indicating (when present and true) that a transaction
2585
2654
  represents a change made by some other actor, not the user. This
2586
2655
  is used, for example, to tag other people's changes in
2587
2656
  collaborative editing.
2588
2657
  */
2589
- Transaction.remote = /* @__PURE__ */ Annotation.define();
2658
+ Transaction.remote = /*@__PURE__*/ Annotation.define();
2590
2659
  function joinRanges(a, b) {
2591
2660
  let result = [];
2592
2661
  for (let iA = 0, iB = 0;;) {
@@ -2693,7 +2762,7 @@ The categories produced by a [character
2693
2762
  categorizer](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer). These are used
2694
2763
  do things like selecting by word.
2695
2764
  */
2696
- var CharCategory = /* @__PURE__ */ (function(CharCategory) {
2765
+ var CharCategory = /*@__PURE__*/ (function(CharCategory) {
2697
2766
  /**
2698
2767
  Word characters.
2699
2768
  */
@@ -2711,7 +2780,7 @@ var CharCategory = /* @__PURE__ */ (function(CharCategory) {
2711
2780
  const nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
2712
2781
  let wordChar;
2713
2782
  try {
2714
- wordChar = /* @__PURE__ */ new RegExp("[\\p{Alphabetic}\\p{Number}_]", "u");
2783
+ wordChar = /*@__PURE__*/ new RegExp("[\\p{Alphabetic}\\p{Number}_]", "u");
2715
2784
  } catch (_) {}
2716
2785
  function hasWordChar(str) {
2717
2786
  if (wordChar) return wordChar.test(str);
@@ -3049,7 +3118,7 @@ Configures the tab size to use in this state. The first
3049
3118
  (highest-precedence) value of the facet is used. If no value is
3050
3119
  given, this defaults to 4.
3051
3120
  */
3052
- EditorState.tabSize = /* @__PURE__ */ Facet.define({ combine: (values) => values.length ? values[0] : 4 });
3121
+ EditorState.tabSize = /*@__PURE__*/ Facet.define({ combine: (values) => values.length ? values[0] : 4 });
3053
3122
  /**
3054
3123
  The line separator to use. By default, any of `"\n"`, `"\r\n"`
3055
3124
  and `"\r"` is treated as a separator when splitting lines, and
@@ -3080,7 +3149,7 @@ Registers translation phrases. The
3080
3149
  all objects registered with this facet to find translations for
3081
3150
  its argument.
3082
3151
  */
3083
- EditorState.phrases = /* @__PURE__ */ Facet.define({ compare(a, b) {
3152
+ EditorState.phrases = /*@__PURE__*/ Facet.define({ compare(a, b) {
3084
3153
  let kA = Object.keys(a), kB = Object.keys(b);
3085
3154
  return kA.length == kB.length && kA.every((k) => a[k] == b[k]);
3086
3155
  } });
@@ -3138,7 +3207,7 @@ but do want to process every transaction.
3138
3207
  Extenders run _after_ filters, when both are present.
3139
3208
  */
3140
3209
  EditorState.transactionExtender = transactionExtender;
3141
- Compartment.reconfigure = /* @__PURE__ */ StateEffect.define();
3210
+ Compartment.reconfigure = /*@__PURE__*/ StateEffect.define();
3142
3211
  /**
3143
3212
  Each range is associated with a value, which must inherit from
3144
3213
  this class.
@@ -3392,7 +3461,7 @@ var RangeSet = class RangeSet {
3392
3461
  if they are equivalent in the given range.
3393
3462
  */
3394
3463
  static eq(oldSets, newSets, from = 0, to) {
3395
- if (to == null) to = 999999999;
3464
+ if (to == null) to = 1e9 - 1;
3396
3465
  let a = oldSets.filter((set) => !set.isEmpty && newSets.indexOf(set) < 0);
3397
3466
  let b = newSets.filter((set) => !set.isEmpty && oldSets.indexOf(set) < 0);
3398
3467
  if (a.length != b.length) return false;
@@ -3457,7 +3526,7 @@ var RangeSet = class RangeSet {
3457
3526
  /**
3458
3527
  The empty set of ranges.
3459
3528
  */
3460
- RangeSet.empty = /* @__PURE__ */ new RangeSet([], [], null, -1);
3529
+ RangeSet.empty = /*@__PURE__*/ new RangeSet([], [], null, -1);
3461
3530
  function lazySort(ranges) {
3462
3531
  if (ranges.length > 1) for (let prev = ranges[0], i = 1; i < ranges.length; i++) {
3463
3532
  let cur = ranges[i];
@@ -3611,7 +3680,8 @@ var LayerCursor = class {
3611
3680
  break;
3612
3681
  } else {
3613
3682
  let chunkPos = this.layer.chunkPos[this.chunkIndex], chunk = this.layer.chunk[this.chunkIndex];
3614
- this.from = chunkPos + chunk.from[this.rangeIndex];
3683
+ let from = chunkPos + chunk.from[this.rangeIndex];
3684
+ this.from = from;
3615
3685
  this.to = chunkPos + chunk.to[this.rangeIndex];
3616
3686
  this.value = chunk.value[this.rangeIndex];
3617
3687
  this.setRangeIndex(this.rangeIndex + 1);
@@ -3851,11 +3921,10 @@ function findColumn(string, col, tabSize, strict) {
3851
3921
  }
3852
3922
  return strict === true ? -1 : string.length;
3853
3923
  }
3854
-
3855
3924
  //#endregion
3856
3925
  //#region node_modules/.pnpm/style-mod@4.1.3/node_modules/style-mod/src/style-mod.js
3857
3926
  const C = "ͼ";
3858
- const COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C);
3927
+ const COUNT = typeof Symbol == "undefined" ? "__ͼ" : Symbol.for(C);
3859
3928
  const SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet");
3860
3929
  const top = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : {};
3861
3930
  var StyleModule = class {
@@ -3944,7 +4013,6 @@ var StyleSet = class {
3944
4013
  if (this.styleTag && this.styleTag.getAttribute("nonce") != nonce) this.styleTag.setAttribute("nonce", nonce);
3945
4014
  }
3946
4015
  };
3947
-
3948
4016
  //#endregion
3949
4017
  //#region node_modules/.pnpm/w3c-keyname@2.2.8/node_modules/w3c-keyname/index.js
3950
4018
  var base = {
@@ -4027,8 +4095,8 @@ var shift = {
4027
4095
  221: "}",
4028
4096
  222: "\""
4029
4097
  };
4030
- var mac = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
4031
- var ie$1 = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
4098
+ typeof navigator != "undefined" && /Mac/.test(navigator.platform);
4099
+ typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
4032
4100
  for (var i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i);
4033
4101
  for (var i = 1; i <= 24; i++) base[i + 111] = "F" + i;
4034
4102
  for (var i = 65; i <= 90; i++) {
@@ -4036,40 +4104,39 @@ for (var i = 65; i <= 90; i++) {
4036
4104
  shift[i] = String.fromCharCode(i);
4037
4105
  }
4038
4106
  for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code];
4039
-
4040
4107
  //#endregion
4041
- //#region node_modules/.pnpm/@codemirror+view@6.39.11/node_modules/@codemirror/view/dist/index.js
4108
+ //#region node_modules/.pnpm/@codemirror+view@6.43.8/node_modules/@codemirror/view/dist/index.js
4042
4109
  let nav = typeof navigator != "undefined" ? navigator : {
4043
4110
  userAgent: "",
4044
4111
  vendor: "",
4045
4112
  platform: ""
4046
4113
  };
4047
4114
  let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
4048
- const ie_edge = /* @__PURE__ */ /Edge\/(\d+)/.exec(nav.userAgent);
4049
- const ie_upto10 = /* @__PURE__ */ /MSIE \d/.test(nav.userAgent);
4050
- const ie_11up = /* @__PURE__ */ /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
4115
+ const ie_edge = /*@__PURE__*/ /Edge\/(\d+)/.exec(nav.userAgent);
4116
+ const ie_upto10 = /*@__PURE__*/ /MSIE \d/.test(nav.userAgent);
4117
+ const ie_11up = /*@__PURE__*/ /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
4051
4118
  const ie = !!(ie_upto10 || ie_11up || ie_edge);
4052
- const gecko = !ie && /* @__PURE__ */ /gecko\/(\d+)/i.test(nav.userAgent);
4053
- const chrome = !ie && /* @__PURE__ */ /Chrome\/(\d+)/.exec(nav.userAgent);
4119
+ const gecko = !ie && /*@__PURE__*/ /gecko\/(\d+)/i.test(nav.userAgent);
4120
+ const chrome = !ie && /*@__PURE__*/ /Chrome\/(\d+)/.exec(nav.userAgent);
4054
4121
  const webkit = "webkitFontSmoothing" in doc.documentElement.style;
4055
- const safari = !ie && /* @__PURE__ */ /Apple Computer/.test(nav.vendor);
4056
- const ios = safari && (/* @__PURE__ */ /Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
4122
+ const safari = !ie && /*@__PURE__*/ /Apple Computer/.test(nav.vendor);
4123
+ const ios = safari && (/*@__PURE__*/ /Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
4057
4124
  var browser = {
4058
- mac: ios || /* @__PURE__ */ /Mac/.test(nav.platform),
4059
- windows: /* @__PURE__ */ /Win/.test(nav.platform),
4060
- linux: /* @__PURE__ */ /Linux|X11/.test(nav.platform),
4125
+ mac: ios || /*@__PURE__*/ /Mac/.test(nav.platform),
4126
+ windows: /*@__PURE__*/ /Win/.test(nav.platform),
4127
+ linux: /*@__PURE__*/ /Linux|X11/.test(nav.platform),
4061
4128
  ie,
4062
4129
  ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
4063
4130
  gecko,
4064
- gecko_version: gecko ? +(/* @__PURE__ */ /Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4131
+ gecko_version: gecko ? +(/*@__PURE__*/ /Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4065
4132
  chrome: !!chrome,
4066
4133
  chrome_version: chrome ? +chrome[1] : 0,
4067
4134
  ios,
4068
- android: /* @__PURE__ */ /Android\b/.test(nav.userAgent),
4135
+ android: /*@__PURE__*/ /Android\b/.test(nav.userAgent),
4069
4136
  webkit,
4070
- webkit_version: webkit ? +(/* @__PURE__ */ /\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4137
+ webkit_version: webkit ? +(/*@__PURE__*/ /\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4071
4138
  safari,
4072
- safari_version: safari ? +(/* @__PURE__ */ /\bVersion\/(\d+(\.\d+)?)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4139
+ safari_version: safari ? +(/*@__PURE__*/ /\bVersion\/(\d+(\.\d+)?)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4073
4140
  tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
4074
4141
  };
4075
4142
  function combineAttrs(source, target) {
@@ -4078,7 +4145,7 @@ function combineAttrs(source, target) {
4078
4145
  else target[name] = source[name];
4079
4146
  return target;
4080
4147
  }
4081
- const noAttrs = /* @__PURE__ */ Object.create(null);
4148
+ const noAttrs = /*@__PURE__*/ Object.create(null);
4082
4149
  function attrsEq(a, b, ignore) {
4083
4150
  if (a == b) return true;
4084
4151
  if (!a) a = noAttrs;
@@ -4152,7 +4219,7 @@ var WidgetType = class {
4152
4219
  couldn't (in which case the widget will be redrawn). The default
4153
4220
  implementation just returns false.
4154
4221
  */
4155
- updateDOM(dom, view) {
4222
+ updateDOM(dom, view, from) {
4156
4223
  return false;
4157
4224
  }
4158
4225
  /**
@@ -4218,7 +4285,7 @@ var WidgetType = class {
4218
4285
  /**
4219
4286
  The different types of blocks that can occur in an editor view.
4220
4287
  */
4221
- var BlockType = /* @__PURE__ */ (function(BlockType) {
4288
+ var BlockType = /*@__PURE__*/ (function(BlockType) {
4222
4289
  /**
4223
4290
  A line of text.
4224
4291
  */
@@ -4397,10 +4464,11 @@ widget that starts inside its range, including blocks starting
4397
4464
  directly at `from` but not including `to`.
4398
4465
  */
4399
4466
  var BlockWrapper = class BlockWrapper extends RangeValue {
4400
- constructor(tagName, attributes) {
4467
+ constructor(tagName, attributes, rank) {
4401
4468
  super();
4402
4469
  this.tagName = tagName;
4403
4470
  this.attributes = attributes;
4471
+ this.rank = rank;
4404
4472
  }
4405
4473
  eq(other) {
4406
4474
  return other == this || other instanceof BlockWrapper && this.tagName == other.tagName && attrsEq(this.attributes, other.attributes);
@@ -4410,7 +4478,7 @@ var BlockWrapper = class BlockWrapper extends RangeValue {
4410
4478
  attributes.
4411
4479
  */
4412
4480
  static create(spec) {
4413
- return new BlockWrapper(spec.tagName, spec.attributes || noAttrs);
4481
+ return new BlockWrapper(spec.tagName, spec.attributes || noAttrs, spec.rank == null ? 50 : Math.max(0, Math.min(spec.rank, 100)));
4414
4482
  }
4415
4483
  /**
4416
4484
  Create a range set from the given block wrapper ranges.
@@ -4473,8 +4541,10 @@ function scanFor(node, off, targetNode, targetOff, dir) {
4473
4541
  function maxOffset(node) {
4474
4542
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
4475
4543
  }
4476
- function flattenRect(rect, left) {
4477
- let x = left ? rect.left : rect.right;
4544
+ function flattenRect(rect, toLeft) {
4545
+ let { left, right } = rect;
4546
+ if (left == right) return rect;
4547
+ let x = toLeft ? left : right;
4478
4548
  return {
4479
4549
  left: x,
4480
4550
  right: x,
@@ -4530,10 +4600,10 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
4530
4600
  }
4531
4601
  let moveX = 0, moveY = 0;
4532
4602
  if (y == "nearest") {
4533
- if (rect.top < bounding.top) {
4603
+ if (rect.top < bounding.top + yMargin) {
4534
4604
  moveY = rect.top - (bounding.top + yMargin);
4535
4605
  if (side > 0 && rect.bottom > bounding.bottom + moveY) moveY = rect.bottom - bounding.bottom + yMargin;
4536
- } else if (rect.bottom > bounding.bottom) {
4606
+ } else if (rect.bottom > bounding.bottom - yMargin) {
4537
4607
  moveY = rect.bottom - bounding.bottom + yMargin;
4538
4608
  if (side < 0 && rect.top - moveY < bounding.top) moveY = rect.top - (bounding.top + yMargin);
4539
4609
  }
@@ -4542,35 +4612,37 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
4542
4612
  moveY = (y == "center" && rectHeight <= boundingHeight ? rect.top + rectHeight / 2 - boundingHeight / 2 : y == "start" || y == "center" && side < 0 ? rect.top - yMargin : rect.bottom - boundingHeight + yMargin) - bounding.top;
4543
4613
  }
4544
4614
  if (x == "nearest") {
4545
- if (rect.left < bounding.left) {
4615
+ if (rect.left < bounding.left + xMargin) {
4546
4616
  moveX = rect.left - (bounding.left + xMargin);
4547
4617
  if (side > 0 && rect.right > bounding.right + moveX) moveX = rect.right - bounding.right + xMargin;
4548
- } else if (rect.right > bounding.right) {
4618
+ } else if (rect.right > bounding.right - xMargin) {
4549
4619
  moveX = rect.right - bounding.right + xMargin;
4550
4620
  if (side < 0 && rect.left < bounding.left + moveX) moveX = rect.left - (bounding.left + xMargin);
4551
4621
  }
4552
4622
  } else moveX = (x == "center" ? rect.left + (rect.right - rect.left) / 2 - (bounding.right - bounding.left) / 2 : x == "start" == ltr ? rect.left - xMargin : rect.right - (bounding.right - bounding.left) + xMargin) - bounding.left;
4553
- if (moveX || moveY) if (top) win.scrollBy(moveX, moveY);
4554
- else {
4555
- let movedX = 0, movedY = 0;
4556
- if (moveY) {
4557
- let start = cur.scrollTop;
4558
- cur.scrollTop += moveY / scaleY;
4559
- movedY = (cur.scrollTop - start) * scaleY;
4560
- }
4561
- if (moveX) {
4562
- let start = cur.scrollLeft;
4563
- cur.scrollLeft += moveX / scaleX;
4564
- movedX = (cur.scrollLeft - start) * scaleX;
4565
- }
4566
- rect = {
4567
- left: rect.left - movedX,
4568
- top: rect.top - movedY,
4569
- right: rect.right - movedX,
4570
- bottom: rect.bottom - movedY
4571
- };
4572
- if (movedX && Math.abs(movedX - moveX) < 1) x = "nearest";
4573
- if (movedY && Math.abs(movedY - moveY) < 1) y = "nearest";
4623
+ if (moveX || moveY) {
4624
+ if (top) win.scrollBy(moveX, moveY);
4625
+ else {
4626
+ let movedX = 0, movedY = 0;
4627
+ if (moveY) {
4628
+ let start = cur.scrollTop;
4629
+ cur.scrollTop += moveY / scaleY;
4630
+ movedY = (cur.scrollTop - start) * scaleY;
4631
+ }
4632
+ if (moveX) {
4633
+ let start = cur.scrollLeft;
4634
+ cur.scrollLeft += moveX / scaleX;
4635
+ movedX = (cur.scrollLeft - start) * scaleX;
4636
+ }
4637
+ rect = {
4638
+ left: rect.left - movedX,
4639
+ top: rect.top - movedY,
4640
+ right: rect.right - movedX,
4641
+ bottom: rect.bottom - movedY
4642
+ };
4643
+ if (movedX && Math.abs(movedX - moveX) < 1) x = "nearest";
4644
+ if (movedY && Math.abs(movedY - moveY) < 1) y = "nearest";
4645
+ }
4574
4646
  }
4575
4647
  if (top) break;
4576
4648
  if (rect.top < bounding.top || rect.bottom > bounding.bottom || rect.left < bounding.left || rect.right > bounding.right) rect = {
@@ -4583,12 +4655,12 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
4583
4655
  } else if (cur.nodeType == 11) cur = cur.host;
4584
4656
  else break;
4585
4657
  }
4586
- function scrollableParents(dom) {
4587
- let doc = dom.ownerDocument, x, y;
4588
- for (let cur = dom.parentNode; cur;) if (cur == doc.body || x && y) break;
4658
+ function scrollableParents(dom, getX = true) {
4659
+ let doc = dom.ownerDocument, x = null, y = null;
4660
+ for (let cur = dom.parentNode; cur;) if (cur == doc.body || (!getX || x) && y) break;
4589
4661
  else if (cur.nodeType == 1) {
4590
4662
  if (!y && cur.scrollHeight > cur.clientHeight) y = cur;
4591
- if (!x && cur.scrollWidth > cur.clientWidth) x = cur;
4663
+ if (getX && !x && cur.scrollWidth > cur.clientWidth) x = cur;
4592
4664
  cur = cur.assignedSlot || cur.parentNode;
4593
4665
  } else if (cur.nodeType == 11) cur = cur.host;
4594
4666
  else break;
@@ -4618,27 +4690,34 @@ var DOMSelectionState = class {
4618
4690
  this.focusOffset = focusOffset;
4619
4691
  }
4620
4692
  };
4693
+ function getScrollStack(target) {
4694
+ let stack = [];
4695
+ for (let cur = target; cur; cur = cur.nodeType == 11 ? cur.host : cur.parentNode) if (cur.nodeType == 1) stack.push({
4696
+ node: cur,
4697
+ left: cur.scrollLeft,
4698
+ top: cur.scrollTop
4699
+ });
4700
+ return stack;
4701
+ }
4702
+ function restoreScrollStack(stack, vert = true) {
4703
+ for (let { node, left, top } of stack) {
4704
+ if (vert && node.scrollTop != top) node.scrollTop = top;
4705
+ if (node.scrollLeft != left) node.scrollLeft = left;
4706
+ }
4707
+ }
4621
4708
  let preventScrollSupported = null;
4622
4709
  if (browser.safari && browser.safari_version >= 26) preventScrollSupported = false;
4623
4710
  function focusPreventScroll(dom) {
4624
4711
  if (dom.setActive) return dom.setActive();
4625
4712
  if (preventScrollSupported) return dom.focus(preventScrollSupported);
4626
- let stack = [];
4627
- for (let cur = dom; cur; cur = cur.parentNode) {
4628
- stack.push(cur, cur.scrollTop, cur.scrollLeft);
4629
- if (cur == cur.ownerDocument) break;
4630
- }
4713
+ let stack = getScrollStack(dom);
4631
4714
  dom.focus(preventScrollSupported == null ? { get preventScroll() {
4632
4715
  preventScrollSupported = { preventScroll: true };
4633
4716
  return true;
4634
4717
  } } : void 0);
4635
4718
  if (!preventScrollSupported) {
4636
4719
  preventScrollSupported = false;
4637
- for (let i = 0; i < stack.length;) {
4638
- let elt = stack[i++], top = stack[i++], left = stack[i++];
4639
- if (elt.scrollTop != top) elt.scrollTop = top;
4640
- if (elt.scrollLeft != left) elt.scrollLeft = left;
4641
- }
4720
+ restoreScrollStack(stack);
4642
4721
  }
4643
4722
  }
4644
4723
  let scratchRange;
@@ -4691,6 +4770,7 @@ function atElementStart(doc, selection) {
4691
4770
  }
4692
4771
  }
4693
4772
  function isScrolledToBottom(elt) {
4773
+ if (elt instanceof Window) return elt.pageYOffset > Math.max(0, elt.document.documentElement.scrollHeight - elt.innerHeight - 4);
4694
4774
  return elt.scrollTop > Math.max(1, elt.scrollHeight - elt.clientHeight - 4);
4695
4775
  }
4696
4776
  function textNodeBefore(startNode, startOffset) {
@@ -4737,7 +4817,7 @@ var DOMPos = class DOMPos {
4737
4817
  /**
4738
4818
  Used to indicate [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection).
4739
4819
  */
4740
- var Direction = /* @__PURE__ */ (function(Direction) {
4820
+ var Direction = /*@__PURE__*/ (function(Direction) {
4741
4821
  /**
4742
4822
  Left-to-right.
4743
4823
  */
@@ -4748,21 +4828,23 @@ var Direction = /* @__PURE__ */ (function(Direction) {
4748
4828
  Direction[Direction["RTL"] = 1] = "RTL";
4749
4829
  return Direction;
4750
4830
  })(Direction || (Direction = {}));
4751
- const LTR = Direction.LTR, RTL = Direction.RTL;
4831
+ const LTR = Direction.LTR;
4832
+ const RTL = Direction.RTL;
4752
4833
  function dec(str) {
4753
4834
  let result = [];
4754
4835
  for (let i = 0; i < str.length; i++) result.push(1 << +str[i]);
4755
4836
  return result;
4756
4837
  }
4757
- const LowTypes = /* @__PURE__ */ dec("88888888888888888888888888888888888666888888787833333333337888888000000000000000000000000008888880000000000000000000000000088888888888888888888888888888888888887866668888088888663380888308888800000000000000000000000800000000000000000000000000000008");
4758
- const ArabicTypes = /* @__PURE__ */ dec("4444448826627288999999999992222222222222222222222222222222222222222222222229999999999999999999994444444444644222822222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222999999949999999229989999223333333333");
4759
- const Brackets = /* @__PURE__ */ Object.create(null), BracketStack = [];
4838
+ const LowTypes = /*@__PURE__*/ dec("88888888888888888888888888888888888666888888787833333333337888888000000000000000000000000008888880000000000000000000000000088888888888888888888888888888888888887866668888088888663380888308888800000000000000000000000800000000000000000000000000000008");
4839
+ const ArabicTypes = /*@__PURE__*/ dec("4444448826627288999999999992222222222222222222222222222222222222222222222229999999999999999999994444444444644222822222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222999999949999999229989999223333333333");
4840
+ const Brackets = /*@__PURE__*/ Object.create(null);
4841
+ const BracketStack = [];
4760
4842
  for (let p of [
4761
4843
  "()",
4762
4844
  "[]",
4763
4845
  "{}"
4764
4846
  ]) {
4765
- let l = /* @__PURE__ */ p.charCodeAt(0), r = /* @__PURE__ */ p.charCodeAt(1);
4847
+ let l = /*@__PURE__*/ p.charCodeAt(0), r = /*@__PURE__*/ p.charCodeAt(1);
4766
4848
  Brackets[l] = r;
4767
4849
  Brackets[r] = -l;
4768
4850
  }
@@ -4840,9 +4922,10 @@ function computeCharTypes(line, rFrom, rTo, isolates, outerType) {
4840
4922
  }
4841
4923
  for (let i = from, prev = prevType, prevStrong = prevType; i < to; i++) {
4842
4924
  let type = types[i];
4843
- if (type == 128) if (i < to - 1 && prev == types[i + 1] && prev & 24) type = types[i] = prev;
4844
- else types[i] = 256;
4845
- else if (type == 64) {
4925
+ if (type == 128) {
4926
+ if (i < to - 1 && prev == types[i + 1] && prev & 24) type = types[i] = prev;
4927
+ else types[i] = 256;
4928
+ } else if (type == 64) {
4846
4929
  let end = i + 1;
4847
4930
  while (end < to && types[end] == 64) end++;
4848
4931
  let replace = i && prev == 8 || end < rTo && types[end] == 8 ? prevStrong == 1 ? 1 : 8 : 256;
@@ -4858,21 +4941,22 @@ function processBracketPairs(line, rFrom, rTo, isolates, outerType) {
4858
4941
  let oppositeType = outerType == 1 ? 2 : 1;
4859
4942
  for (let iI = 0, sI = 0, context = 0; iI <= isolates.length; iI++) {
4860
4943
  let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
4861
- for (let i = from, ch, br, type; i < to; i++) if (br = Brackets[ch = line.charCodeAt(i)]) if (br < 0) {
4862
- for (let sJ = sI - 3; sJ >= 0; sJ -= 3) if (BracketStack[sJ + 1] == -br) {
4863
- let flags = BracketStack[sJ + 2];
4864
- let type = flags & 2 ? outerType : !(flags & 4) ? 0 : flags & 1 ? oppositeType : outerType;
4865
- if (type) types[i] = types[BracketStack[sJ]] = type;
4866
- sI = sJ;
4867
- break;
4944
+ for (let i = from, ch, br, type; i < to; i++) if (br = Brackets[ch = line.charCodeAt(i)]) {
4945
+ if (br < 0) {
4946
+ for (let sJ = sI - 3; sJ >= 0; sJ -= 3) if (BracketStack[sJ + 1] == -br) {
4947
+ let flags = BracketStack[sJ + 2];
4948
+ let type = flags & 2 ? outerType : !(flags & 4) ? 0 : flags & 1 ? oppositeType : outerType;
4949
+ if (type) types[i] = types[BracketStack[sJ]] = type;
4950
+ sI = sJ;
4951
+ break;
4952
+ }
4953
+ } else if (BracketStack.length == 189) break;
4954
+ else {
4955
+ BracketStack[sI++] = i;
4956
+ BracketStack[sI++] = ch;
4957
+ BracketStack[sI++] = context;
4868
4958
  }
4869
- } else if (BracketStack.length == 189) break;
4870
- else {
4871
- BracketStack[sI++] = i;
4872
- BracketStack[sI++] = ch;
4873
- BracketStack[sI++] = context;
4874
- }
4875
- else if ((type = types[i]) == 2 || type == 1) {
4959
+ } else if ((type = types[i]) == 2 || type == 1) {
4876
4960
  let embed = type == outerType;
4877
4961
  context = embed ? 0 : 1;
4878
4962
  for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
@@ -5035,20 +5119,20 @@ function autoDirection(text, from, to) {
5035
5119
  }
5036
5120
  return LTR;
5037
5121
  }
5038
- const clickAddsSelectionRange = /* @__PURE__ */ Facet.define();
5039
- const dragMovesSelection$1 = /* @__PURE__ */ Facet.define();
5040
- const mouseSelectionStyle = /* @__PURE__ */ Facet.define();
5041
- const exceptionSink = /* @__PURE__ */ Facet.define();
5042
- const updateListener = /* @__PURE__ */ Facet.define();
5043
- const inputHandler = /* @__PURE__ */ Facet.define();
5044
- const focusChangeEffect = /* @__PURE__ */ Facet.define();
5045
- const clipboardInputFilter = /* @__PURE__ */ Facet.define();
5046
- const clipboardOutputFilter = /* @__PURE__ */ Facet.define();
5047
- const perLineTextDirection = /* @__PURE__ */ Facet.define({ combine: (values) => values.some((x) => x) });
5048
- const nativeSelectionHidden = /* @__PURE__ */ Facet.define({ combine: (values) => values.some((x) => x) });
5049
- const scrollHandler = /* @__PURE__ */ Facet.define();
5122
+ const clickAddsSelectionRange = /*@__PURE__*/ Facet.define();
5123
+ const dragMovesSelection$1 = /*@__PURE__*/ Facet.define();
5124
+ const mouseSelectionStyle = /*@__PURE__*/ Facet.define();
5125
+ const exceptionSink = /*@__PURE__*/ Facet.define();
5126
+ const updateListener = /*@__PURE__*/ Facet.define();
5127
+ const inputHandler = /*@__PURE__*/ Facet.define();
5128
+ const focusChangeEffect = /*@__PURE__*/ Facet.define();
5129
+ const clipboardInputFilter = /*@__PURE__*/ Facet.define();
5130
+ const clipboardOutputFilter = /*@__PURE__*/ Facet.define();
5131
+ const perLineTextDirection = /*@__PURE__*/ Facet.define({ combine: (values) => values.some((x) => x) });
5132
+ const nativeSelectionHidden = /*@__PURE__*/ Facet.define({ combine: (values) => values.some((x) => x) });
5133
+ const scrollHandler = /*@__PURE__*/ Facet.define();
5050
5134
  var ScrollTarget = class ScrollTarget {
5051
- constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5, isSnapshot = false) {
5135
+ constructor(range, y, x, yMargin, xMargin, isSnapshot = false) {
5052
5136
  this.range = range;
5053
5137
  this.y = y;
5054
5138
  this.x = x;
@@ -5063,8 +5147,8 @@ var ScrollTarget = class ScrollTarget {
5063
5147
  return this.range.to <= state.doc.length ? this : new ScrollTarget(EditorSelection.cursor(state.doc.length), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
5064
5148
  }
5065
5149
  };
5066
- const scrollIntoView = /* @__PURE__ */ StateEffect.define({ map: (t, ch) => t.map(ch) });
5067
- const setEditContextFormatting = /* @__PURE__ */ StateEffect.define();
5150
+ const scrollIntoView = /*@__PURE__*/ StateEffect.define({ map: (t, ch) => t.map(ch) });
5151
+ const setEditContextFormatting = /*@__PURE__*/ StateEffect.define();
5068
5152
  /**
5069
5153
  Log or report an unhandled exception in client code. Should
5070
5154
  probably only be used by extension code that allows client code to
@@ -5084,9 +5168,9 @@ function logException(state, exception, context) {
5084
5168
  else if (context) console.error(context + ":", exception);
5085
5169
  else console.error(exception);
5086
5170
  }
5087
- const editable = /* @__PURE__ */ Facet.define({ combine: (values) => values.length ? values[0] : true });
5171
+ const editable = /*@__PURE__*/ Facet.define({ combine: (values) => values.length ? values[0] : true });
5088
5172
  let nextPluginID = 0;
5089
- const viewPlugin = /* @__PURE__ */ Facet.define({ combine(plugins) {
5173
+ const viewPlugin = /*@__PURE__*/ Facet.define({ combine(plugins) {
5090
5174
  return plugins.filter((p, i) => {
5091
5175
  for (let j = 0; j < i; j++) if (plugins[j].plugin == p.plugin) return false;
5092
5176
  return true;
@@ -5189,13 +5273,13 @@ var PluginInstance = class {
5189
5273
  this.spec = this.value = null;
5190
5274
  }
5191
5275
  };
5192
- const editorAttributes = /* @__PURE__ */ Facet.define();
5193
- const contentAttributes = /* @__PURE__ */ Facet.define();
5194
- const decorations = /* @__PURE__ */ Facet.define();
5195
- const blockWrappers = /* @__PURE__ */ Facet.define();
5196
- const outerDecorations = /* @__PURE__ */ Facet.define();
5197
- const atomicRanges = /* @__PURE__ */ Facet.define();
5198
- const bidiIsolatedRanges = /* @__PURE__ */ Facet.define();
5276
+ const editorAttributes = /*@__PURE__*/ Facet.define();
5277
+ const contentAttributes = /*@__PURE__*/ Facet.define();
5278
+ const decorations = /*@__PURE__*/ Facet.define();
5279
+ const blockWrappers = /*@__PURE__*/ Facet.define();
5280
+ const outerDecorations = /*@__PURE__*/ Facet.define();
5281
+ const atomicRanges = /*@__PURE__*/ Facet.define();
5282
+ const bidiIsolatedRanges = /*@__PURE__*/ Facet.define();
5199
5283
  function getIsolatedRanges(view, line) {
5200
5284
  let isolates = view.state.facet(bidiIsolatedRanges);
5201
5285
  if (!isolates.length) return isolates;
@@ -5227,7 +5311,7 @@ function getIsolatedRanges(view, line) {
5227
5311
  });
5228
5312
  return result;
5229
5313
  }
5230
- const scrollMargins = /* @__PURE__ */ Facet.define();
5314
+ const scrollMargins = /*@__PURE__*/ Facet.define();
5231
5315
  function getScrollMargins(view) {
5232
5316
  let left = 0, right = 0, top = 0, bottom = 0;
5233
5317
  for (let source of view.state.facet(scrollMargins)) {
@@ -5246,7 +5330,7 @@ function getScrollMargins(view) {
5246
5330
  bottom
5247
5331
  };
5248
5332
  }
5249
- const styleModule = /* @__PURE__ */ Facet.define();
5333
+ const styleModule = /*@__PURE__*/ Facet.define();
5250
5334
  var ChangedRange = class ChangedRange {
5251
5335
  constructor(fromA, toA, fromB, toB) {
5252
5336
  this.fromA = fromA;
@@ -5451,7 +5535,7 @@ var Tile = class {
5451
5535
  covers(side) {
5452
5536
  return true;
5453
5537
  }
5454
- coordsIn(pos, side) {
5538
+ coordsIn(pos, side, rtl) {
5455
5539
  return null;
5456
5540
  }
5457
5541
  domPosFor(off, side) {
@@ -5632,10 +5716,10 @@ var LineTile = class LineTile extends CompositeTile {
5632
5716
  let child = tile.children[i], end = off + child.length;
5633
5717
  if (end >= pos) {
5634
5718
  if (child.isComposite()) scan(child, pos - off);
5635
- else if ((!after || after.isHidden && (side > 0 || forCoords && onSameLine(after, child))) && (end > pos || child.flags & 32)) {
5719
+ else if ((!after || after.isHidden && (side > 0 && !(after.flags & 32) || forCoords && onSameLine(after, child))) && (end > pos || child.flags & 32 && side <= 1)) {
5636
5720
  after = child;
5637
5721
  afterOff = pos - off;
5638
- } else if (off < pos || child.flags & 16 && !child.isHidden) {
5722
+ } else if (off < pos || child.flags & 16 && !child.isHidden && side >= -1) {
5639
5723
  before = child;
5640
5724
  beforeOff = pos - off;
5641
5725
  }
@@ -5650,10 +5734,10 @@ var LineTile = class LineTile extends CompositeTile {
5650
5734
  offset: target == before ? beforeOff : afterOff
5651
5735
  } : null;
5652
5736
  }
5653
- coordsIn(pos, side) {
5737
+ coordsIn(pos, side, rtl) {
5654
5738
  let found = this.resolveInline(pos, side, true);
5655
5739
  if (!found) return fallbackRect(this);
5656
- return found.tile.coordsIn(Math.max(0, found.offset), side);
5740
+ return found.tile.coordsIn(Math.max(0, found.offset), side, rtl);
5657
5741
  }
5658
5742
  domIn(pos, side) {
5659
5743
  let found = this.resolveInline(pos, side);
@@ -5715,7 +5799,7 @@ var TextTile = class TextTile extends Tile {
5715
5799
  toString() {
5716
5800
  return JSON.stringify(this.text);
5717
5801
  }
5718
- coordsIn(pos, side) {
5802
+ coordsIn(pos, side, rtl) {
5719
5803
  let length = this.dom.nodeValue.length;
5720
5804
  if (pos > length) pos = length;
5721
5805
  let from = pos, to = pos, flatten = 0;
@@ -5735,7 +5819,7 @@ var TextTile = class TextTile extends Tile {
5735
5819
  if (!rects.length) return null;
5736
5820
  let rect = rects[(flatten ? flatten < 0 : side >= 0) ? 0 : rects.length - 1];
5737
5821
  if (browser.safari && !flatten && rect.width == 0) rect = Array.prototype.find.call(rects, (r) => r.width) || rect;
5738
- return flatten ? flattenRect(rect, flatten < 0) : rect || null;
5822
+ return rtl == null ? rect : flattenRect(rect, (flatten ? flatten > 0 : side < 0) == rtl);
5739
5823
  }
5740
5824
  static of(text, dom) {
5741
5825
  let tile = new TextTile(dom || document.createTextNode(text), text);
@@ -5808,8 +5892,9 @@ var WidgetBufferTile = class extends Tile {
5808
5892
  get overrideDOMText() {
5809
5893
  return Text.empty;
5810
5894
  }
5811
- coordsIn(pos) {
5812
- return this.dom.getBoundingClientRect();
5895
+ coordsIn(pos, side, rtl) {
5896
+ let rect = this.dom.getBoundingClientRect();
5897
+ return rtl == null ? rect : flattenRect(rect, side > 0 == rtl);
5813
5898
  }
5814
5899
  };
5815
5900
  var TilePointer = class {
@@ -5821,18 +5906,20 @@ var TilePointer = class {
5821
5906
  }
5822
5907
  advance(dist, side, walker) {
5823
5908
  let { tile, index, beforeBreak, parents } = this;
5824
- while (dist || side > 0) if (!tile.isComposite()) if (index == tile.length) {
5825
- beforeBreak = !!tile.breakAfter;
5826
- ({tile, index} = parents.pop());
5827
- index++;
5828
- } else if (!dist) break;
5829
- else {
5830
- let take = Math.min(dist, tile.length - index);
5831
- if (walker) walker.skip(tile, index, index + take);
5832
- dist -= take;
5833
- index += take;
5834
- }
5835
- else if (beforeBreak) {
5909
+ while (dist || side > 0) if (!tile.isComposite()) {
5910
+ let len = tile.length;
5911
+ if (index < len && dist) {
5912
+ let take = Math.min(dist, len - index);
5913
+ if (walker) walker.skip(tile, index, index + take);
5914
+ dist -= take;
5915
+ index += take;
5916
+ }
5917
+ if (index == len) {
5918
+ beforeBreak = !!tile.breakAfter;
5919
+ ({tile, index} = parents.pop());
5920
+ index++;
5921
+ } else if (!dist) break;
5922
+ } else if (beforeBreak) {
5836
5923
  if (!dist) break;
5837
5924
  if (walker) walker.break();
5838
5925
  dist--;
@@ -5893,7 +5980,7 @@ var TileBuilder = class {
5893
5980
  this.flushBuffer();
5894
5981
  let parent = this.ensureMarks(marks, openStart);
5895
5982
  let prev = parent.lastChild;
5896
- if (prev && prev.isText() && !(prev.flags & 8)) {
5983
+ if (prev && prev.isText() && !(prev.flags & 8) && prev.length + text.length < 512) {
5897
5984
  this.cache.reused.set(prev, 2);
5898
5985
  let tile = parent.children[parent.children.length - 1] = new TextTile(prev.dom, prev.text + text);
5899
5986
  tile.parent = parent;
@@ -5929,6 +6016,7 @@ var TileBuilder = class {
5929
6016
  if (oldTile) this.cache.reused.set(oldTile, 2);
5930
6017
  let text = new TextTile(composition.text, composition.text.nodeValue);
5931
6018
  text.flags |= 8;
6019
+ this.pos = composition.range.toB;
5932
6020
  head.append(text);
5933
6021
  }
5934
6022
  addInlineWidget(widget, marks, openStart) {
@@ -6012,7 +6100,8 @@ var TileBuilder = class {
6012
6100
  }
6013
6101
  for (let i = this.wrappers.length - 1; i >= 0; i--) if (this.wrappers[i].to < this.pos) this.wrappers.splice(i, 1);
6014
6102
  for (let cur = this.blockWrappers; cur.value && cur.from <= this.pos; cur.next()) if (cur.to >= this.pos) {
6015
- let wrap = new OpenWrapper(cur.from, cur.to, cur.value, cur.rank), i = this.wrappers.length;
6103
+ let rank = cur.rank * 102 + cur.value.rank;
6104
+ let wrap = new OpenWrapper(cur.from, cur.to, cur.value, rank), i = this.wrappers.length;
6016
6105
  while (i > 0 && (this.wrappers[i - 1].rank - wrap.rank || this.wrappers[i - 1].to - wrap.to) < 0) i--;
6017
6106
  this.wrappers.splice(i, 0, wrap);
6018
6107
  }
@@ -6105,7 +6194,7 @@ var TileCache = class {
6105
6194
  find(cls, test, type = 2) {
6106
6195
  let i = cls.bucket;
6107
6196
  let bucket = this.buckets[i], off = this.index[i];
6108
- for (let j = bucket.length - 1; j >= 0; j--) {
6197
+ for (let j = 0; j < bucket.length; j++) {
6109
6198
  let index = (j + off) % bucket.length, tile = bucket[index];
6110
6199
  if ((!test || test(tile)) && !this.reused.has(tile)) {
6111
6200
  bucket.splice(index, 1);
@@ -6125,7 +6214,7 @@ var TileCache = class {
6125
6214
  i = 0;
6126
6215
  }
6127
6216
  let tile = widgets[i];
6128
- if (!this.reused.has(tile) && (pass == 0 ? tile.widget.compare(widget) : tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view))) {
6217
+ if (!this.reused.has(tile) && (pass == 0 ? tile.widget.compare(widget) : tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view, tile.widget))) {
6129
6218
  widgets.splice(i, 1);
6130
6219
  if (i < this.index[0]) this.index[0]--;
6131
6220
  if (tile.widget == widget && tile.length == length && (tile.flags & 497) == flags) {
@@ -6188,6 +6277,7 @@ var TileUpdate = class {
6188
6277
  if (composition && next.fromA <= composition.range.fromA && next.toA >= composition.range.toA) {
6189
6278
  this.forward(next.fromA, composition.range.fromA, composition.range.fromA < composition.range.toA ? 1 : -1);
6190
6279
  this.emit(posB, composition.range.fromB);
6280
+ this.builder.flushBuffer();
6191
6281
  this.cache.clear();
6192
6282
  this.builder.addComposition(composition, compositionContext);
6193
6283
  this.text.skip(composition.range.toB - composition.range.fromB);
@@ -6207,21 +6297,22 @@ var TileUpdate = class {
6207
6297
  let activeMarks = getMarks(this.old), openMarks = this.openMarks;
6208
6298
  this.old.advance(length, incEnd ? 1 : -1, {
6209
6299
  skip: (tile, from, to) => {
6210
- if (tile.isWidget()) if (this.openWidget) this.builder.continueWidget(to - from);
6211
- else {
6212
- let widget = to > 0 || from < tile.length ? WidgetTile.of(tile.widget, this.view, to - from, tile.flags & 496, this.cache.maybeReuse(tile)) : this.cache.reuse(tile);
6213
- if (widget.flags & 256) {
6214
- widget.flags &= -2;
6215
- this.builder.addBlockWidget(widget);
6216
- } else {
6217
- this.builder.ensureLine(null);
6218
- this.builder.addInlineWidget(widget, activeMarks, openMarks);
6219
- openMarks = activeMarks.length;
6300
+ if (tile.isWidget()) {
6301
+ if (this.openWidget) this.builder.continueWidget(to - from);
6302
+ else {
6303
+ let widget = to > 0 || from < tile.length ? WidgetTile.of(tile.widget, this.view, to - from, tile.flags & 496, this.cache.maybeReuse(tile)) : this.cache.reuse(tile);
6304
+ if (widget.flags & 256) {
6305
+ widget.flags &= -2;
6306
+ this.builder.addBlockWidget(widget);
6307
+ } else {
6308
+ this.builder.ensureLine(null);
6309
+ this.builder.addInlineWidget(widget, activeMarks, openMarks);
6310
+ openMarks = activeMarks.length;
6311
+ }
6220
6312
  }
6221
- }
6222
- else if (tile.isText()) {
6313
+ } else if (tile.isText()) {
6223
6314
  this.builder.ensureLine(null);
6224
- if (!from && to == tile.length) this.builder.addText(tile.text, activeMarks, openMarks, this.cache.reuse(tile));
6315
+ if (!from && to == tile.length && !this.cache.reused.has(tile)) this.builder.addText(tile.text, activeMarks, openMarks, this.cache.reuse(tile));
6225
6316
  else {
6226
6317
  this.cache.add(tile);
6227
6318
  this.builder.addText(tile.text.slice(from, to), activeMarks, openMarks);
@@ -6265,7 +6356,7 @@ var TileUpdate = class {
6265
6356
  }
6266
6357
  emit(from, to) {
6267
6358
  let pendingLineAttrs = null;
6268
- let b = this.builder, markCount = 0;
6359
+ let b = this.builder, markCount = -1;
6269
6360
  let openEnd = RangeSet.spans(this.decorations, from, to, {
6270
6361
  point: (from, to, deco, active, openStart, index) => {
6271
6362
  if (deco instanceof PointDecoration) {
@@ -6300,15 +6391,16 @@ var TileUpdate = class {
6300
6391
  pos++;
6301
6392
  } else {
6302
6393
  b.ensureLine(pendingLineAttrs);
6303
- b.addText(chars, active, openStart);
6394
+ b.addText(chars, active, pos == from ? openStart : active.length);
6304
6395
  pos += chars.length;
6305
6396
  }
6306
6397
  pendingLineAttrs = null;
6307
6398
  }
6399
+ markCount = active.length;
6308
6400
  }
6309
6401
  });
6310
- b.addLineStartIfNotCovered(pendingLineAttrs);
6311
- this.openWidget = openEnd > markCount;
6402
+ if (markCount > -1) this.openWidget = openEnd > markCount;
6403
+ if (!this.openWidget) b.addLineStartIfNotCovered(pendingLineAttrs);
6312
6404
  this.openMarks = openEnd;
6313
6405
  }
6314
6406
  forward(from, to, side = 1) {
@@ -6326,8 +6418,9 @@ var TileUpdate = class {
6326
6418
  if (parent == this.view.contentDOM) break;
6327
6419
  if (tile instanceof MarkTile) marks.push(tile);
6328
6420
  else if (tile === null || tile === void 0 ? void 0 : tile.isLine()) line = tile;
6421
+ else if (tile instanceof BlockWrapperTile);
6329
6422
  else if (parent.nodeName == "DIV" && !line && parent != this.view.contentDOM) line = new LineTile(parent, lineBaseAttrs);
6330
- else marks.push(MarkTile.of(new MarkDecoration({
6423
+ else if (!line) marks.push(MarkTile.of(new MarkDecoration({
6331
6424
  tagName: parent.nodeName.toLowerCase(),
6332
6425
  attributes: getAttrs(parent)
6333
6426
  }), parent));
@@ -6390,9 +6483,9 @@ var NullWidget = class extends WidgetType {
6390
6483
  return true;
6391
6484
  }
6392
6485
  };
6393
- NullWidget.inline = /* @__PURE__ */ new NullWidget("span");
6394
- NullWidget.block = /* @__PURE__ */ new NullWidget("div");
6395
- const BreakWidget = /* @__PURE__ */ new class extends WidgetType {
6486
+ NullWidget.inline = /*@__PURE__*/ new NullWidget("span");
6487
+ NullWidget.block = /*@__PURE__*/ new NullWidget("div");
6488
+ const BreakWidget = /*@__PURE__*/ new class extends WidgetType {
6396
6489
  toDOM() {
6397
6490
  return document.createElement("br");
6398
6491
  }
@@ -6427,10 +6520,12 @@ var DocView = class {
6427
6520
  update(update) {
6428
6521
  var _a;
6429
6522
  let changedRanges = update.changedRanges;
6430
- if (this.minWidth > 0 && changedRanges.length) if (!changedRanges.every(({ fromA, toA }) => toA < this.minWidthFrom || fromA > this.minWidthTo)) this.minWidth = this.minWidthFrom = this.minWidthTo = 0;
6431
- else {
6432
- this.minWidthFrom = update.changes.mapPos(this.minWidthFrom, 1);
6433
- this.minWidthTo = update.changes.mapPos(this.minWidthTo, 1);
6523
+ if (this.minWidth > 0 && changedRanges.length) {
6524
+ if (!changedRanges.every(({ fromA, toA }) => toA < this.minWidthFrom || fromA > this.minWidthTo)) this.minWidth = this.minWidthFrom = this.minWidthTo = 0;
6525
+ else {
6526
+ this.minWidthFrom = update.changes.mapPos(this.minWidthFrom, 1);
6527
+ this.minWidthTo = update.changes.mapPos(this.minWidthTo, 1);
6528
+ }
6434
6529
  }
6435
6530
  this.updateEditContextFormatting(update);
6436
6531
  let readCompositionAt = -1;
@@ -6470,6 +6565,7 @@ var DocView = class {
6470
6565
  if (composition || changes.length) {
6471
6566
  let oldTile = this.tile;
6472
6567
  let builder = new TileUpdate(this.view, oldTile, this.blockWrappers, this.decorations, this.dynamicDecorationMap);
6568
+ if (composition && Tile.get(composition.text)) builder.cache.reused.set(Tile.get(composition.text), 2);
6473
6569
  this.tile = builder.run(changes, composition);
6474
6570
  destroyDropped(oldTile, builder.cache.reused);
6475
6571
  }
@@ -6589,8 +6685,10 @@ var DocView = class {
6589
6685
  for (;;) {
6590
6686
  let parent = node.parentNode;
6591
6687
  if (parent == tile.dom) break;
6592
- if (bias == 0 && parent.firstChild != parent.lastChild) if (node == parent.firstChild) bias = -1;
6593
- else bias = 1;
6688
+ if (bias == 0 && parent.firstChild != parent.lastChild) {
6689
+ if (node == parent.firstChild) bias = -1;
6690
+ else bias = 1;
6691
+ }
6594
6692
  node = parent;
6595
6693
  }
6596
6694
  if (bias < 0) after = node;
@@ -6609,7 +6707,7 @@ var DocView = class {
6609
6707
  }
6610
6708
  domAtPos(pos, side) {
6611
6709
  let { tile, offset } = this.tile.resolveBlock(pos, side);
6612
- if (tile.isWidget()) return tile.domPosFor(pos, side);
6710
+ if (tile.isWidget()) return tile.domPosFor(offset, side);
6613
6711
  return tile.domIn(offset, side);
6614
6712
  }
6615
6713
  inlineDOMNearPos(pos, side) {
@@ -6639,13 +6737,13 @@ var DocView = class {
6639
6737
  else if (afterBad && before) after = null;
6640
6738
  return before && side < 0 || !after ? before.domIn(beforeOff, side) : after.domIn(afterOff, side);
6641
6739
  }
6642
- coordsAt(pos, side) {
6740
+ coordsAt(pos, side, rtl) {
6643
6741
  let { tile, offset } = this.tile.resolveBlock(pos, side);
6644
6742
  if (tile.isWidget()) {
6645
6743
  if (tile.widget instanceof BlockGapWidget) return null;
6646
6744
  return tile.coordsInWidget(offset, side, true);
6647
6745
  }
6648
- return tile.coordsIn(offset, side);
6746
+ return tile.coordsIn(offset, side, rtl);
6649
6747
  }
6650
6748
  lineAt(pos, side) {
6651
6749
  let { tile } = this.tile.resolveBlock(pos, side);
@@ -6813,7 +6911,7 @@ var DocView = class {
6813
6911
  logException(this.view.state, e, "scroll handler");
6814
6912
  }
6815
6913
  let { range } = target;
6816
- let rect = this.coordsAt(range.head, range.empty ? range.assoc : range.head > range.anchor ? -1 : 1), other;
6914
+ let rect = this.coordsAt(range.head, range.assoc || (range.head > range.anchor ? -1 : 1)), other;
6817
6915
  if (!rect) return;
6818
6916
  if (!range.empty && (other = this.coordsAt(range.anchor, range.anchor > range.head ? -1 : 1))) rect = {
6819
6917
  left: Math.min(rect.left, other.left),
@@ -6830,6 +6928,14 @@ var DocView = class {
6830
6928
  };
6831
6929
  let { offsetWidth, offsetHeight } = this.view.scrollDOM;
6832
6930
  scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == Direction.LTR);
6931
+ if (window.visualViewport && window.innerHeight - window.visualViewport.height > 1 && (rect.top > window.visualViewport.offsetTop + window.visualViewport.height || rect.bottom < window.visualViewport.offsetTop)) {
6932
+ let line = this.view.docView.lineAt(range.head, 1);
6933
+ if (line) {
6934
+ let stack = getScrollStack(line.dom);
6935
+ line.dom.scrollIntoView({ block: "nearest" });
6936
+ restoreScrollStack(stack, false);
6937
+ }
6938
+ }
6833
6939
  }
6834
6940
  lineHasWidget(pos) {
6835
6941
  let scan = (child) => child.isWidget() || child.children.some(scan);
@@ -6983,7 +7089,7 @@ function groupAt(state, pos, bias = 1) {
6983
7089
  if (categorize(line.text.slice(to, next)) != cat) break;
6984
7090
  to = next;
6985
7091
  }
6986
- return EditorSelection.range(from + line.from, to + line.from);
7092
+ return EditorSelection.undirectionalRange(from + line.from, to + line.from);
6987
7093
  }
6988
7094
  function posAtCoordsImprecise(view, contentRect, block, x, y) {
6989
7095
  let into = Math.round((x - contentRect.left) * view.defaultCharacterWidth);
@@ -7056,7 +7162,8 @@ function moveVertically(view, start, forward, distance) {
7056
7162
  if (startPos == (forward ? view.state.doc.length : 0)) return EditorSelection.cursor(startPos, start.assoc);
7057
7163
  let goal = start.goalColumn, startY;
7058
7164
  let rect = view.contentDOM.getBoundingClientRect();
7059
- let startCoords = view.coordsAtPos(startPos, start.assoc || -1), docTop = view.documentTop;
7165
+ let startCoords = view.coordsAtPos(startPos, start.assoc || ((start.empty ? forward : start.head == start.from) ? 1 : -1));
7166
+ let docTop = view.documentTop;
7060
7167
  if (startCoords) {
7061
7168
  if (goal == null) goal = startCoords.left - rect.left;
7062
7169
  startY = dir < 0 ? startCoords.top : startCoords.bottom;
@@ -7066,12 +7173,17 @@ function moveVertically(view, start, forward, distance) {
7066
7173
  startY = (dir < 0 ? line.top : line.bottom) + docTop;
7067
7174
  }
7068
7175
  let resolvedGoal = rect.left + goal;
7069
- let dist = distance !== null && distance !== void 0 ? distance : view.viewState.heightOracle.textHeight >> 1;
7070
- let pos = posAtCoords(view, {
7071
- x: resolvedGoal,
7072
- y: startY + dist * dir
7073
- }, false, dir);
7074
- return EditorSelection.cursor(pos.pos, pos.assoc, void 0, goal);
7176
+ let halfText = view.viewState.heightOracle.textHeight >> 1, dist = distance !== null && distance !== void 0 ? distance : halfText;
7177
+ for (let scan = 0;; scan += halfText) {
7178
+ let y = startY + (dist + scan) * dir;
7179
+ let pos = posAtCoords(view, {
7180
+ x: resolvedGoal,
7181
+ y
7182
+ }, false, dir);
7183
+ if (forward ? y > rect.bottom : y < rect.top) return EditorSelection.cursor(pos.pos, pos.assoc);
7184
+ let posCoords = view.coordsAtPos(pos.pos, pos.assoc), mid = posCoords ? (posCoords.top + posCoords.bottom) / 2 : 0;
7185
+ if (!posCoords || (forward ? mid > startY : mid < startY)) return EditorSelection.cursor(pos.pos, pos.assoc, void 0, goal);
7186
+ }
7075
7187
  }
7076
7188
  function skipAtomicRanges(atoms, pos, bias) {
7077
7189
  for (;;) {
@@ -7096,7 +7208,10 @@ function skipAtomsForSelection(atoms, sel) {
7096
7208
  } else {
7097
7209
  let from = skipAtomicRanges(atoms, range.from, -1);
7098
7210
  let to = skipAtomicRanges(atoms, range.to, 1);
7099
- if (from != range.from || to != range.to) updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
7211
+ if (from != range.from || to != range.to) {
7212
+ if (range.undirectional) updated = EditorSelection.undirectionalRange(range.from, range.to);
7213
+ else updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
7214
+ }
7100
7215
  }
7101
7216
  if (updated) {
7102
7217
  if (!ranges) ranges = sel.ranges.slice();
@@ -7124,7 +7239,8 @@ function posAtCoords(view, coords, precise, scanY) {
7124
7239
  block = view.elementAtHeight(yOffset);
7125
7240
  if (scanY == null) break;
7126
7241
  if (block.type == BlockType.Text) {
7127
- let rect = view.docView.coordsAt(scanY < 0 ? block.from : block.to, scanY);
7242
+ if (scanY < 0 ? block.to < view.viewport.from : block.from > view.viewport.to) break;
7243
+ let rect = view.docView.coordsAt(scanY < 0 ? block.from : block.to, scanY > 0 ? -1 : 1);
7128
7244
  if (rect && (scanY < 0 ? rect.top <= yOffset + docTop : rect.bottom >= yOffset + docTop)) break;
7129
7245
  }
7130
7246
  let halfLine = view.viewState.heightOracle.textHeight / 2;
@@ -7140,57 +7256,135 @@ function posAtCoords(view, coords, precise, scanY) {
7140
7256
  if (block.type != BlockType.Text) return yOffset < (block.top + block.bottom) / 2 ? new PosAssoc(block.from, 1) : new PosAssoc(block.to, -1);
7141
7257
  let line = view.docView.lineAt(block.from, 2);
7142
7258
  if (!line || line.length != block.length) line = view.docView.lineAt(block.from, -2);
7143
- return posAtCoordsInline(view, line, block.from, x, y);
7144
- }
7145
- function posAtCoordsInline(view, tile, offset, x, y) {
7146
- let closest = -1, closestRect = null;
7147
- let dxClosest = 1e9, dyClosest = 1e9;
7148
- let rowTop = y, rowBot = y;
7149
- let checkRects = (rects, index) => {
7150
- for (let i = 0; i < rects.length; i++) {
7151
- let rect = rects[i];
7152
- if (rect.top == rect.bottom) continue;
7153
- let dx = rect.left > x ? rect.left - x : rect.right < x ? x - rect.right : 0;
7154
- let dy = rect.top > y ? rect.top - y : rect.bottom < y ? y - rect.bottom : 0;
7155
- if (rect.top <= rowBot && rect.bottom >= rowTop) {
7156
- rowTop = Math.min(rect.top, rowTop);
7157
- rowBot = Math.max(rect.bottom, rowBot);
7158
- dy = 0;
7159
- }
7160
- if (closest < 0 || (dy - dyClosest || dx - dxClosest) < 0) if (closest >= 0 && dyClosest && dxClosest < dx && closestRect.top <= rowBot - 2 && closestRect.bottom >= rowTop + 2) dyClosest = 0;
7161
- else {
7162
- closest = index;
7163
- dxClosest = dx;
7164
- dyClosest = dy;
7165
- closestRect = rect;
7259
+ return new InlineCoordsScan(view, x, y, view.textDirectionAt(block.from)).scanTile(line, block.from);
7260
+ }
7261
+ var InlineCoordsScan = class {
7262
+ constructor(view, x, y, baseDir) {
7263
+ this.view = view;
7264
+ this.x = x;
7265
+ this.y = y;
7266
+ this.baseDir = baseDir;
7267
+ this.line = null;
7268
+ this.spans = null;
7269
+ }
7270
+ bidiSpansAt(pos) {
7271
+ if (!this.line || this.line.from > pos || this.line.to < pos) {
7272
+ this.line = this.view.state.doc.lineAt(pos);
7273
+ this.spans = this.view.bidiSpans(this.line);
7274
+ }
7275
+ return this;
7276
+ }
7277
+ baseDirAt(pos, side) {
7278
+ let { line, spans } = this.bidiSpansAt(pos);
7279
+ return spans[BidiSpan.find(spans, pos - line.from, -1, side)].level == this.baseDir;
7280
+ }
7281
+ dirAt(pos, side) {
7282
+ let { line, spans } = this.bidiSpansAt(pos);
7283
+ return spans[BidiSpan.find(spans, pos - line.from, -1, side)].dir;
7284
+ }
7285
+ bidiIn(from, to) {
7286
+ let { spans, line } = this.bidiSpansAt(from);
7287
+ return spans.length > 1 || spans.length && (spans[0].level != this.baseDir || spans[0].to + line.from < to);
7288
+ }
7289
+ scan(positions, getRects, recursed = false) {
7290
+ let lo = 0, hi = positions.length - 1, seen = /* @__PURE__ */ new Set();
7291
+ let bidi = this.bidiIn(positions[0], positions[hi]);
7292
+ let above, below;
7293
+ let closestI = -1, closestDx = 1e9, closestRect;
7294
+ search: while (lo < hi) {
7295
+ let dist = hi - lo, mid = lo + hi >> 1;
7296
+ adjust: if (seen.has(mid)) {
7297
+ for (let i = 1; i < dist; i++) {
7298
+ let scan = mid + i;
7299
+ if (scan >= hi) scan -= dist;
7300
+ if (!seen.has(scan)) {
7301
+ mid = scan;
7302
+ break adjust;
7303
+ }
7304
+ }
7305
+ break search;
7306
+ }
7307
+ seen.add(mid);
7308
+ let rects = getRects(mid), side = 0;
7309
+ if (rects) for (let i = 0; i < rects.length; i++) {
7310
+ let rect = rects[i];
7311
+ if (rect.width == 0 && rects.length > 1) continue;
7312
+ if (rect.bottom < this.y) {
7313
+ if (!above || above.bottom < rect.bottom) above = rect;
7314
+ side = 1;
7315
+ } else if (rect.top > this.y) {
7316
+ if (!below || below.top > rect.top) below = rect;
7317
+ side = -1;
7318
+ } else {
7319
+ let off = rect.left > this.x ? this.x - rect.left : rect.right < this.x ? this.x - rect.right : 0;
7320
+ let dx = Math.abs(off);
7321
+ if (dx < closestDx) {
7322
+ closestI = mid;
7323
+ closestDx = dx;
7324
+ closestRect = rect;
7325
+ }
7326
+ if (off) side = off < 0 == (this.baseDir == Direction.LTR) ? -1 : 1;
7327
+ }
7166
7328
  }
7329
+ if (side == -1 && (!bidi || this.baseDirAt(positions[mid], 1))) hi = mid;
7330
+ else if (side == 1 && (!bidi || this.baseDirAt(positions[mid + 1], -1))) lo = mid + 1;
7167
7331
  }
7168
- };
7169
- if (tile.isText()) {
7170
- for (let i = 0; i < tile.length;) {
7171
- let next = findClusterBreak(tile.text, i);
7172
- checkRects(textRange(tile.dom, i, next).getClientRects(), i);
7173
- if (!dxClosest && !dyClosest) break;
7174
- i = next;
7175
- }
7176
- return x > (closestRect.left + closestRect.right) / 2 == (dirAt(view, closest + offset) == Direction.LTR) ? new PosAssoc(offset + findClusterBreak(tile.text, closest), -1) : new PosAssoc(offset + closest, 1);
7177
- } else {
7332
+ if (!closestRect) {
7333
+ if (!below && !above) return {
7334
+ i: positions[0],
7335
+ after: false
7336
+ };
7337
+ let side = above && (!below || this.y - above.bottom < below.top - this.y) ? above : below;
7338
+ this.y = (side.top + side.bottom) / 2;
7339
+ return this.scan(positions, getRects, true);
7340
+ }
7341
+ if (closestDx && !recursed) {
7342
+ let { top, bottom } = closestRect;
7343
+ if (above && above.bottom > (top + top + bottom) / 3) {
7344
+ this.y = above.bottom - 1;
7345
+ return this.scan(positions, getRects, true);
7346
+ }
7347
+ if (below && below.top < (top + bottom + bottom) / 3) {
7348
+ this.y = below.top + 1;
7349
+ return this.scan(positions, getRects, true);
7350
+ }
7351
+ }
7352
+ let ltr = (bidi ? this.dirAt(positions[closestI], 1) : this.baseDir) == Direction.LTR;
7353
+ return {
7354
+ i: closestI,
7355
+ after: this.x > (closestRect.left + closestRect.right) / 2 == ltr
7356
+ };
7357
+ }
7358
+ scanText(tile, offset) {
7359
+ let positions = [];
7360
+ for (let i = 0; i < tile.length; i = findClusterBreak(tile.text, i)) positions.push(offset + i);
7361
+ positions.push(offset + tile.length);
7362
+ let scan = this.scan(positions, (i) => {
7363
+ let off = positions[i] - offset, end = positions[i + 1] - offset;
7364
+ return textRange(tile.dom, off, end).getClientRects();
7365
+ });
7366
+ return scan.after ? new PosAssoc(positions[scan.i + 1], -1) : new PosAssoc(positions[scan.i], 1);
7367
+ }
7368
+ scanTile(tile, offset) {
7178
7369
  if (!tile.length) return new PosAssoc(offset, 1);
7179
- for (let i = 0; i < tile.children.length; i++) {
7370
+ if (tile.children.length == 1) {
7371
+ let child = tile.children[0];
7372
+ if (child.isText()) return this.scanText(child, offset);
7373
+ else if (child.isComposite()) return this.scanTile(child, offset);
7374
+ }
7375
+ let positions = [offset];
7376
+ for (let i = 0, pos = offset; i < tile.children.length; i++) positions.push(pos += tile.children[i].length);
7377
+ let scan = this.scan(positions, (i) => {
7180
7378
  let child = tile.children[i];
7181
- if (child.flags & 48) continue;
7182
- checkRects((child.dom.nodeType == 1 ? child.dom : textRange(child.dom, 0, child.length)).getClientRects(), i);
7183
- if (!dxClosest && !dyClosest) break;
7184
- }
7185
- let inner = tile.children[closest], innerOff = tile.posBefore(inner, offset);
7186
- if (inner.isComposite() || inner.isText()) return posAtCoordsInline(view, inner, innerOff, Math.max(closestRect.left, Math.min(closestRect.right, x)), y);
7187
- return x > (closestRect.left + closestRect.right) / 2 == (dirAt(view, closest + offset) == Direction.LTR) ? new PosAssoc(innerOff + inner.length, -1) : new PosAssoc(innerOff, 1);
7379
+ if (child.flags & 48) return null;
7380
+ return (child.dom.nodeType == 1 ? child.dom : textRange(child.dom, 0, child.length)).getClientRects();
7381
+ });
7382
+ let child = tile.children[scan.i], pos = positions[scan.i];
7383
+ if (child.isText()) return this.scanText(child, pos);
7384
+ if (child.isComposite()) return this.scanTile(child, pos);
7385
+ return scan.after ? new PosAssoc(positions[scan.i + 1], -1) : new PosAssoc(pos, 1);
7188
7386
  }
7189
- }
7190
- function dirAt(view, pos) {
7191
- let line = view.state.doc.lineAt(pos);
7192
- return view.bidiSpans(line)[BidiSpan.find(view.bidiSpans(line), pos - line.from, -1, 1)].dir;
7193
- }
7387
+ };
7194
7388
  const LineBreakPlaceholder = "￿";
7195
7389
  var DOMReader = class {
7196
7390
  constructor(points, view) {
@@ -7299,7 +7493,7 @@ var DOMChange = class {
7299
7493
  this.bounds = null;
7300
7494
  this.text = "";
7301
7495
  this.domChanged = start > -1;
7302
- let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView;
7496
+ let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView, curSel = view.state.selection;
7303
7497
  if (view.state.readOnly && start > -1) this.newSel = null;
7304
7498
  else if (start > -1 && (this.bounds = domBoundsAround(view.docView.tile, start, end, 0))) {
7305
7499
  let selPoints = iHead || iAnchor ? [] : selectionPoints(view);
@@ -7309,10 +7503,10 @@ var DOMChange = class {
7309
7503
  this.newSel = selectionFromPoints(selPoints, this.bounds.from);
7310
7504
  } else {
7311
7505
  let domSel = view.observer.selectionRange;
7312
- let head = iHead && iHead.node == domSel.focusNode && iHead.offset == domSel.focusOffset || !contains(view.contentDOM, domSel.focusNode) ? view.state.selection.main.head : view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset);
7313
- let anchor = iAnchor && iAnchor.node == domSel.anchorNode && iAnchor.offset == domSel.anchorOffset || !contains(view.contentDOM, domSel.anchorNode) ? view.state.selection.main.anchor : view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
7506
+ let head = iHead && iHead.node == domSel.focusNode && iHead.offset == domSel.focusOffset || !contains(view.contentDOM, domSel.focusNode) ? curSel.main.head : view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset);
7507
+ let anchor = iAnchor && iAnchor.node == domSel.anchorNode && iAnchor.offset == domSel.anchorOffset || !contains(view.contentDOM, domSel.anchorNode) ? curSel.main.anchor : view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
7314
7508
  let vp = view.viewport;
7315
- if ((browser.ios || browser.chrome) && view.state.selection.main.empty && head != anchor && (vp.from > 0 || vp.to < view.state.doc.length)) {
7509
+ if ((browser.ios || browser.chrome) && head != anchor && Math.min(head, anchor) <= curSel.main.from && Math.max(head, anchor) >= curSel.main.to && (vp.from > 0 || vp.to < view.state.doc.length)) {
7316
7510
  let from = Math.min(head, anchor), to = Math.max(head, anchor);
7317
7511
  let offFrom = vp.from - from, offTo = vp.to - to;
7318
7512
  if ((offFrom == 0 || offFrom == 1 || from == 0) && (offTo == 0 || offTo == -1 || to == view.state.doc.length)) {
@@ -7320,8 +7514,12 @@ var DOMChange = class {
7320
7514
  anchor = view.state.doc.length;
7321
7515
  }
7322
7516
  }
7323
- if (view.inputState.composing > -1 && view.state.selection.ranges.length > 1) this.newSel = view.state.selection.replaceRange(EditorSelection.range(anchor, head));
7324
- else this.newSel = EditorSelection.single(anchor, head);
7517
+ if (view.inputState.composing > -1 && curSel.ranges.length > 1) this.newSel = curSel.replaceRange(EditorSelection.range(anchor, head));
7518
+ else if (view.lineWrapping && anchor == head && !(curSel.main.empty && curSel.main.head == head) && view.inputState.lastTouchTime > Date.now() - 100) {
7519
+ let before = view.coordsAtPos(head, -1), assoc = 0;
7520
+ if (before) assoc = view.inputState.lastTouchY <= before.bottom ? -1 : 1;
7521
+ this.newSel = EditorSelection.create([EditorSelection.cursor(head, assoc)]);
7522
+ } else this.newSel = EditorSelection.single(anchor, head);
7325
7523
  }
7326
7524
  }
7327
7525
  };
@@ -7359,7 +7557,7 @@ function domBoundsAround(tile, from, to, offset) {
7359
7557
  }
7360
7558
  function applyDOMChange(view, domChange) {
7361
7559
  let change;
7362
- let { newSel } = domChange, sel = view.state.selection.main;
7560
+ let { newSel } = domChange, { state } = view, sel = state.selection.main;
7363
7561
  let lastKey = view.inputState.lastKeyTime > Date.now() - 100 ? view.inputState.lastKeyCode : -1;
7364
7562
  if (domChange.bounds) {
7365
7563
  let { from, to } = domChange.bounds;
@@ -7368,38 +7566,33 @@ function applyDOMChange(view, domChange) {
7368
7566
  preferredPos = sel.to;
7369
7567
  preferredSide = "end";
7370
7568
  }
7371
- let diff = findDiff(view.state.doc.sliceString(from, to, LineBreakPlaceholder), domChange.text, preferredPos - from, preferredSide);
7372
- if (diff) {
7373
- if (browser.chrome && lastKey == 13 && diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder) diff.toB--;
7569
+ let cmp = state.doc.sliceString(from, to, LineBreakPlaceholder), selEnd, diff;
7570
+ if (!sel.empty && sel.from >= from && sel.to <= to && (domChange.typeOver || cmp != domChange.text) && cmp.slice(0, sel.from - from) == domChange.text.slice(0, sel.from - from) && cmp.slice(sel.to - from) == domChange.text.slice(selEnd = domChange.text.length - (cmp.length - (sel.to - from)))) change = {
7571
+ from: sel.from,
7572
+ to: sel.to,
7573
+ insert: Text.of(domChange.text.slice(sel.from - from, selEnd).split(LineBreakPlaceholder))
7574
+ };
7575
+ else if (diff = findDiff(cmp, domChange.text, preferredPos - from, preferredSide)) {
7576
+ if (browser.chrome && lastKey == 13 && diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == "￿￿") diff.toB--;
7374
7577
  change = {
7375
7578
  from: from + diff.from,
7376
7579
  to: from + diff.toA,
7377
7580
  insert: Text.of(domChange.text.slice(diff.from, diff.toB).split(LineBreakPlaceholder))
7378
7581
  };
7379
7582
  }
7380
- } else if (newSel && (!view.hasFocus && view.state.facet(editable) || sameSelPos(newSel, sel))) newSel = null;
7583
+ } else if (newSel && (!view.hasFocus && state.facet(editable) || sameSelPos(newSel, sel))) newSel = null;
7381
7584
  if (!change && !newSel) return false;
7382
- if (!change && domChange.typeOver && !sel.empty && newSel && newSel.main.empty) change = {
7383
- from: sel.from,
7384
- to: sel.to,
7385
- insert: view.state.doc.slice(sel.from, sel.to)
7386
- };
7387
- else if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 && /^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
7585
+ if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 && /^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
7388
7586
  if (newSel && change.insert.length == 2) newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
7389
7587
  change = {
7390
7588
  from: change.from,
7391
7589
  to: change.to,
7392
7590
  insert: Text.of([change.insert.toString().replace(".", " ")])
7393
7591
  };
7394
- } else if (change && change.from >= sel.from && change.to <= sel.to && (change.from != sel.from || change.to != sel.to) && sel.to - sel.from - (change.to - change.from) <= 4) change = {
7395
- from: sel.from,
7396
- to: sel.to,
7397
- insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to))
7398
- };
7399
- else if (view.state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) && view.inputState.insertingTextAt > Date.now() - 50) change = {
7592
+ } else if (state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) && view.inputState.insertingTextAt > Date.now() - 50) change = {
7400
7593
  from: sel.from,
7401
7594
  to: sel.to,
7402
- insert: view.state.toText(view.inputState.insertingText)
7595
+ insert: state.toText(view.inputState.insertingText)
7403
7596
  };
7404
7597
  else if (browser.chrome && change && change.from == change.to && change.from == sel.head && change.insert.toString() == "\n " && view.lineWrapping) {
7405
7598
  if (newSel) newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
@@ -7415,7 +7608,7 @@ function applyDOMChange(view, domChange) {
7415
7608
  if (view.inputState.lastSelectionTime > Date.now() - 50) {
7416
7609
  if (view.inputState.lastSelectionOrigin == "select") scrollIntoView = true;
7417
7610
  userEvent = view.inputState.lastSelectionOrigin;
7418
- if (userEvent == "select.pointer") newSel = skipAtomsForSelection(view.state.facet(atomicRanges).map((f) => f(view)), newSel);
7611
+ if (userEvent == "select.pointer") newSel = skipAtomsForSelection(state.facet(atomicRanges).map((f) => f(view)), newSel);
7419
7612
  }
7420
7613
  view.dispatch({
7421
7614
  selection: newSel,
@@ -7559,18 +7752,16 @@ var InputState = class {
7559
7752
  this.view = view;
7560
7753
  this.lastKeyCode = 0;
7561
7754
  this.lastKeyTime = 0;
7755
+ this.touchActive = false;
7562
7756
  this.lastTouchTime = 0;
7757
+ this.lastTouchX = 0;
7758
+ this.lastTouchY = 0;
7563
7759
  this.lastFocusTime = 0;
7564
7760
  this.lastScrollTop = 0;
7565
7761
  this.lastScrollLeft = 0;
7762
+ this.lastWheelEvent = 0;
7566
7763
  this.pendingIOSKey = void 0;
7567
- /**
7568
- When enabled (>-1), tab presses are not given to key handlers,
7569
- leaving the browser's default behavior. If >0, the mode expires
7570
- at that timestamp, and any other keypress clears it.
7571
- Esc enables temporary tab focus mode for two seconds when not
7572
- otherwise handled.
7573
- */
7764
+ this.lastIOSMomentumScroll = 0;
7574
7765
  this.tabFocusMode = -1;
7575
7766
  this.lastSelectionOrigin = null;
7576
7767
  this.lastSelectionTime = 0;
@@ -7633,9 +7824,19 @@ var InputState = class {
7633
7824
  this.view.observer.delayAndroidKey(event.key, event.keyCode);
7634
7825
  return true;
7635
7826
  }
7636
- let pending;
7637
- if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey && ((pending = PendingKeys.find((key) => key.keyCode == event.keyCode)) && !event.ctrlKey || EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey && !event.shiftKey)) {
7638
- this.pendingIOSKey = pending || event;
7827
+ if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey && (PendingKeys.some((key) => key.keyCode == event.keyCode) && !event.ctrlKey || EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey)) {
7828
+ let mods = {
7829
+ ctrlKey: event.ctrlKey,
7830
+ altKey: event.altKey,
7831
+ metaKey: event.metaKey,
7832
+ shiftKey: event.shiftKey
7833
+ };
7834
+ if (mods.shiftKey && browser.ios && !/^(off|none)$/.test(this.view.contentDOM.autocapitalize) && iosVirtualKeyboardOpen(this.view.win)) mods.shiftKey = false;
7835
+ this.pendingIOSKey = {
7836
+ key: event.key,
7837
+ keyCode: event.keyCode,
7838
+ mods
7839
+ };
7639
7840
  setTimeout(() => this.flushIOSKey(), 250);
7640
7841
  return true;
7641
7842
  }
@@ -7647,7 +7848,7 @@ var InputState = class {
7647
7848
  if (!key) return false;
7648
7849
  if (key.key == "Enter" && change && change.from < change.to && /^\S+$/.test(change.insert.toString())) return false;
7649
7850
  this.pendingIOSKey = void 0;
7650
- return dispatchKey(this.view.contentDOM, key.key, key.keyCode, key instanceof KeyboardEvent ? key : void 0);
7851
+ return dispatchKey(this.view.contentDOM, key.key, key.keyCode, key.mods);
7651
7852
  }
7652
7853
  ignoreDuringComposition(event) {
7653
7854
  if (!/^key/.test(event.type) || event.synthetic) return false;
@@ -7672,6 +7873,10 @@ var InputState = class {
7672
7873
  if (this.mouseSelection) this.mouseSelection.destroy();
7673
7874
  }
7674
7875
  };
7876
+ function iosVirtualKeyboardOpen(win) {
7877
+ if (!win.visualViewport) return false;
7878
+ return win.visualViewport.height * win.visualViewport.scale / win.document.documentElement.clientHeight < .85;
7879
+ }
7675
7880
  function bindHandler(plugin, handler) {
7676
7881
  return (view, event) => {
7677
7882
  try {
@@ -7859,8 +8064,8 @@ function eventBelongsToEditor(view, event) {
7859
8064
  for (let node = event.target, tile; node != view.contentDOM; node = node.parentNode) if (!node || node.nodeType == 11 || (tile = Tile.get(node)) && tile.isWidget() && !tile.isHidden && tile.widget.ignoreEvent(event)) return false;
7860
8065
  return true;
7861
8066
  }
7862
- const handlers = /* @__PURE__ */ Object.create(null);
7863
- const observers = /* @__PURE__ */ Object.create(null);
8067
+ const handlers = /*@__PURE__*/ Object.create(null);
8068
+ const observers = /*@__PURE__*/ Object.create(null);
7864
8069
  const brokenClipboardAPI = browser.ie && browser.ie_version < 15 || browser.ios && browser.webkit_version < 604;
7865
8070
  function capturePaste(view) {
7866
8071
  let parent = view.dom.parentNode;
@@ -7915,8 +8120,13 @@ function doPaste(view, input) {
7915
8120
  });
7916
8121
  }
7917
8122
  observers.scroll = (view) => {
7918
- view.inputState.lastScrollTop = view.scrollDOM.scrollTop;
7919
- view.inputState.lastScrollLeft = view.scrollDOM.scrollLeft;
8123
+ let iState = view.inputState;
8124
+ iState.lastScrollTop = view.scrollDOM.scrollTop;
8125
+ iState.lastScrollLeft = view.scrollDOM.scrollLeft;
8126
+ if (browser.ios && !iState.touchActive) iState.lastIOSMomentumScroll = Date.now();
8127
+ };
8128
+ observers.wheel = observers.mousewheel = (view) => {
8129
+ view.inputState.lastWheelEvent = Date.now();
7920
8130
  };
7921
8131
  handlers.keydown = (view, event) => {
7922
8132
  view.inputState.setSelectionOrigin("select");
@@ -7924,12 +8134,21 @@ handlers.keydown = (view, event) => {
7924
8134
  return false;
7925
8135
  };
7926
8136
  observers.touchstart = (view, e) => {
7927
- view.inputState.lastTouchTime = Date.now();
7928
- view.inputState.setSelectionOrigin("select.pointer");
8137
+ let iState = view.inputState, touch = e.targetTouches[0];
8138
+ iState.touchActive = true;
8139
+ iState.lastTouchTime = Date.now();
8140
+ if (touch) {
8141
+ iState.lastTouchX = touch.clientX;
8142
+ iState.lastTouchY = touch.clientY;
8143
+ }
8144
+ iState.setSelectionOrigin("select.pointer");
7929
8145
  };
7930
8146
  observers.touchmove = (view) => {
7931
8147
  view.inputState.setSelectionOrigin("select.pointer");
7932
8148
  };
8149
+ observers.touchend = (view, e) => {
8150
+ view.inputState.touchActive = false;
8151
+ };
7933
8152
  handlers.mousedown = (view, event) => {
7934
8153
  view.observer.flush();
7935
8154
  if (view.inputState.lastTouchTime > Date.now() - 2e3) return false;
@@ -7962,11 +8181,13 @@ function rangeForClick(view, pos, bias, type) {
7962
8181
  let visual = view.docView.lineAt(pos, bias), line = view.state.doc.lineAt(visual ? visual.posAtEnd : pos);
7963
8182
  let from = visual ? visual.posAtStart : line.from, to = visual ? visual.posAtEnd : line.to;
7964
8183
  if (to < view.state.doc.length && to == line.to) to++;
7965
- return EditorSelection.range(from, to);
8184
+ return EditorSelection.undirectionalRange(from, to);
7966
8185
  }
7967
8186
  }
7968
8187
  const BadMouseDetail = browser.ie && browser.ie_version <= 11;
7969
- let lastMouseDown = null, lastMouseDownCount = 0, lastMouseDownTime = 0;
8188
+ let lastMouseDown = null;
8189
+ let lastMouseDownCount = 0;
8190
+ let lastMouseDownTime = 0;
7970
8191
  function getClickType(event) {
7971
8192
  if (!BadMouseDetail) return event.detail;
7972
8193
  let last = lastMouseDown, lastTime = lastMouseDownTime;
@@ -7996,9 +8217,9 @@ function basicMouseSelection(view, event) {
7996
8217
  if (start.pos != cur.pos && !extend) {
7997
8218
  let startRange = rangeForClick(view, start.pos, start.assoc, type);
7998
8219
  let from = Math.min(startRange.from, range.from), to = Math.max(startRange.to, range.to);
7999
- range = from < range.from ? EditorSelection.range(from, to) : EditorSelection.range(to, from);
8220
+ range = from < range.from ? EditorSelection.range(from, to, range.assoc) : EditorSelection.range(to, from, range.assoc);
8000
8221
  }
8001
- if (extend) return startSel.replaceRange(startSel.main.extend(range.from, range.to));
8222
+ if (extend) return startSel.replaceRange(startSel.main.extend(range.from, range.to, range.assoc));
8002
8223
  else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos))) return removed;
8003
8224
  else if (multiple) return startSel.addRange(range);
8004
8225
  else return EditorSelection.create([range]);
@@ -8018,7 +8239,7 @@ handlers.dragstart = (view, event) => {
8018
8239
  let tile = view.docView.tile.nearest(event.target);
8019
8240
  if (tile && tile.isWidget()) {
8020
8241
  let from = tile.posAtStart, to = from + tile.length;
8021
- if (from >= range.to || to <= range.from) range = EditorSelection.range(from, to);
8242
+ if (from >= range.to || to <= range.from) range = EditorSelection.undirectionalRange(from, to);
8022
8243
  }
8023
8244
  }
8024
8245
  let { inputState } = view;
@@ -8145,8 +8366,7 @@ function copiedRange(state) {
8145
8366
  }
8146
8367
  let lastLinewiseCopy = null;
8147
8368
  handlers.copy = handlers.cut = (view, event) => {
8148
- let domSel = getSelection(view.root);
8149
- if (domSel && !hasSelection(view.contentDOM, domSel)) return false;
8369
+ if (!hasSelection(view.contentDOM, view.observer.selectionRange)) return false;
8150
8370
  let { text, ranges, linewise } = copiedRange(view.state);
8151
8371
  if (!text && !linewise) return false;
8152
8372
  lastLinewiseCopy = linewise ? text : null;
@@ -8165,7 +8385,7 @@ handlers.copy = handlers.cut = (view, event) => {
8165
8385
  return false;
8166
8386
  }
8167
8387
  };
8168
- const isFocusChange = /* @__PURE__ */ Annotation.define();
8388
+ const isFocusChange = /*@__PURE__*/ Annotation.define();
8169
8389
  function focusChangeTransaction(state, focus) {
8170
8390
  let effects = [];
8171
8391
  for (let getEffect of state.facet(focusChangeEffect)) {
@@ -8256,7 +8476,7 @@ handlers.beforeinput = (view, event) => {
8256
8476
  if (browser.safari && event.inputType == "insertText" && view.inputState.composing >= 0) setTimeout(() => observers.compositionend(view, event), 20);
8257
8477
  return false;
8258
8478
  };
8259
- const appliedFirefoxHack = /* @__PURE__ */ new Set();
8479
+ const appliedFirefoxHack = /*@__PURE__*/ new Set();
8260
8480
  function firefoxCopyCutHack(doc) {
8261
8481
  if (!appliedFirefoxHack.has(doc)) {
8262
8482
  appliedFirefoxHack.add(doc);
@@ -8314,7 +8534,7 @@ var HeightOracle = class {
8314
8534
  }
8315
8535
  refresh(whiteSpace, lineHeight, charWidth, textHeight, lineLength, knownHeights) {
8316
8536
  let lineWrapping = wrappingWhiteSpace.indexOf(whiteSpace) > -1;
8317
- let changed = Math.abs(lineHeight - this.lineHeight) > .3 || this.lineWrapping != lineWrapping || Math.abs(charWidth - this.charWidth) > .1;
8537
+ let changed = Math.abs(lineHeight - this.lineHeight) > .3 || this.lineWrapping != lineWrapping;
8318
8538
  this.lineWrapping = lineWrapping;
8319
8539
  this.lineHeight = lineHeight;
8320
8540
  this.charWidth = charWidth;
@@ -8397,7 +8617,7 @@ var BlockInfo = class BlockInfo {
8397
8617
  return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, content);
8398
8618
  }
8399
8619
  };
8400
- var QueryType = /* @__PURE__ */ (function(QueryType) {
8620
+ var QueryType = /*@__PURE__*/ (function(QueryType) {
8401
8621
  QueryType[QueryType["ByPos"] = 0] = "ByPos";
8402
8622
  QueryType[QueryType["ByHeight"] = 1] = "ByHeight";
8403
8623
  QueryType[QueryType["ByPosNoHeight"] = 2] = "ByPosNoHeight";
@@ -8458,20 +8678,21 @@ var HeightMap = class HeightMap {
8458
8678
  static of(nodes) {
8459
8679
  if (nodes.length == 1) return nodes[0];
8460
8680
  let i = 0, j = nodes.length, before = 0, after = 0;
8461
- for (;;) if (i == j) if (before > after * 2) {
8462
- let split = nodes[i - 1];
8463
- if (split.break) nodes.splice(--i, 1, split.left, null, split.right);
8464
- else nodes.splice(--i, 1, split.left, split.right);
8465
- j += 1 + split.break;
8466
- before -= split.size;
8467
- } else if (after > before * 2) {
8468
- let split = nodes[j];
8469
- if (split.break) nodes.splice(j, 1, split.left, null, split.right);
8470
- else nodes.splice(j, 1, split.left, split.right);
8471
- j += 2 + split.break;
8472
- after -= split.size;
8473
- } else break;
8474
- else if (before < after) {
8681
+ for (;;) if (i == j) {
8682
+ if (before > after * 2) {
8683
+ let split = nodes[i - 1];
8684
+ if (split.break) nodes.splice(--i, 1, split.left, null, split.right);
8685
+ else nodes.splice(--i, 1, split.left, split.right);
8686
+ j += 1 + split.break;
8687
+ before -= split.size;
8688
+ } else if (after > before * 2) {
8689
+ let split = nodes[j];
8690
+ if (split.break) nodes.splice(j, 1, split.left, null, split.right);
8691
+ else nodes.splice(j, 1, split.left, split.right);
8692
+ j += 2 + split.break;
8693
+ after -= split.size;
8694
+ } else break;
8695
+ } else if (before < after) {
8475
8696
  let next = nodes[i++];
8476
8697
  if (next) before += next.size;
8477
8698
  } else {
@@ -8495,7 +8716,7 @@ function replace(old, val) {
8495
8716
  return val;
8496
8717
  }
8497
8718
  HeightMap.prototype.size = 1;
8498
- const SpaceDeco = /* @__PURE__ */ Decoration.replace({});
8719
+ const SpaceDeco = /*@__PURE__*/ Decoration.replace({});
8499
8720
  var HeightMapBlock = class extends HeightMap {
8500
8721
  constructor(length, height, deco) {
8501
8722
  super(length, height);
@@ -8973,7 +9194,8 @@ var LineGapWidget = class extends WidgetType {
8973
9194
  }
8974
9195
  };
8975
9196
  var ViewState = class {
8976
- constructor(state) {
9197
+ constructor(view, state) {
9198
+ this.view = view;
8977
9199
  this.state = state;
8978
9200
  this.pixelViewport = {
8979
9201
  left: 0,
@@ -8988,10 +9210,10 @@ var ViewState = class {
8988
9210
  this.contentDOMHeight = 0;
8989
9211
  this.editorHeight = 0;
8990
9212
  this.editorWidth = 0;
8991
- this.scrollTop = 0;
8992
- this.scrolledToBottom = false;
8993
9213
  this.scaleX = 1;
8994
9214
  this.scaleY = 1;
9215
+ this.scrollOffset = 0;
9216
+ this.scrolledToBottom = false;
8995
9217
  this.scrollAnchorPos = 0;
8996
9218
  this.scrollAnchorHeight = -1;
8997
9219
  this.scaler = IdScaler;
@@ -9001,7 +9223,8 @@ var ViewState = class {
9001
9223
  this.defaultTextDirection = Direction.LTR;
9002
9224
  this.visibleRanges = [];
9003
9225
  this.mustEnforceCursorAssoc = false;
9004
- this.heightOracle = new HeightOracle(state.facet(contentAttributes).some((v) => typeof v != "function" && v.class == "cm-lineWrapping"));
9226
+ let guessWrapping = state.facet(contentAttributes).some((v) => typeof v != "function" && v.class == "cm-lineWrapping");
9227
+ this.heightOracle = new HeightOracle(guessWrapping);
9005
9228
  this.stateDeco = staticDeco(state);
9006
9229
  this.heightMap = HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle.setDoc(state.doc), [new ChangedRange(0, 0, 0, state.doc.length)]);
9007
9230
  for (let i = 0; i < 2; i++) {
@@ -9011,6 +9234,7 @@ var ViewState = class {
9011
9234
  this.updateViewportLines();
9012
9235
  this.lineGaps = this.ensureLineGaps([]);
9013
9236
  this.lineGapDeco = Decoration.set(this.lineGaps.map((gap) => gap.draw(this, false)));
9237
+ this.scrollParent = view.scrollDOM;
9014
9238
  this.computeVisibleRanges();
9015
9239
  }
9016
9240
  updateForViewport() {
@@ -9043,7 +9267,7 @@ var ViewState = class {
9043
9267
  let contentChanges = update.changedRanges;
9044
9268
  let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
9045
9269
  let prevHeight = this.heightMap.height;
9046
- let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollTop);
9270
+ let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollOffset);
9047
9271
  clearHeightChangeFlag();
9048
9272
  this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
9049
9273
  if (this.heightMap.height != prevHeight || heightChangeFlag) update.flags |= 2;
@@ -9065,12 +9289,12 @@ var ViewState = class {
9065
9289
  if (scrollTarget) this.scrollTarget = scrollTarget;
9066
9290
  if (!this.mustEnforceCursorAssoc && (update.selectionSet || update.focusChanged) && update.view.lineWrapping && update.state.selection.main.empty && update.state.selection.main.assoc && !update.state.facet(nativeSelectionHidden)) this.mustEnforceCursorAssoc = true;
9067
9291
  }
9068
- measure(view) {
9069
- let dom = view.contentDOM, style = window.getComputedStyle(dom);
9292
+ measure() {
9293
+ let { view } = this, dom = view.contentDOM, style = window.getComputedStyle(dom);
9070
9294
  let oracle = this.heightOracle;
9071
9295
  let whiteSpace = style.whiteSpace;
9072
9296
  this.defaultTextDirection = style.direction == "rtl" ? Direction.RTL : Direction.LTR;
9073
- let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace) || this.mustMeasureContent;
9297
+ let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace) || this.mustMeasureContent === "refresh";
9074
9298
  let domRect = dom.getBoundingClientRect();
9075
9299
  let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != domRect.height;
9076
9300
  this.contentDOMHeight = domRect.height;
@@ -9097,12 +9321,18 @@ var ViewState = class {
9097
9321
  this.editorWidth = view.scrollDOM.clientWidth;
9098
9322
  result |= 16;
9099
9323
  }
9100
- let scrollTop = view.scrollDOM.scrollTop * this.scaleY;
9101
- if (this.scrollTop != scrollTop) {
9324
+ let scrollParent = scrollableParents(this.view.contentDOM, false).y;
9325
+ if (scrollParent != this.scrollParent) {
9326
+ this.scrollParent = scrollParent;
9102
9327
  this.scrollAnchorHeight = -1;
9103
- this.scrollTop = scrollTop;
9328
+ this.scrollOffset = 0;
9104
9329
  }
9105
- this.scrolledToBottom = isScrolledToBottom(view.scrollDOM);
9330
+ let scrollOffset = this.getScrollOffset();
9331
+ if (this.scrollOffset != scrollOffset) {
9332
+ this.scrollAnchorHeight = -1;
9333
+ this.scrollOffset = scrollOffset;
9334
+ }
9335
+ this.scrolledToBottom = isScrolledToBottom(this.scrollParent || view.win);
9106
9336
  let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
9107
9337
  let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
9108
9338
  this.pixelViewport = pixelViewport;
@@ -9172,7 +9402,7 @@ var ViewState = class {
9172
9402
  if (scrollTarget.y == "center") topPos = (block.top + block.bottom) / 2 - viewHeight / 2;
9173
9403
  else if (scrollTarget.y == "start" || scrollTarget.y == "nearest" && head < viewport.from) topPos = block.top;
9174
9404
  else topPos = block.bottom - viewHeight;
9175
- viewport = new Viewport(map.lineAt(topPos - 1e3 / 2, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1e3 / 2, QueryType.ByHeight, oracle, 0, 0).to);
9405
+ viewport = new Viewport(map.lineAt(topPos - 500, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 500, QueryType.ByHeight, oracle, 0, 0).to);
9176
9406
  }
9177
9407
  }
9178
9408
  return viewport;
@@ -9186,7 +9416,7 @@ var ViewState = class {
9186
9416
  let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0);
9187
9417
  let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0);
9188
9418
  let { visibleTop, visibleBottom } = this;
9189
- return (from == 0 || top <= visibleTop - Math.max(10, Math.min(-bias, 250))) && (to == this.state.doc.length || bottom >= visibleBottom + Math.max(10, Math.min(bias, 250))) && top > visibleTop - 2 * 1e3 && bottom < visibleBottom + 2 * 1e3;
9419
+ return (from == 0 || top <= visibleTop - Math.max(10, Math.min(-bias, 250))) && (to == this.state.doc.length || bottom >= visibleBottom + Math.max(10, Math.min(bias, 250))) && top > visibleTop - 2e3 && bottom < visibleBottom + 2e3;
9190
9420
  }
9191
9421
  mapLineGaps(gaps, changes) {
9192
9422
  if (!gaps.length || changes.empty) return gaps;
@@ -9309,9 +9539,12 @@ var ViewState = class {
9309
9539
  lineBlockAtHeight(height) {
9310
9540
  return height >= this.viewportLines[0].top && height <= this.viewportLines[this.viewportLines.length - 1].bottom && this.viewportLines.find((l) => l.top <= height && l.bottom >= height) || scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType.ByHeight, this.heightOracle, 0, 0), this.scaler);
9311
9541
  }
9312
- scrollAnchorAt(scrollTop) {
9313
- let block = this.lineBlockAtHeight(scrollTop + 8);
9314
- return block.from >= this.viewport.from || this.viewportLines[0].top - scrollTop > 200 ? block : this.viewportLines[0];
9542
+ getScrollOffset() {
9543
+ return (this.scrollParent == this.view.scrollDOM ? this.scrollParent.scrollTop : (this.scrollParent ? this.scrollParent.getBoundingClientRect().top : 0) - this.view.contentDOM.getBoundingClientRect().top) * this.scaleY;
9544
+ }
9545
+ scrollAnchorAt(scrollOffset) {
9546
+ let block = this.lineBlockAtHeight(scrollOffset + 8);
9547
+ return block.from >= this.viewport.from || this.viewportLines[0].top - scrollOffset > 200 ? block : this.viewportLines[0];
9315
9548
  }
9316
9549
  elementAtHeight(height) {
9317
9550
  return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
@@ -9449,9 +9682,11 @@ function scaleBlock(block, scaler) {
9449
9682
  let bTop = scaler.toDOM(block.top), bBottom = scaler.toDOM(block.bottom);
9450
9683
  return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block._content) ? block._content.map((b) => scaleBlock(b, scaler)) : block._content);
9451
9684
  }
9452
- const theme = /* @__PURE__ */ Facet.define({ combine: (strs) => strs.join(" ") });
9453
- const darkTheme = /* @__PURE__ */ Facet.define({ combine: (values) => values.indexOf(true) > -1 });
9454
- const baseThemeID = /* @__PURE__ */ StyleModule.newName(), baseLightID = /* @__PURE__ */ StyleModule.newName(), baseDarkID = /* @__PURE__ */ StyleModule.newName();
9685
+ const theme = /*@__PURE__*/ Facet.define({ combine: (strs) => strs.join(" ") });
9686
+ const darkTheme = /*@__PURE__*/ Facet.define({ combine: (values) => values.indexOf(true) > -1 });
9687
+ const baseThemeID = /*@__PURE__*/ StyleModule.newName();
9688
+ const baseLightID = /*@__PURE__*/ StyleModule.newName();
9689
+ const baseDarkID = /*@__PURE__*/ StyleModule.newName();
9455
9690
  const lightDarkIDs = {
9456
9691
  "&light": "." + baseLightID,
9457
9692
  "&dark": "." + baseDarkID
@@ -9465,7 +9700,7 @@ function buildTheme(main, spec, scopes) {
9465
9700
  }) : main + " " + sel;
9466
9701
  } });
9467
9702
  }
9468
- const baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
9703
+ const baseTheme$1 = /*@__PURE__*/ buildTheme("." + baseThemeID, {
9469
9704
  "&": {
9470
9705
  position: "relative !important",
9471
9706
  boxSizing: "border-box",
@@ -9511,6 +9746,7 @@ const baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
9511
9746
  padding: "0 2px 0 6px"
9512
9747
  },
9513
9748
  ".cm-layer": {
9749
+ userSelect: "none",
9514
9750
  position: "absolute",
9515
9751
  left: 0,
9516
9752
  top: 0,
@@ -9540,6 +9776,21 @@ const baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
9540
9776
  },
9541
9777
  ".cm-cursor": { display: "none" },
9542
9778
  "&dark .cm-cursor": { borderLeftColor: "#ddd" },
9779
+ ".cm-selectionHandle": {
9780
+ backgroundColor: "currentColor",
9781
+ width: "1.5px"
9782
+ },
9783
+ ".cm-selectionHandle-start::before, .cm-selectionHandle-end::before": {
9784
+ content: "\"\"",
9785
+ backgroundColor: "inherit",
9786
+ borderRadius: "50%",
9787
+ width: "8px",
9788
+ height: "8px",
9789
+ position: "absolute",
9790
+ left: "-3.25px"
9791
+ },
9792
+ ".cm-selectionHandle-start::before": { top: "-8px" },
9793
+ ".cm-selectionHandle-end::before": { bottom: "-8px" },
9543
9794
  ".cm-dropCursor": { position: "absolute" },
9544
9795
  "&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": { display: "block" },
9545
9796
  ".cm-iso": { unicodeBidi: "isolate" },
@@ -9600,6 +9851,8 @@ const baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
9600
9851
  backgroundColor: "#f5f5f5",
9601
9852
  color: "black"
9602
9853
  },
9854
+ ".cm-panels-top": { top: "0" },
9855
+ ".cm-panels-bottom": { bottom: "0" },
9603
9856
  "&light .cm-panels-top": { borderBottom: "1px solid #ddd" },
9604
9857
  "&light .cm-panels-bottom": { borderTop: "1px solid #ddd" },
9605
9858
  "&dark .cm-panels": {
@@ -9980,18 +10233,20 @@ var DOMObserver = class {
9980
10233
  }
9981
10234
  addWindowListeners(win) {
9982
10235
  win.addEventListener("resize", this.onResize);
9983
- if (this.printQuery) if (this.printQuery.addEventListener) this.printQuery.addEventListener("change", this.onPrint);
9984
- else this.printQuery.addListener(this.onPrint);
9985
- else win.addEventListener("beforeprint", this.onPrint);
10236
+ if (this.printQuery) {
10237
+ if (this.printQuery.addEventListener) this.printQuery.addEventListener("change", this.onPrint);
10238
+ else this.printQuery.addListener(this.onPrint);
10239
+ } else win.addEventListener("beforeprint", this.onPrint);
9986
10240
  win.addEventListener("scroll", this.onScroll);
9987
10241
  win.document.addEventListener("selectionchange", this.onSelectionChange);
9988
10242
  }
9989
10243
  removeWindowListeners(win) {
9990
10244
  win.removeEventListener("scroll", this.onScroll);
9991
10245
  win.removeEventListener("resize", this.onResize);
9992
- if (this.printQuery) if (this.printQuery.removeEventListener) this.printQuery.removeEventListener("change", this.onPrint);
9993
- else this.printQuery.removeListener(this.onPrint);
9994
- else win.removeEventListener("beforeprint", this.onPrint);
10246
+ if (this.printQuery) {
10247
+ if (this.printQuery.removeEventListener) this.printQuery.removeEventListener("change", this.onPrint);
10248
+ else this.printQuery.removeListener(this.onPrint);
10249
+ } else win.removeEventListener("beforeprint", this.onPrint);
9995
10250
  win.document.removeEventListener("selectionchange", this.onSelectionChange);
9996
10251
  }
9997
10252
  update(update) {
@@ -10154,7 +10409,6 @@ var EditContextManager = class {
10154
10409
  };
10155
10410
  for (let event in this.handlers) context.addEventListener(event, this.handlers[event]);
10156
10411
  this.measureReq = { read: (view) => {
10157
- this.editContext.updateControlBounds(view.contentDOM.getBoundingClientRect());
10158
10412
  let sel = getSelection(view.root);
10159
10413
  if (sel && sel.rangeCount) this.editContext.updateSelectionBounds(sel.getRangeAt(0).getBoundingClientRect());
10160
10414
  } };
@@ -10164,14 +10418,16 @@ var EditContextManager = class {
10164
10418
  update.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {
10165
10419
  if (abort) return;
10166
10420
  let dLen = insert.length - (toA - fromA);
10167
- if (pending && toA >= pending.to) if (pending.from == fromA && pending.to == toA && pending.insert.eq(insert)) {
10168
- pending = this.pendingContextChange = null;
10169
- off += dLen;
10170
- this.to += dLen;
10171
- return;
10172
- } else {
10173
- pending = null;
10174
- this.revertPending(update.state);
10421
+ if (pending && toA >= pending.to) {
10422
+ if (pending.from == fromA && pending.to == toA && pending.insert.eq(insert)) {
10423
+ pending = this.pendingContextChange = null;
10424
+ off += dLen;
10425
+ this.to += dLen;
10426
+ return;
10427
+ } else {
10428
+ pending = null;
10429
+ this.revertPending(update.state);
10430
+ }
10175
10431
  }
10176
10432
  fromA += off;
10177
10433
  toA += off;
@@ -10225,7 +10481,7 @@ var EditContextManager = class {
10225
10481
  }
10226
10482
  rangeIsValid(state) {
10227
10483
  let { head } = state.selection.main;
10228
- return !(this.from > 0 && head - this.from < 500 || this.to < state.doc.length && this.to - head < 500 || this.to - this.from > 1e4 * 3);
10484
+ return !(this.from > 0 && head - this.from < 500 || this.to < state.doc.length && this.to - head < 500 || this.to - this.from > 3e4);
10229
10485
  }
10230
10486
  toEditorPos(contextPos, clipLen = this.to - this.from) {
10231
10487
  contextPos = Math.min(contextPos, clipLen);
@@ -10351,7 +10607,7 @@ var EditorView = class EditorView {
10351
10607
  this.dispatchTransactions = config.dispatchTransactions || dispatch && ((trs) => trs.forEach((tr) => dispatch(tr, this))) || ((trs) => this.update(trs));
10352
10608
  this.dispatch = this.dispatch.bind(this);
10353
10609
  this._root = config.root || getRoot(config.parent) || document;
10354
- this.viewState = new ViewState(config.state || EditorState.create(config));
10610
+ this.viewState = new ViewState(this, config.state || EditorState.create(config));
10355
10611
  if (config.scrollTo && config.scrollTo.is(scrollIntoView)) this.viewState.scrollTarget = config.scrollTo.value.clip(this.viewState.state);
10356
10612
  this.plugins = this.state.facet(viewPlugin).map((spec) => new PluginInstance(spec));
10357
10613
  for (let plugin of this.plugins) plugin.update(this);
@@ -10364,7 +10620,7 @@ var EditorView = class EditorView {
10364
10620
  this.updateState = 0;
10365
10621
  this.requestMeasure();
10366
10622
  if ((_a = document.fonts) === null || _a === void 0 ? void 0 : _a.ready) document.fonts.ready.then(() => {
10367
- this.viewState.mustMeasureContent = true;
10623
+ this.viewState.mustMeasureContent = "refresh";
10368
10624
  this.requestMeasure();
10369
10625
  });
10370
10626
  }
@@ -10417,7 +10673,8 @@ var EditorView = class EditorView {
10417
10673
  if (scrollTarget) scrollTarget = scrollTarget.map(tr.changes);
10418
10674
  if (tr.scrollIntoView) {
10419
10675
  let { main } = tr.state.selection;
10420
- scrollTarget = new ScrollTarget(main.empty ? main : EditorSelection.cursor(main.head, main.head > main.anchor ? -1 : 1));
10676
+ let { x, y } = this.state.facet(EditorView.cursorScrollMargin);
10677
+ scrollTarget = new ScrollTarget(main.empty ? main : EditorSelection.cursor(main.head, main.head > main.anchor ? -1 : 1), "nearest", "nearest", y, x);
10421
10678
  }
10422
10679
  for (let e of tr.effects) if (e.is(scrollIntoView)) scrollTarget = e.value.clip(this.state);
10423
10680
  }
@@ -10467,7 +10724,7 @@ var EditorView = class EditorView {
10467
10724
  let hadFocus = this.hasFocus;
10468
10725
  try {
10469
10726
  for (let plugin of this.plugins) plugin.destroy(this);
10470
- this.viewState = new ViewState(newState);
10727
+ this.viewState = new ViewState(this, newState);
10471
10728
  this.plugins = newState.facet(viewPlugin).map((spec) => new PluginInstance(spec));
10472
10729
  this.pluginMap.clear();
10473
10730
  for (let plugin of this.plugins) plugin.update(this);
@@ -10527,22 +10784,24 @@ var EditorView = class EditorView {
10527
10784
  this.measureScheduled = 0;
10528
10785
  if (flush) this.observer.forceFlush();
10529
10786
  let updated = null;
10530
- let sDOM = this.scrollDOM, scrollTop = sDOM.scrollTop * this.scaleY;
10787
+ let scroll = this.viewState.scrollParent, scrollOffset = this.viewState.getScrollOffset();
10531
10788
  let { scrollAnchorPos, scrollAnchorHeight } = this.viewState;
10532
- if (Math.abs(scrollTop - this.viewState.scrollTop) > 1) scrollAnchorHeight = -1;
10789
+ if (Math.abs(scrollOffset - this.viewState.scrollOffset) > 1) scrollAnchorHeight = -1;
10533
10790
  this.viewState.scrollAnchorHeight = -1;
10534
10791
  try {
10535
10792
  for (let i = 0;; i++) {
10536
- if (scrollAnchorHeight < 0) if (isScrolledToBottom(sDOM)) {
10537
- scrollAnchorPos = -1;
10538
- scrollAnchorHeight = this.viewState.heightMap.height;
10539
- } else {
10540
- let block = this.viewState.scrollAnchorAt(scrollTop);
10541
- scrollAnchorPos = block.from;
10542
- scrollAnchorHeight = block.top;
10793
+ if (scrollAnchorHeight < 0) {
10794
+ if (isScrolledToBottom(scroll || this.win)) {
10795
+ scrollAnchorPos = -1;
10796
+ scrollAnchorHeight = this.viewState.heightMap.height;
10797
+ } else {
10798
+ let block = this.viewState.scrollAnchorAt(scrollOffset);
10799
+ scrollAnchorPos = block.from;
10800
+ scrollAnchorHeight = block.top;
10801
+ }
10543
10802
  }
10544
10803
  this.updateState = 1;
10545
- let changed = this.viewState.measure(this);
10804
+ let changed = this.viewState.measure();
10546
10805
  if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null) break;
10547
10806
  if (i > 5) {
10548
10807
  console.warn(this.measureRequests.length ? "Measure loop restarted more than 5 times" : "Viewport failed to stabilize");
@@ -10578,18 +10837,21 @@ var EditorView = class EditorView {
10578
10837
  }
10579
10838
  if (redrawn) this.docView.updateSelection(true);
10580
10839
  if (!update.viewportChanged && this.measureRequests.length == 0) {
10581
- if (this.viewState.editorHeight) if (this.viewState.scrollTarget) {
10582
- this.docView.scrollIntoView(this.viewState.scrollTarget);
10583
- this.viewState.scrollTarget = null;
10584
- scrollAnchorHeight = -1;
10585
- continue;
10586
- } else {
10587
- let diff = (scrollAnchorPos < 0 ? this.viewState.heightMap.height : this.viewState.lineBlockAt(scrollAnchorPos).top) - scrollAnchorHeight;
10588
- if (diff > 1 || diff < -1) {
10589
- scrollTop = scrollTop + diff;
10590
- sDOM.scrollTop = scrollTop / this.scaleY;
10840
+ if (this.viewState.editorHeight) {
10841
+ if (this.viewState.scrollTarget) {
10842
+ this.docView.scrollIntoView(this.viewState.scrollTarget);
10843
+ this.viewState.scrollTarget = null;
10591
10844
  scrollAnchorHeight = -1;
10592
10845
  continue;
10846
+ } else {
10847
+ let diff = ((scrollAnchorPos < 0 ? this.viewState.heightMap.height : this.viewState.lineBlockAt(scrollAnchorPos).top) - scrollAnchorHeight) / this.scaleY;
10848
+ if ((diff > 1 || diff < -1) && !(browser.ios && this.inputState.lastIOSMomentumScroll > Date.now() - 100) && (scroll == this.scrollDOM || this.hasFocus || Math.max(this.inputState.lastWheelEvent, this.inputState.lastTouchTime) > Date.now() - 100)) {
10849
+ scrollOffset = scrollOffset + diff;
10850
+ if (scroll) scroll.scrollTop += diff;
10851
+ else this.win.scrollBy(0, diff);
10852
+ scrollAnchorHeight = -1;
10853
+ continue;
10854
+ }
10593
10855
  }
10594
10856
  }
10595
10857
  break;
@@ -10861,11 +11123,9 @@ var EditorView = class EditorView {
10861
11123
  */
10862
11124
  coordsAtPos(pos, side = 1) {
10863
11125
  this.readMeasured();
10864
- let rect = this.docView.coordsAt(pos, side);
10865
- if (!rect || rect.left == rect.right) return rect;
10866
11126
  let line = this.state.doc.lineAt(pos), order = this.bidiSpans(line);
10867
11127
  let span = order[BidiSpan.find(order, pos - line.from, -1, side)];
10868
- return flattenRect(rect, span.dir == Direction.LTR == side > 0);
11128
+ return this.docView.coordsAt(pos, side, span.dir == Direction.RTL);
10869
11129
  }
10870
11130
  /**
10871
11131
  Return the rectangle around a given character. If `pos` does not
@@ -10991,7 +11251,8 @@ var EditorView = class EditorView {
10991
11251
  cause it to scroll the given position or range into view.
10992
11252
  */
10993
11253
  static scrollIntoView(pos, options = {}) {
10994
- return scrollIntoView.of(new ScrollTarget(typeof pos == "number" ? EditorSelection.cursor(pos) : pos, options.y, options.x, options.yMargin, options.xMargin));
11254
+ var _a, _b, _c, _d;
11255
+ return scrollIntoView.of(new ScrollTarget(typeof pos == "number" ? EditorSelection.cursor(pos) : pos, (_a = options.y) !== null && _a !== void 0 ? _a : "nearest", (_b = options.x) !== null && _b !== void 0 ? _b : "nearest", (_c = options.yMargin) !== null && _c !== void 0 ? _c : 5, (_d = options.xMargin) !== null && _d !== void 0 ? _d : 5));
10995
11256
  }
10996
11257
  /**
10997
11258
  Return an effect that resets the editor to its current (at the
@@ -11054,7 +11315,7 @@ var EditorView = class EditorView {
11054
11315
  }
11055
11316
  /**
11056
11317
  Create a theme extension. The first argument can be a
11057
- [`style-mod`](https://github.com/marijnh/style-mod#documentation)
11318
+ [`style-mod`](https://code.haverbeke.berlin/marijn/style-mod#documentation)
11058
11319
  style spec providing the styles for the theme. These will be
11059
11320
  prefixed with a generated class for the style.
11060
11321
 
@@ -11099,7 +11360,7 @@ var EditorView = class EditorView {
11099
11360
  };
11100
11361
  /**
11101
11362
  Facet to add a [style
11102
- module](https://github.com/marijnh/style-mod#documentation) to
11363
+ module](https://code.haverbeke.berlin/marijn/style-mod#documentation) to
11103
11364
  an editor view. The view will ensure that the module is
11104
11365
  mounted in its [document
11105
11366
  root](https://codemirror.net/6/docs/ref/#view.EditorView.constructor^config.root).
@@ -11246,11 +11507,27 @@ supported.)
11246
11507
  */
11247
11508
  EditorView.bidiIsolatedRanges = bidiIsolatedRanges;
11248
11509
  /**
11510
+ Can be used to specify the distance that scrolling cursor into
11511
+ view keeps it away from the sides of the editor, either as a
11512
+ single pixel number or two different values for the different
11513
+ axes. Defaults to 5 pixels on both axes.
11514
+ */
11515
+ EditorView.cursorScrollMargin = /*@__PURE__*/ Facet.define({ combine: (inputs) => {
11516
+ let x = 5, y = 5;
11517
+ for (let i of inputs) if (typeof i == "number") x = y = i;
11518
+ else ({x, y} = i);
11519
+ return {
11520
+ x,
11521
+ y
11522
+ };
11523
+ } });
11524
+ /**
11249
11525
  Facet that allows extensions to provide additional scroll
11250
11526
  margins (space around the sides of the scrolling element that
11251
11527
  should be considered invisible). This can be useful when the
11252
11528
  plugin introduces elements that cover part of that element (for
11253
- example a horizontally fixed gutter).
11529
+ example a horizontally fixed gutter). Not to be confused with
11530
+ [`cursorScrollMargin`](https://codemirror.net/6/docs/ref/#view.EditorView^cursorScrollMargin).
11254
11531
  */
11255
11532
  EditorView.scrollMargins = scrollMargins;
11256
11533
  /**
@@ -11265,7 +11542,7 @@ Provides a Content Security Policy nonce to use when creating
11265
11542
  the style sheets for the editor. Holds the empty string when no
11266
11543
  nonce has been provided.
11267
11544
  */
11268
- EditorView.cspNonce = /* @__PURE__ */ Facet.define({ combine: (values) => values.length ? values[0] : "" });
11545
+ EditorView.cspNonce = /*@__PURE__*/ Facet.define({ combine: (values) => values.length ? values[0] : "" });
11269
11546
  /**
11270
11547
  Facet that provides additional DOM attributes for the editor's
11271
11548
  editable DOM element.
@@ -11280,7 +11557,7 @@ EditorView.editorAttributes = editorAttributes;
11280
11557
  An extension that enables line wrapping in the editor (by
11281
11558
  setting CSS `white-space` to `pre-wrap` in the content).
11282
11559
  */
11283
- EditorView.lineWrapping = /* @__PURE__ */ EditorView.contentAttributes.of({ "class": "cm-lineWrapping" });
11560
+ EditorView.lineWrapping = /*@__PURE__*/ EditorView.contentAttributes.of({ "class": "cm-lineWrapping" });
11284
11561
  /**
11285
11562
  State effect used to include screen reader announcements in a
11286
11563
  transaction. These will be added to the DOM in a visually hidden
@@ -11289,7 +11566,7 @@ describe effects that are visually obvious but may not be
11289
11566
  noticed by screen reader users (such as moving to the next
11290
11567
  search match).
11291
11568
  */
11292
- EditorView.announce = /* @__PURE__ */ StateEffect.define();
11569
+ EditorView.announce = /*@__PURE__*/ StateEffect.define();
11293
11570
  const MaxBidiLine = 4096;
11294
11571
  const BadMeasure = {};
11295
11572
  var CachedOrder = class CachedOrder {
@@ -11318,8 +11595,9 @@ function attrsFromFacet(view, facet, base) {
11318
11595
  }
11319
11596
  return base;
11320
11597
  }
11321
- const currentPlatform = browser.mac ? "mac" : browser.windows ? "win" : browser.linux ? "linux" : "key";
11322
- const UnicodeRegexpSupport = /x/.unicode != null ? "gu" : "g";
11598
+ browser.mac || browser.windows || browser.linux;
11599
+ browser.gecko && browser.gecko_version;
11600
+ /x/.unicode;
11323
11601
  /**
11324
11602
  A gutter marker represents a bit of information attached to a line
11325
11603
  in a specific gutter. Your own custom markers have to extend this
@@ -11349,7 +11627,6 @@ GutterMarker.prototype.toDOM = void 0;
11349
11627
  GutterMarker.prototype.mapMode = MapMode.TrackBefore;
11350
11628
  GutterMarker.prototype.startSide = GutterMarker.prototype.endSide = -1;
11351
11629
  GutterMarker.prototype.point = true;
11352
-
11353
11630
  //#endregion
11354
11631
  //#region src/components/editor/use-format-code.ts
11355
11632
  const DEFAULT_PRETTIER_OPTIONS = {
@@ -11381,7 +11658,6 @@ const useFormatCode = ({ fragment, prettierOptions } = {}) => {
11381
11658
  return formatted;
11382
11659
  }, [prettierConfig, fragment]);
11383
11660
  };
11384
-
11385
11661
  //#endregion
11386
11662
  //#region src/components/editor/core.tsx
11387
11663
  const Core = ({ value, theme, height, className, prettierOptions, fragment, raw, onChange, onSave: _onSave, onError, ...props }) => {
@@ -11425,7 +11701,8 @@ const Core = ({ value, theme, height, className, prettierOptions, fragment, raw,
11425
11701
  const onKeyDown = useCallback((e) => {
11426
11702
  if ((e.metaKey || e.ctrlKey) && e.key === "s") {
11427
11703
  e.preventDefault();
11428
- onSave(editorRef.current?.view?.state.doc.toString() || value);
11704
+ const currentValue = editorRef.current?.view?.state.doc.toString() || value;
11705
+ onSave(currentValue);
11429
11706
  }
11430
11707
  }, [onSave, value]);
11431
11708
  return /* @__PURE__ */ jsx("div", {
@@ -11445,7 +11722,6 @@ const Core = ({ value, theme, height, className, prettierOptions, fragment, raw,
11445
11722
  })
11446
11723
  });
11447
11724
  };
11448
-
11449
11725
  //#endregion
11450
11726
  //#region src/components/editor/tiptap.tsx
11451
11727
  const Tiptap = ({ value = "", placeholder = "Enter text...", className, onChange }) => {
@@ -11466,11 +11742,10 @@ const Tiptap = ({ value = "", placeholder = "Enter text...", className, onChange
11466
11742
  py-2`, "prose prose-sm max-w-none text-sm text-gray-800", "[&_.tiptap]:outline-none", "[&_.tiptap_p.is-editor-empty:first-child::before]:pointer-events-none", "[&_.tiptap_p.is-editor-empty:first-child::before]:float-left", "[&_.tiptap_p.is-editor-empty:first-child::before]:h-0", "[&_.tiptap_p.is-editor-empty:first-child::before]:text-gray-400", "[&_.tiptap_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]", className)
11467
11743
  });
11468
11744
  };
11469
-
11470
11745
  //#endregion
11471
11746
  //#region src/components/dnd/panel/selection.ts
11472
- var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$1());
11473
11747
  var import_lib = require_lib();
11748
+ var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$1(), 1);
11474
11749
  const removeIndices = (items, indices) => {
11475
11750
  return items.filter((_, index) => !indices.has(index));
11476
11751
  };
@@ -11496,7 +11771,6 @@ const moveSelectedIndices = (items, indices, direction) => {
11496
11771
  indices: nextIndices
11497
11772
  };
11498
11773
  };
11499
-
11500
11774
  //#endregion
11501
11775
  //#region src/components/dnd/panel/items.tsx
11502
11776
  const BulkActionsBar = ({ count, onDuplicate, onMoveUp, onMoveDown, onDelete, onClear }) => {
@@ -11573,7 +11847,8 @@ const Items = ({ value, render, onChange, onChildChange }) => {
11573
11847
  if (!import_lib$1.isObjectProperty(prop) || !import_lib$1.isIdentifier(prop.key) || !import_lib$1.isJSXElement(prop.value)) return;
11574
11848
  const propertyName = prop.key.name;
11575
11849
  try {
11576
- const nodes = extract(generateCode(prop.value));
11850
+ const jsxCode = generateCode(prop.value);
11851
+ const nodes = extract(jsxCode);
11577
11852
  const bindings = [];
11578
11853
  const bindingContainer = nodes.find((node) => node.bindings?.some((b) => b.property === "children"));
11579
11854
  if (bindingContainer) bindings.push(bindingContainer);
@@ -11632,7 +11907,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
11632
11907
  const nextElements = removeIndices(allElements, indices);
11633
11908
  onChange?.(generateCode(import_lib$1.arrayExpression(nextElements)));
11634
11909
  };
11635
- const deletePrimitive = (index) => deleteSelectedPrimitives(new Set([index]));
11910
+ const deletePrimitive = (index) => deleteSelectedPrimitives(/* @__PURE__ */ new Set([index]));
11636
11911
  const addPrimitive = () => {
11637
11912
  const first = primitiveItems[0];
11638
11913
  if (!first) return;
@@ -11706,10 +11981,11 @@ const Items = ({ value, render, onChange, onChildChange }) => {
11706
11981
  };
11707
11982
  const deleteSelectedItems = (indices) => {
11708
11983
  if (objectItems.length - indices.size < 1) return;
11709
- const nextValue = arrayExpressionToCode(removeIndices(objectItems, indices).map((item) => item.originalElement));
11984
+ const nextItems = removeIndices(objectItems, indices);
11985
+ const nextValue = arrayExpressionToCode(nextItems.map((item) => item.originalElement));
11710
11986
  onChange?.(nextValue);
11711
11987
  };
11712
- const deleteItem = (index) => deleteSelectedItems(new Set([index]));
11988
+ const deleteItem = (index) => deleteSelectedItems(/* @__PURE__ */ new Set([index]));
11713
11989
  const cloneObjectItemElement = (source) => {
11714
11990
  const clonedElement = clone(source.originalElement);
11715
11991
  clonedElement.properties.forEach((prop) => {
@@ -11980,7 +12256,6 @@ const Items = ({ value, render, onChange, onChildChange }) => {
11980
12256
  ]
11981
12257
  });
11982
12258
  };
11983
-
11984
12259
  //#endregion
11985
12260
  //#region src/components/dnd/panel/children.tsx
11986
12261
  const Children = ({ value, onChange, onNodeChange }) => {
@@ -12010,9 +12285,10 @@ const Children = ({ value, onChange, onNodeChange }) => {
12010
12285
  const nextItems = removeIndices(items, indices);
12011
12286
  onChange?.(JSON.stringify(nextItems));
12012
12287
  };
12013
- const deleteItem = (index) => deleteSelectedItems(new Set([index]));
12288
+ const deleteItem = (index) => deleteSelectedItems(/* @__PURE__ */ new Set([index]));
12014
12289
  const addItem = () => {
12015
- const newItem = cloneDataAttrNode(items[0] || createDefaultItem());
12290
+ const template = items[0] || createDefaultItem();
12291
+ const newItem = cloneDataAttrNode(template);
12016
12292
  const nextItems = [...items, newItem];
12017
12293
  onChange?.(JSON.stringify(nextItems));
12018
12294
  };
@@ -12173,7 +12449,6 @@ const Children = ({ value, onChange, onNodeChange }) => {
12173
12449
  ]
12174
12450
  });
12175
12451
  };
12176
-
12177
12452
  //#endregion
12178
12453
  //#region src/components/dnd/panel/icon-map.ts
12179
12454
  const ICON_MAP = {
@@ -12215,7 +12490,6 @@ const ICON_MAP = {
12215
12490
  User,
12216
12491
  X
12217
12492
  };
12218
-
12219
12493
  //#endregion
12220
12494
  //#region src/components/dnd/panel/field.tsx
12221
12495
  const isColorProperty = (propertyName) => {
@@ -12236,6 +12510,43 @@ const parseDateValue = (value) => {
12236
12510
  const formatDateValue = (date) => {
12237
12511
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
12238
12512
  };
12513
+ const COLOR_COMMIT_DELAY = 75;
12514
+ const ColorPickerField = ({ id, label, value, onChange }) => {
12515
+ const [liveValue, setLiveValue] = useState(value);
12516
+ const [prevValue, setPrevValue] = useState(value);
12517
+ const lastCommittedRef = useRef(value);
12518
+ if (value !== prevValue) {
12519
+ setPrevValue(value);
12520
+ setLiveValue(value);
12521
+ }
12522
+ useEffect(() => {
12523
+ lastCommittedRef.current = value;
12524
+ }, [value]);
12525
+ const commit = (next) => {
12526
+ if (next === lastCommittedRef.current) return;
12527
+ lastCommittedRef.current = next;
12528
+ onChange?.({
12529
+ id,
12530
+ label,
12531
+ value: next
12532
+ });
12533
+ };
12534
+ const debouncedCommit = useDebounce(() => commit(liveValue), {
12535
+ delay: COLOR_COMMIT_DELAY,
12536
+ autoInvoke: false
12537
+ });
12538
+ return /* @__PURE__ */ jsx(ColorPicker, {
12539
+ showText: true,
12540
+ value: liveValue,
12541
+ onChange: (next) => {
12542
+ setLiveValue(next);
12543
+ debouncedCommit();
12544
+ },
12545
+ onOpenChange: (open) => {
12546
+ if (!open) commit(liveValue);
12547
+ }
12548
+ });
12549
+ };
12239
12550
  const ICON_OPTIONS = Object.entries(ICON_MAP).map(([name, Icon]) => ({
12240
12551
  label: /* @__PURE__ */ jsxs("span", {
12241
12552
  className: "flex items-center gap-2",
@@ -12350,16 +12661,11 @@ const Field = ({ binding, id, value, onChange }) => {
12350
12661
  });
12351
12662
  }
12352
12663
  });
12353
- if (binding.type === "color" || isColorProperty(binding.property)) return /* @__PURE__ */ jsx(ColorPicker, {
12354
- showText: true,
12664
+ if (binding.type === "color" || isColorProperty(binding.property)) return /* @__PURE__ */ jsx(ColorPickerField, {
12665
+ id,
12666
+ label: binding.label,
12355
12667
  value: normalizeToHex(stringValue),
12356
- onChange: (next) => {
12357
- if (next !== value) onChange?.({
12358
- id,
12359
- label: binding.label,
12360
- value: next
12361
- });
12362
- }
12668
+ onChange
12363
12669
  });
12364
12670
  if (binding.type === "date") return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(DatePicker, {
12365
12671
  defaultValue: parseDateValue(stringValue),
@@ -12515,7 +12821,6 @@ const Field = ({ binding, id, value, onChange }) => {
12515
12821
  children: validationError
12516
12822
  })] });
12517
12823
  };
12518
-
12519
12824
  //#endregion
12520
12825
  //#region src/components/dnd/panel/node.tsx
12521
12826
  const Node = ({ data, onChange }) => {
@@ -12554,21 +12859,21 @@ const Node = ({ data, onChange }) => {
12554
12859
  })
12555
12860
  });
12556
12861
  };
12557
-
12558
12862
  //#endregion
12559
12863
  //#region src/components/dnd/panel/panel.tsx
12560
12864
  const Panel = ({ item, onChange, onDelete }) => {
12865
+ const code = item?.code;
12561
12866
  const { dataAttrNodes, updatedCode, parseError } = useMemo(() => {
12562
- if (!item?.code) return {
12867
+ if (!code) return {
12563
12868
  dataAttrNodes: [],
12564
12869
  updatedCode: "",
12565
12870
  parseError: false
12566
12871
  };
12567
12872
  try {
12568
- const updatedCode = fillIds(item.code);
12873
+ const updatedCode = fillIds(code);
12569
12874
  return {
12570
12875
  dataAttrNodes: extract(updatedCode).filter((node) => node.tagName !== "section"),
12571
- updatedCode: updatedCode !== item.code ? updatedCode : item.code,
12876
+ updatedCode: updatedCode !== code ? updatedCode : code,
12572
12877
  parseError: false
12573
12878
  };
12574
12879
  } catch (e) {
@@ -12579,7 +12884,7 @@ const Panel = ({ item, onChange, onDelete }) => {
12579
12884
  parseError: true
12580
12885
  };
12581
12886
  }
12582
- }, [item?.code]);
12887
+ }, [code]);
12583
12888
  useEffect(() => {
12584
12889
  if (parseError) Toast.error("Failed to parse this section", { description: "Check the console for details." });
12585
12890
  }, [parseError]);
@@ -12622,7 +12927,6 @@ const Panel = ({ item, onChange, onDelete }) => {
12622
12927
  ]
12623
12928
  });
12624
12929
  };
12625
-
12626
12930
  //#endregion
12627
12931
  //#region src/components/dnd/dnd.tsx
12628
12932
  const conditionalModifiers = (args) => {
@@ -12639,7 +12943,12 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
12639
12943
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 10 } }));
12640
12944
  const value = _value || DEFAULT_TEMPLATE;
12641
12945
  const sections = useMemo(() => extractSections(value), [value]);
12642
- const previews = useMemo(() => generateSections(sections.map((s) => s.code), value), [sections, value]);
12946
+ const [previewCache] = useState(() => createSectionPreviewCache());
12947
+ const previews = useMemo(() => previewCache.compute(value, sections), [
12948
+ previewCache,
12949
+ sections,
12950
+ value
12951
+ ]);
12643
12952
  const onDragStart = (_) => {};
12644
12953
  const onDragOver = (_e) => {};
12645
12954
  const onDragEnd = (event) => {
@@ -12672,7 +12981,8 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
12672
12981
  const prevIndex = sections.findIndex((s) => s.id === active.id);
12673
12982
  const nextIndex = sections.findIndex((s) => s.id === over.id);
12674
12983
  if (prevIndex >= 0 && nextIndex >= 0) {
12675
- const nextCode = replaceSections(value, arrayMove(sections, prevIndex, nextIndex).map((s) => s.code));
12984
+ const nextSections = arrayMove(sections, prevIndex, nextIndex);
12985
+ const nextCode = replaceSections(value, nextSections.map((s) => s.code));
12676
12986
  _onChange?.(nextCode);
12677
12987
  setCode(nextCode);
12678
12988
  }
@@ -12684,7 +12994,8 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
12684
12994
  name: item.name,
12685
12995
  code: item.code
12686
12996
  };
12687
- const nextCode = replaceSections(value, [...sections, newSection].map((s) => s.code));
12997
+ const nextSections = [...sections, newSection];
12998
+ const nextCode = replaceSections(value, nextSections.map((s) => s.code));
12688
12999
  _onChange?.(nextCode);
12689
13000
  setCode(nextCode);
12690
13001
  };
@@ -12720,10 +13031,11 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
12720
13031
  setSelectedId((prev) => prev === id ? null : id);
12721
13032
  };
12722
13033
  const onChange = (next) => {
12723
- const nextCode = replaceSections(value, sections.map((s) => s.id === next.id ? {
13034
+ const nextSections = sections.map((s) => s.id === next.id ? {
12724
13035
  ...s,
12725
13036
  ...next
12726
- } : s).map((s) => s.code));
13037
+ } : s);
13038
+ const nextCode = replaceSections(value, nextSections.map((s) => s.code));
12727
13039
  _onChange?.(nextCode);
12728
13040
  setCode(nextCode);
12729
13041
  };
@@ -12858,12 +13170,10 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
12858
13170
  }) })]
12859
13171
  }) });
12860
13172
  };
12861
-
12862
13173
  //#endregion
12863
13174
  //#region src/components/dnd/index.ts
12864
13175
  const Dnd = Dnd$1;
12865
13176
  Dnd.DraggableItem = DraggableItem;
12866
-
12867
13177
  //#endregion
12868
13178
  //#region src/components/editor/editor.tsx
12869
13179
  const Editor$1 = ({ defaultValue, value: _value, debounce = 1e3, onChange: _onChange, renderEditor, fragment, prettierOptions, ...props }) => {
@@ -12902,12 +13212,10 @@ const Editor$1 = ({ defaultValue, value: _value, debounce = 1e3, onChange: _onCh
12902
13212
  ...props
12903
13213
  });
12904
13214
  };
12905
-
12906
13215
  //#endregion
12907
13216
  //#region src/components/editor/index.ts
12908
13217
  const Editor = Editor$1;
12909
13218
  Editor.Core = Core;
12910
-
12911
13219
  //#endregion
12912
13220
  //#region src/components/error/error.tsx
12913
13221
  const Error$2 = ({ message, title = "An error occurred", className, onReset }) => {
@@ -12956,7 +13264,6 @@ const Error$2 = ({ message, title = "An error occurred", className, onReset }) =
12956
13264
  ]
12957
13265
  });
12958
13266
  };
12959
-
12960
13267
  //#endregion
12961
13268
  //#region src/components/error/boundary.tsx
12962
13269
  var ErrorBoundary = class extends React.Component {
@@ -12995,7 +13302,6 @@ var ErrorBoundary = class extends React.Component {
12995
13302
  return this.props.children;
12996
13303
  }
12997
13304
  };
12998
-
12999
13305
  //#endregion
13000
13306
  //#region src/components/error/guard.tsx
13001
13307
  const Guard = ({ children, onError }) => {
@@ -13046,7 +13352,6 @@ const Guard = ({ children, onError }) => {
13046
13352
  children
13047
13353
  });
13048
13354
  };
13049
-
13050
13355
  //#endregion
13051
13356
  //#region src/components/error/runtime.tsx
13052
13357
  const Runtime = ({ open = true, reset }) => {
@@ -13065,14 +13370,12 @@ const Runtime = ({ open = true, reset }) => {
13065
13370
  title: "Runtime Error"
13066
13371
  });
13067
13372
  };
13068
-
13069
13373
  //#endregion
13070
13374
  //#region src/components/error/index.ts
13071
13375
  const Error$1 = Error$2;
13072
13376
  Error$1.Boundary = ErrorBoundary;
13073
13377
  Error$1.Runtime = Runtime;
13074
13378
  Error$1.Guard = Guard;
13075
-
13076
13379
  //#endregion
13077
13380
  //#region src/components/preview/client.tsx
13078
13381
  const Client = ({ code: _code = "", className, showError, props = {}, modules = {}, frame, provider }) => {
@@ -13140,7 +13443,6 @@ const Client = ({ code: _code = "", className, showError, props = {}, modules =
13140
13443
  })
13141
13444
  }), /* @__PURE__ */ jsx(Error$1.Runtime, { open: isError })] });
13142
13445
  };
13143
-
13144
13446
  //#endregion
13145
13447
  //#region src/components/preview/preview.tsx
13146
13448
  const Preview = ({ code, props = {}, modules = {}, dynamicTailwind = false, provider, ...restProps }) => {
@@ -13212,7 +13514,6 @@ const Preview = ({ code, props = {}, modules = {}, dynamicTailwind = false, prov
13212
13514
  ...restProps
13213
13515
  });
13214
13516
  };
13215
-
13216
13517
  //#endregion
13217
13518
  //#region src/index.tsx
13218
13519
  const App = ({ children }) => {
@@ -13224,7 +13525,7 @@ App.Renderer = LiveRenderer;
13224
13525
  App.Error = Error$1;
13225
13526
  App.Editor = Editor;
13226
13527
  App.Dnd = Dnd;
13227
-
13228
13528
  //#endregion
13229
13529
  export { Dnd as LiveDnd, Editor as LiveEditor, Error$1 as LiveError, Preview as LivePreview, App as LiveProvider, App as default, LiveRenderer };
13530
+
13230
13531
  //# sourceMappingURL=index.mjs.map