@weasel-js/text-dom 1.13.0 → 1.14.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.d.ts CHANGED
@@ -337,7 +337,7 @@ declare function domPositionToCharOffset(parent: HTMLElement, node: Node, offset
337
337
  declare function domToRuns(parent: HTMLElement): StyledRun[];
338
338
  /** What a run inherits from its node, for the overlay's small caps: which
339
339
  * runs have it, and the face and transform that decide their pieces. */
340
- type OverlayRunBase = Pick<ResolvedTextStyle, 'fontFamily' | 'fontWeight' | 'fontStyle' | 'textTransform' | 'fontVariantCaps'>;
340
+ type OverlayRunBase = Pick<ResolvedTextStyle, 'fontFamily' | 'fontWeight' | 'fontStyle' | 'textTransform' | 'fontVariantCaps' | 'lang'>;
341
341
  /**
342
342
  * Replace `parent`'s children with one `<span data-run>` per run. `base` is
343
343
  * the node's style, which a run inheriting small caps is split by.
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { useRef, useState, useCallback, useEffect } from 'react';
2
2
  import { useLatest, useVisibleRaf } from '@weasel-js/react';
3
3
  import { DEFAULT_TEXT_STYLE, smallCapsScaleFor, numericWeight, resolveTextStyle, styleAtRange, unboldPatch, nodeHasFlag, setFlagOverRange, applyStyleToRange, patchRangeStyle, effectiveRangeStyle, SMALL_CAPS_SCALE, isHardLineBreak, runsCarryStyling, runsToPlainText, fontString, supersededKey, rangeWeight, scriptMetricsFor, transformRunTexts, smallCapsText, resolveAlign, paragraphDirection, layoutTextPose, verticalAlignOffset } from '@weasel-js/text';
4
4
  import { cssFontFamily, cssFontFamilyLoading, isCanvasFont } from '@weasel-js/font';
5
+ import { imeKey, editEnd } from '@weasel-js/headless';
5
6
  import { isSolidPaint } from '@weasel-js/paint';
6
7
 
7
8
  // src/useTextEdit.ts
@@ -80,13 +81,10 @@ function domPositionToCharOffset(parent, node, offset) {
80
81
  return total;
81
82
  }
82
83
 
83
- // src/domRuns.ts
84
- function solidColor(p) {
85
- if (!p) return null;
86
- if (isSolidPaint(p)) return p.color;
87
- return null;
88
- }
84
+ // src/runStyle.ts
89
85
  var FILL_ATTR = "data-fill";
86
+ var STROKE_ATTR = "data-stroke";
87
+ var ROTATE_ATTR = "data-rotate";
90
88
  var TRANSFORMS = /* @__PURE__ */ new Set(["none", "uppercase", "lowercase", "capitalize"]);
91
89
  var EMPTY_STYLE = {
92
90
  bold: false,
@@ -111,6 +109,16 @@ function cssFontVariant(el) {
111
109
  const v = el.style.fontVariant || el.style.getPropertyValue("font-variant-caps");
112
110
  return v === "small-caps" || v === "normal" ? v : void 0;
113
111
  }
112
+ function jsonAttr(el, name) {
113
+ const raw = el.getAttribute(name);
114
+ if (raw == null) return void 0;
115
+ try {
116
+ JSON.parse(raw);
117
+ return raw;
118
+ } catch {
119
+ return void 0;
120
+ }
121
+ }
114
122
  function styleStateFromElement(el, parent) {
115
123
  if (isSmallCapsPiece(el)) return parent;
116
124
  const next = { ...parent };
@@ -164,10 +172,15 @@ function styleStateFromElement(el, parent) {
164
172
  if (TRANSFORMS.has(tt)) next.textTransform = tt;
165
173
  const fv = cssFontVariant(el);
166
174
  if (fv) next.fontVariantCaps = fv;
175
+ if (el.hasAttribute("lang")) next.lang = el.lang || void 0;
167
176
  const family = el.getAttribute("data-font-family") ?? el.style.fontFamily;
168
177
  if (family) next.fontFamily = family;
169
- const fillJson = el.getAttribute(FILL_ATTR);
170
- if (fillJson != null) {
178
+ const strokeJson = jsonAttr(el, STROKE_ATTR);
179
+ if (strokeJson !== void 0) next.strokeJson = strokeJson;
180
+ const rotate = parseFloat(el.getAttribute(ROTATE_ATTR) ?? "");
181
+ if (Number.isFinite(rotate)) next.rotate = rotate;
182
+ const fillJson = jsonAttr(el, FILL_ATTR);
183
+ if (fillJson !== void 0) {
171
184
  next.fillJson = fillJson;
172
185
  next.color = void 0;
173
186
  } else if (el.style.color) {
@@ -185,7 +198,7 @@ function styleStateFromElement(el, parent) {
185
198
  return next;
186
199
  }
187
200
  function styleEquals(a, b) {
188
- return a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strikethrough === b.strikethrough && a.overline === b.overline && a.fontWeight === b.fontWeight && a.fontSize === b.fontSize && a.fontFamily === b.fontFamily && a.color === b.color && a.fillJson === b.fillJson && a.letterSpacing === b.letterSpacing && a.script === b.script && a.baselineShift === b.baselineShift && a.fontScale === b.fontScale && a.textTransform === b.textTransform && a.fontVariantCaps === b.fontVariantCaps;
201
+ return a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strikethrough === b.strikethrough && a.overline === b.overline && a.fontWeight === b.fontWeight && a.fontSize === b.fontSize && a.fontFamily === b.fontFamily && a.color === b.color && a.fillJson === b.fillJson && a.strokeJson === b.strokeJson && a.rotate === b.rotate && a.letterSpacing === b.letterSpacing && a.script === b.script && a.baselineShift === b.baselineShift && a.fontScale === b.fontScale && a.textTransform === b.textTransform && a.fontVariantCaps === b.fontVariantCaps && a.lang === b.lang;
189
202
  }
190
203
  function toRun(text, style) {
191
204
  const run = { text };
@@ -196,6 +209,8 @@ function toRun(text, style) {
196
209
  if (style.fontFamily != null) run.fontFamily = style.fontFamily;
197
210
  if (style.fillJson !== void 0) run.fill = JSON.parse(style.fillJson);
198
211
  else if (style.color != null) run.fill = { paint: { kind: "solid", color: style.color } };
212
+ if (style.strokeJson !== void 0) run.stroke = JSON.parse(style.strokeJson);
213
+ if (style.rotate != null) run.rotate = style.rotate;
199
214
  if (style.letterSpacing != null) run.letterSpacing = style.letterSpacing;
200
215
  if (style.underline) run.underline = true;
201
216
  if (style.strikethrough) run.strikethrough = true;
@@ -205,8 +220,16 @@ function toRun(text, style) {
205
220
  if (style.fontScale != null) run.fontScale = style.fontScale;
206
221
  if (style.textTransform != null) run.textTransform = style.textTransform;
207
222
  if (style.fontVariantCaps != null) run.fontVariantCaps = style.fontVariantCaps;
223
+ if (style.lang) run.lang = style.lang;
208
224
  return run;
209
225
  }
226
+
227
+ // src/domRuns.ts
228
+ function solidColor(p) {
229
+ if (!p) return null;
230
+ if (isSolidPaint(p)) return p.color;
231
+ return null;
232
+ }
210
233
  var BREAK_ATTR = "data-break";
211
234
  function restoreBreak(el) {
212
235
  const text = el.textContent ?? "";
@@ -271,9 +294,9 @@ function domToRuns(parent) {
271
294
  return runs;
272
295
  }
273
296
  var SMALL_CAPS_SCALE_PROPERTY = "--weasel-small-caps";
274
- function smallCapsPieces(text, transform) {
275
- const [shown] = transformRunTexts([text], [transform]);
276
- const caps = smallCapsText(shown.text, shown.srcMap);
297
+ function smallCapsPieces(text, transform, lang) {
298
+ const [shown] = transformRunTexts([text], [transform], [lang]);
299
+ const caps = smallCapsText(shown.text, shown.srcMap, lang);
277
300
  const small = new Array(text.length).fill(false);
278
301
  caps.small?.forEach((s, i) => {
279
302
  if (s) small[caps.srcMap ? caps.srcMap.starts[i] : i] = true;
@@ -288,9 +311,9 @@ function smallCapsPieces(text, transform) {
288
311
  }
289
312
  return out;
290
313
  }
291
- function writeSmallCaps(span, text, transform) {
314
+ function writeSmallCaps(span, text, transform, lang) {
292
315
  span.replaceChildren();
293
- for (const p of smallCapsPieces(text, transform)) {
316
+ for (const p of smallCapsPieces(text, transform, lang)) {
294
317
  if (!p.small) {
295
318
  appendOverlayText(span, p.text);
296
319
  continue;
@@ -315,7 +338,7 @@ function runsToDom(runs, parent, base = DEFAULT_TEXT_STYLE) {
315
338
  run.italic ? "italic" : base.fontStyle
316
339
  );
317
340
  span.style.setProperty(SMALL_CAPS_SCALE_PROPERTY, String(scale));
318
- writeSmallCaps(span, run.text, run.textTransform ?? base.textTransform);
341
+ writeSmallCaps(span, run.text, run.textTransform ?? base.textTransform, run.lang ?? base.lang);
319
342
  } else {
320
343
  appendOverlayText(span, run.text);
321
344
  }
@@ -338,6 +361,9 @@ function runsToDom(runs, parent, base = DEFAULT_TEXT_STYLE) {
338
361
  if (color != null) span.style.color = color;
339
362
  else if (run.fill !== void 0) span.setAttribute(FILL_ATTR, JSON.stringify(run.fill));
340
363
  if (run.fill === null) span.style.color = "#000";
364
+ if (run.stroke !== void 0) span.setAttribute(STROKE_ATTR, JSON.stringify(run.stroke));
365
+ if (run.rotate != null) span.setAttribute(ROTATE_ATTR, String(run.rotate));
366
+ if (run.lang) span.lang = run.lang;
341
367
  const decorations = [];
342
368
  if (run.underline) decorations.push("underline");
343
369
  if (run.strikethrough) decorations.push("line-through");
@@ -360,8 +386,8 @@ function sourceText(el) {
360
386
  }
361
387
  return out;
362
388
  }
363
- function piecesMatch(span, transform) {
364
- const want = smallCapsPieces(sourceText(span), transform);
389
+ function piecesMatch(span, transform, lang) {
390
+ const want = smallCapsPieces(sourceText(span), transform, lang);
365
391
  const have = [];
366
392
  for (const n of span.childNodes) {
367
393
  let small;
@@ -385,14 +411,15 @@ function piecesMatch(span, transform) {
385
411
  }
386
412
  function normalizeSmallCaps(parent) {
387
413
  let changed = false;
388
- const visit = (el, variant, transform) => {
414
+ const visit = (el, variant, transform, inherited) => {
389
415
  const v = cssFontVariant(el) ?? variant;
390
416
  const tt = el.style.textTransform;
391
417
  const t = TRANSFORMS.has(tt) ? tt : transform;
418
+ const lang = el.hasAttribute("lang") ? el.lang || void 0 : inherited;
392
419
  if (el.hasAttribute("data-run")) {
393
420
  if (v === "small-caps") {
394
- if (!piecesMatch(el, t)) {
395
- writeSmallCaps(el, sourceText(el), t);
421
+ if (!piecesMatch(el, t, lang)) {
422
+ writeSmallCaps(el, sourceText(el), t, lang);
396
423
  changed = true;
397
424
  }
398
425
  } else if (el.querySelector("[data-small-caps]")) {
@@ -403,9 +430,9 @@ function normalizeSmallCaps(parent) {
403
430
  }
404
431
  return;
405
432
  }
406
- for (const child of el.children) if (child instanceof HTMLElement) visit(child, v, t);
433
+ for (const child of el.children) if (child instanceof HTMLElement) visit(child, v, t, lang);
407
434
  };
408
- visit(parent, "normal", "none");
435
+ visit(parent, "normal", "none", void 0);
409
436
  return changed;
410
437
  }
411
438
  function applyOverlayDirection(el, style) {
@@ -486,6 +513,8 @@ function applyOverlayStyle(el, style) {
486
513
  el.style.textRendering = isCanvasFont(style.fontFamily) ? "" : "geometricPrecision";
487
514
  el.style.lineHeight = String(style.lineHeight);
488
515
  applyOverlayDirection(el, style);
516
+ if (style.lang) el.lang = style.lang;
517
+ else el.removeAttribute("lang");
489
518
  const decorations = [];
490
519
  if (style.underline) decorations.push("underline");
491
520
  if (style.strikethrough) decorations.push("line-through");
@@ -1093,15 +1122,11 @@ function useTextEdit(opts) {
1093
1122
  sel?.addRange(range);
1094
1123
  syncSelection();
1095
1124
  const onKeyDown = (e) => {
1096
- if (e.isComposing || e.keyCode === 229) return;
1097
- if (e.key === "Enter" && !e.shiftKey) {
1098
- e.preventDefault();
1099
- commit();
1100
- return;
1101
- }
1102
- if (e.key === "Escape") {
1125
+ if (imeKey(e)) return;
1126
+ const ends = editEnd({ key: e.key, shift: e.shiftKey }, { escape: optsRef.current.escape, multiline: true });
1127
+ if (ends) {
1103
1128
  e.preventDefault();
1104
- if (optsRef.current.escape === "commit") commit();
1129
+ if (ends === "commit") commit();
1105
1130
  else cancelEdit();
1106
1131
  return;
1107
1132
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/domOffsets.ts","../src/domRuns.ts","../src/overlayDirection.ts","../src/overlayDraft.ts","../src/overlayFrame.ts","../src/overlayStyle.ts","../src/overlaySeed.ts","../src/overlaySelection.ts","../src/pasteRuns.ts","../src/runSplice.ts","../src/overlayTyping.ts","../src/styleShortcuts.ts","../src/editSession.ts","../src/textEditTypes.ts","../src/useTextEdit.ts"],"names":["isSolidPaint","cssFontFamily","numericWeight","smallCapsScaleFor","isHardLineBreak","runsToPlainText","supersededKey","useRef","useState","useCallback","opts","applyStyleToRange","nodeStyle"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Character offsets in the edit overlay's DOM, counted the way `domToRuns`\n * reads its text: every text node's characters, plus one newline for each\n * break element a browser or a paste can leave behind.\n */\n\n/** One stretch of the overlay's text, in document order. */\nexport type OverlayPiece =\n | { text: Text }\n /** A newline with no text node of its own: a `<br>`, or the boundary a block opens. */\n | { br: Element }\n | { block: Element };\n\n/** Elements whose boundary reads as a newline. */\nexport const BLOCK_TAGS: ReadonlySet<string> = new Set(['DIV', 'P']);\n\n/**\n * `parent`'s text as pieces. A block (`<div>`, `<p>`) reads as a newline\n * before its contents unless it opens the text, which is how a browser renders\n * the boundary. Both offset walkers below read through here, and `domToRuns`\n * applies the same rule from `BLOCK_TAGS` in its own styled walk.\n */\nexport function overlayPieces(parent: Element): OverlayPiece[] {\n const out: OverlayPiece[] = [];\n const visit = (node: Node): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n if ((node as Text).data.length > 0) out.push({ text: node as Text });\n return;\n }\n if (!(node instanceof Element)) return;\n if (node.tagName === 'BR') { out.push({ br: node }); return; }\n if (BLOCK_TAGS.has(node.tagName) && out.length > 0) out.push({ block: node });\n for (const child of node.childNodes) visit(child);\n };\n for (const child of parent.childNodes) visit(child);\n return out;\n}\n\nconst indexIn = (el: Element): number => Array.prototype.indexOf.call(el.parentNode!.childNodes, el);\n\n/** The DOM position just past a break piece, where the next character goes. */\nfunction afterBreak(piece: { br: Element } | { block: Element }): { node: Node; offset: number } {\n return 'br' in piece\n ? { node: piece.br.parentNode!, offset: indexIn(piece.br) + 1 }\n : { node: piece.block, offset: 0 };\n}\n\n/**\n * The DOM position of plain-text character position `offset`: a text node\n * and an offset into it wherever one holds the position, otherwise an element\n * and a child index (just past a `<br>` that ends the text). Offsets beyond\n * the text clamp to its end. Returns `{ node: parent, offset: 0 }` for an\n * overlay with no text.\n */\nexport function charOffsetToDomPosition(\n parent: HTMLElement,\n offset: number,\n): { node: Node; offset: number } | null {\n let remaining = offset;\n let end: { node: Node; offset: number } = { node: parent, offset: 0 };\n /** Set while the position sits just past a break, with no text met since. */\n let pending: { node: Node; offset: number } | null = null;\n for (const piece of overlayPieces(parent)) {\n if ('text' in piece) {\n const len = piece.text.data.length;\n if (remaining <= len) return { node: piece.text, offset: remaining };\n remaining -= len;\n end = { node: piece.text, offset: len };\n pending = null;\n continue;\n }\n if (remaining === 0) {\n return pending ?? ('br' in piece\n ? { node: piece.br.parentNode!, offset: indexIn(piece.br) }\n : afterBreak(piece));\n }\n remaining -= 1;\n end = afterBreak(piece);\n pending = remaining === 0 ? end : null;\n }\n return end;\n}\n\n/**\n * Inverse of `charOffsetToDomPosition`: the characters that precede the DOM\n * position `(node, offset)`.\n *\n * When `node` is an element the DOM offset indexes *child nodes*, not\n * characters — `(overlay, 0)` is the start of the text and `(overlay,\n * childNodes.length)` its end. That shape is not exotic: `Range.\n * selectNodeContents`, which `useTextEdit` uses for its select-all caret,\n * produces exactly it. So an element position is resolved by counting the\n * pieces that end at or before the boundary point.\n */\nexport function domPositionToCharOffset(\n parent: HTMLElement,\n node: Node,\n offset: number,\n): number {\n const pieces = overlayPieces(parent);\n let total = 0;\n if (node.nodeType === Node.TEXT_NODE) {\n for (const piece of pieces) {\n if (!('text' in piece)) { total += 1; continue; }\n if (piece.text === node) return total + offset;\n total += piece.text.data.length;\n }\n return total;\n }\n const point = document.createRange();\n point.setStart(node, Math.max(0, Math.min(offset, node.childNodes.length)));\n point.collapse(true);\n for (const piece of pieces) {\n if ('text' in piece) {\n // A text node cannot contain the point, so it is wholly before or after.\n if (point.comparePoint(piece.text, 0) < 0) total += piece.text.data.length;\n } else {\n const past = afterBreak(piece);\n if (point.comparePoint(past.node, past.offset) <= 0) total += 1;\n }\n }\n return total;\n}\n","/**\n * DOM ↔ `StyledRun[]` serializers for the contenteditable overlay: a flat\n * sequence of `<span data-run>` elements, one per run. The browser breaks at\n * `\\n` and at no other UAX #14 hard break, so each of those is written as a\n * `<span data-break>` holding a `\\n` in its place — one character for one,\n * which keeps DOM offsets equal to source offsets.\n *\n * A small-caps run's lowercase letters sit in `<span data-small-caps>` pieces,\n * uppercased and sized at the scale the canvas draws them with, since a\n * browser's own synthesis uses a fixed factor of its own.\n */\n\nimport { isSolidPaint, type Fill, type Paint } from '@weasel-js/paint';\nimport {\n DEFAULT_TEXT_STYLE, isHardLineBreak, numericWeight, smallCapsScaleFor, smallCapsText, transformRunTexts,\n SMALL_CAPS_SCALE,\n type FontVariantCaps, type ResolvedTextStyle, type StyledRun, type TextTransform,\n} from '@weasel-js/text';\nimport { cssFontFamily } from '@weasel-js/font';\nimport { BLOCK_TAGS } from './domOffsets';\n\nexport { charOffsetToDomPosition, domPositionToCharOffset } from './domOffsets';\n\nfunction solidColor(p: Paint | null | undefined): string | null {\n if (!p) return null;\n if (isSolidPaint(p)) return p.color;\n return null;\n}\n\n/** Holds, as JSON, a run fill its span's CSS color cannot say: a gradient, a\n * pattern, or `null` for no fill. */\nconst FILL_ATTR = 'data-fill';\n\nexport interface StyleState {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n overline: boolean;\n fontWeight?: number;\n fontSize?: number;\n fontFamily?: string;\n color?: string;\n /** `FILL_ATTR`'s value, which wins over `color`. */\n fillJson?: string;\n letterSpacing?: number;\n script?: 'super' | 'sub';\n baselineShift?: number;\n fontScale?: number;\n textTransform?: TextTransform;\n fontVariantCaps?: FontVariantCaps;\n}\n\nconst TRANSFORMS: ReadonlySet<string> = new Set(['none', 'uppercase', 'lowercase', 'capitalize']);\n\nexport const EMPTY_STYLE: StyleState = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n overline: false,\n};\n\n/**\n * Parse a CSS `letter-spacing` value into world units. Pasted markup can carry\n * a unit other than `px`; it is read as its bare number and flagged, since\n * `0.1em` becomes `0.1` world units, off by a factor of the font size.\n */\nfunction parseLetterSpacing(raw: string): number | undefined {\n const n = parseFloat(raw);\n if (!Number.isFinite(n)) return undefined;\n const unit = /^-?[\\d.]+([a-z%]+)$/i.exec(raw.trim())?.[1]?.toLowerCase();\n if (unit && unit !== 'px') {\n console.warn(\n `weasel domRuns: letter-spacing \"${raw}\" uses unit \"${unit}\", which is not converted; treated as ${n} world units`,\n );\n }\n return n;\n}\n\n/** A small-caps piece is presentation `runsToDom` split a run into, not styling. */\nconst isSmallCapsPiece = (el: Element): boolean => el.hasAttribute('data-small-caps');\n\n/** The element's own `font-variant`, from the shorthand or the caps longhand\n * pasted markup may carry alone. */\nfunction cssFontVariant(el: HTMLElement): FontVariantCaps | undefined {\n const v = el.style.fontVariant || el.style.getPropertyValue('font-variant-caps');\n return v === 'small-caps' || v === 'normal' ? v : undefined;\n}\n\nexport function styleStateFromElement(el: Element, parent: StyleState): StyleState {\n if (isSmallCapsPiece(el)) return parent;\n const next: StyleState = { ...parent };\n const tag = el.tagName;\n if (tag === 'B' || tag === 'STRONG') {\n next.bold = true;\n next.fontWeight = undefined;\n }\n if (tag === 'I' || tag === 'EM') next.italic = true;\n // `runsToDom` never emits these, but a browser contenteditable can: Cmd+U\n // runs the native `underline` command, which produces `<u>` in Chrome.\n if (tag === 'U') next.underline = true;\n if (tag === 'S' || tag === 'STRIKE' || tag === 'DEL') next.strikethrough = true;\n if (tag === 'SUP') next.script = 'super';\n if (tag === 'SUB') next.script = 'sub';\n if (el instanceof HTMLElement) {\n // 700 and 400 are the bold flag on and off, which is what pasted markup\n // means by them. A run's own weight is written with an attribute beside\n // the CSS, so a stored 400 or 700 comes back as the weight it was.\n const fw = el.style.fontWeight;\n const ownWeight = Number(el.getAttribute('data-font-weight') ?? fw);\n if (el.hasAttribute('data-font-weight') || !['', '700', 'bold', '400', 'normal'].includes(fw)) {\n if (Number.isFinite(ownWeight) && ownWeight > 0) {\n next.fontWeight = ownWeight;\n next.bold = false;\n }\n } else if (fw !== '') {\n next.bold = fw === '700' || fw === 'bold';\n next.fontWeight = undefined;\n }\n const fs = el.style.fontStyle;\n if (fs === 'italic') next.italic = true;\n if (fs === 'normal') next.italic = false;\n // `text-decoration` does not inherit, it *propagates*, and a descendant\n // cannot cancel what an ancestor drew — so OR the flags in rather than\n // overwriting, and an explicit `none` cancels nothing.\n //\n // A declaration block carrying only the longhand serializes the shorthand\n // as `''`, so fall back to `text-decoration-line`.\n const td = el.style.textDecoration || el.style.textDecorationLine;\n if (td && !td.includes('none')) {\n next.underline ||= td.includes('underline');\n next.strikethrough ||= td.includes('line-through');\n next.overline ||= td.includes('overline');\n }\n // A percentage is `fontScale`; any other unit is an absolute size.\n if (el.style.fontSize) {\n const size = parseFloat(el.style.fontSize);\n if (Number.isFinite(size)) {\n if (el.style.fontSize.trim().endsWith('%')) next.fontScale = size / 100;\n else next.fontSize = size;\n }\n }\n const va = el.style.verticalAlign;\n if (va === 'super' || va === 'sub') next.script = va === 'super' ? 'super' : 'sub';\n if (va === 'baseline') next.script = undefined;\n const rawShift = el.getAttribute('data-baseline-shift');\n if (rawShift != null) {\n const shift = parseFloat(rawShift);\n if (Number.isFinite(shift)) next.baselineShift = shift;\n }\n const tt = el.style.textTransform;\n if (TRANSFORMS.has(tt)) next.textTransform = tt as TextTransform;\n const fv = cssFontVariant(el);\n if (fv) next.fontVariantCaps = fv;\n // The attribute holds the run's family; the CSS holds the face it maps to.\n const family = el.getAttribute('data-font-family') ?? el.style.fontFamily;\n if (family) next.fontFamily = family;\n const fillJson = el.getAttribute(FILL_ATTR);\n if (fillJson != null) {\n next.fillJson = fillJson;\n next.color = undefined;\n } else if (el.style.color) {\n next.color = el.style.color;\n next.fillJson = undefined;\n }\n const ls = el.style.letterSpacing;\n if (ls === 'normal') {\n next.letterSpacing = undefined;\n } else if (ls) {\n const px = parseLetterSpacing(ls);\n if (px != null) next.letterSpacing = px;\n }\n }\n return next;\n}\n\nfunction styleEquals(a: StyleState, b: StyleState): boolean {\n return (\n a.bold === b.bold &&\n a.italic === b.italic &&\n a.underline === b.underline &&\n a.strikethrough === b.strikethrough &&\n a.overline === b.overline &&\n a.fontWeight === b.fontWeight &&\n a.fontSize === b.fontSize &&\n a.fontFamily === b.fontFamily &&\n a.color === b.color &&\n a.fillJson === b.fillJson &&\n a.letterSpacing === b.letterSpacing &&\n a.script === b.script &&\n a.baselineShift === b.baselineShift &&\n a.fontScale === b.fontScale &&\n a.textTransform === b.textTransform &&\n a.fontVariantCaps === b.fontVariantCaps\n );\n}\n\nexport function toRun(text: string, style: StyleState): StyledRun {\n const run: StyledRun = { text };\n if (style.bold) run.bold = true;\n if (style.italic) run.italic = true;\n if (style.fontWeight != null) run.fontWeight = style.fontWeight;\n if (style.fontSize != null) run.fontSize = style.fontSize;\n if (style.fontFamily != null) run.fontFamily = style.fontFamily;\n if (style.fillJson !== undefined) run.fill = JSON.parse(style.fillJson) as Fill | null;\n else if (style.color != null) run.fill = { paint: { kind: 'solid', color: style.color } };\n // `letterSpacing: 0` is a meaningful override (it cancels node-level\n // tracking for this run), so test for presence, not truthiness.\n if (style.letterSpacing != null) run.letterSpacing = style.letterSpacing;\n // Run-level flags are additive over the node style — a run cannot un-set\n // one — so an undecorated run gets an absent key, never `false`.\n if (style.underline) run.underline = true;\n if (style.strikethrough) run.strikethrough = true;\n if (style.overline) run.overline = true;\n if (style.script != null) run.script = style.script;\n // Both are meaningful at values that test falsy — a 0 shift cancels an\n // inherited script's rise — so test for presence, as `letterSpacing` does.\n if (style.baselineShift != null) run.baselineShift = style.baselineShift;\n if (style.fontScale != null) run.fontScale = style.fontScale;\n if (style.textTransform != null) run.textTransform = style.textTransform;\n if (style.fontVariantCaps != null) run.fontVariantCaps = style.fontVariantCaps;\n return run;\n}\n\nconst BREAK_ATTR = 'data-break';\n\n/** A break stand-in's source text: its hard break, and anything typed into it after. */\nfunction restoreBreak(el: Element): string {\n const text = el.textContent ?? '';\n const code = parseInt(el.getAttribute(BREAK_ATTR) ?? '', 16);\n return text.startsWith('\\n') && Number.isFinite(code) ? String.fromCharCode(code) + text.slice(1) : text;\n}\n\n/**\n * Append `text` to `parent` as the overlay sets it: a hard break the browser\n * would not break at becomes a `<span data-break>` holding a `\\n`, carrying\n * the original's code as hex. A CR that opens a CRLF is left as it is — the\n * LF breaks, and the CR draws nothing.\n */\nexport function appendOverlayText(parent: Node, text: string): void {\n let from = 0;\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i);\n if (c === 10 || !isHardLineBreak(c) || (c === 13 && text.charCodeAt(i + 1) === 10)) continue;\n if (i > from) parent.appendChild(document.createTextNode(text.slice(from, i)));\n const span = document.createElement('span');\n span.setAttribute(BREAK_ATTR, c.toString(16));\n span.textContent = '\\n';\n parent.appendChild(span);\n from = i + 1;\n }\n if (from < text.length) parent.appendChild(document.createTextNode(text.slice(from)));\n}\n\n/** Walk an overlay tree and emit a coalesced `StyledRun[]`. */\nexport function domToRuns(parent: HTMLElement): StyledRun[] {\n const fragments: Array<{ text: string; style: StyleState }> = [];\n\n function visit(node: Node, style: StyleState): void {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = (node as Text).data;\n if (text.length > 0) fragments.push({ text, style });\n return;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as Element;\n if (el.tagName === 'BR') {\n fragments.push({ text: '\\n', style });\n return;\n }\n if (el.hasAttribute(BREAK_ATTR)) {\n const restored = restoreBreak(el);\n if (restored.length > 0) fragments.push({ text: restored, style });\n return;\n }\n if (BLOCK_TAGS.has(el.tagName) && fragments.length > 0) {\n fragments.push({ text: '\\n', style });\n }\n const nextStyle = styleStateFromElement(el, style);\n for (const child of Array.from(el.childNodes)) {\n visit(child, nextStyle);\n }\n }\n\n for (const child of Array.from(parent.childNodes)) {\n visit(child, EMPTY_STYLE);\n }\n\n const runs: StyledRun[] = [];\n let i = 0;\n while (i < fragments.length) {\n let j = i + 1;\n while (j < fragments.length && styleEquals(fragments[i].style, fragments[j].style)) {\n j++;\n }\n const merged = fragments.slice(i, j).map((f) => f.text).join('');\n runs.push(toRun(merged, fragments[i].style));\n i = j;\n }\n return runs;\n}\n\n/** What a run inherits from its node, for the overlay's small caps: which\n * runs have it, and the face and transform that decide their pieces. */\nexport type OverlayRunBase = Pick<\n ResolvedTextStyle, 'fontFamily' | 'fontWeight' | 'fontStyle' | 'textTransform' | 'fontVariantCaps'\n>;\n\n/** The custom property carrying a small-caps run's scale down to its pieces. */\nexport const SMALL_CAPS_SCALE_PROPERTY = '--weasel-small-caps';\n\n/** A run's source text cut where small caps changes size, per `smallCapsText`\n * over the text as `transform` draws it. */\nfunction smallCapsPieces(text: string, transform: TextTransform): Array<{ text: string; small: boolean }> {\n const [shown] = transformRunTexts([text], [transform]);\n const caps = smallCapsText(shown.text, shown.srcMap);\n const small = new Array<boolean>(text.length).fill(false);\n caps.small?.forEach((s, i) => {\n if (s) small[caps.srcMap ? caps.srcMap.starts[i] : i] = true;\n });\n const out: Array<{ text: string; small: boolean }> = [];\n let at = 0;\n for (const ch of text) {\n const last = out[out.length - 1];\n if (last && last.small === small[at]) last.text += ch;\n else out.push({ text: ch, small: small[at] });\n at += ch.length;\n }\n return out;\n}\n\n/** Replace `span`'s children with `text`, its small-caps letters in pieces. */\nfunction writeSmallCaps(span: HTMLElement, text: string, transform: TextTransform): void {\n span.replaceChildren();\n for (const p of smallCapsPieces(text, transform)) {\n if (!p.small) { appendOverlayText(span, p.text); continue; }\n const piece = document.createElement('span');\n piece.setAttribute('data-small-caps', '');\n piece.style.fontSize = `calc(var(${SMALL_CAPS_SCALE_PROPERTY}, ${SMALL_CAPS_SCALE}) * 1em)`;\n piece.style.textTransform = 'uppercase';\n piece.textContent = p.text;\n span.appendChild(piece);\n }\n}\n\n/**\n * Replace `parent`'s children with one `<span data-run>` per run. `base` is\n * the node's style, which a run inheriting small caps is split by.\n */\nexport function runsToDom(\n runs: readonly StyledRun[],\n parent: HTMLElement,\n base: OverlayRunBase = DEFAULT_TEXT_STYLE,\n): void {\n parent.replaceChildren();\n for (const run of runs) {\n const span = document.createElement('span');\n span.setAttribute('data-run', '');\n if ((run.fontVariantCaps ?? base.fontVariantCaps) === 'small-caps') {\n const scale = smallCapsScaleFor(\n run.fontFamily ?? base.fontFamily,\n run.fontWeight ?? (run.bold ? 700 : numericWeight(base.fontWeight)),\n run.italic ? 'italic' : base.fontStyle,\n );\n span.style.setProperty(SMALL_CAPS_SCALE_PROPERTY, String(scale));\n writeSmallCaps(span, run.text, run.textTransform ?? base.textTransform);\n } else {\n appendOverlayText(span, run.text);\n }\n // CSS as well as the pieces: it is what pasted markup says, and it gives a\n // letter typed outside a piece a small cap until the next normalize.\n if (run.fontVariantCaps != null) span.style.fontVariant = run.fontVariantCaps;\n if (run.fontWeight != null) {\n span.style.fontWeight = String(run.fontWeight);\n span.setAttribute('data-font-weight', String(run.fontWeight));\n } else if (run.bold) span.style.fontWeight = '700';\n if (run.italic) span.style.fontStyle = 'italic';\n // An absolute size wins over a relative one, as it does in `resolveRuns`.\n if (run.fontSize != null) span.style.fontSize = `${run.fontSize}px`;\n else if (run.fontScale != null) span.style.fontSize = `${run.fontScale * 100}%`;\n if (run.fontFamily != null) {\n span.style.fontFamily = cssFontFamily(run.fontFamily, {\n weight: run.fontWeight ?? (run.bold ? 700 : undefined),\n style: run.italic ? 'italic' : undefined,\n });\n span.setAttribute('data-font-family', run.fontFamily);\n }\n const color = solidColor(run.fill?.paint);\n if (color != null) span.style.color = color;\n else if (run.fill !== undefined) span.setAttribute(FILL_ATTR, JSON.stringify(run.fill));\n // Black, as an unfilled node edits in: no CSS color leaves it legible.\n if (run.fill === null) span.style.color = '#000';\n // Decoration goes on the span as an inline style rather than `<u>`/`<s>`\n // wrappers: one representation for `domToRuns` to unwrap, and one element\n // per run so the caret-offset walkers stay flat.\n const decorations: string[] = [];\n if (run.underline) decorations.push('underline');\n if (run.strikethrough) decorations.push('line-through');\n if (run.overline) decorations.push('overline');\n if (decorations.length > 0) span.style.textDecoration = decorations.join(' ');\n if (run.script != null) span.style.verticalAlign = run.script;\n // No CSS spelling: `vertical-align` takes a length or a percentage of the\n // *line height*, and this is a fraction of the parent's font size.\n if (run.baselineShift != null) {\n span.setAttribute('data-baseline-shift', String(run.baselineShift));\n }\n // World units — the overlay's own node-level tracking is screen-scaled,\n // but a run override is stored as-is so the round-trip is lossless.\n if (run.letterSpacing != null) span.style.letterSpacing = `${run.letterSpacing}px`;\n // CSS draws the transform, so the span's text stays the source and the\n // caret-offset walkers below need no map.\n if (run.textTransform != null) span.style.textTransform = run.textTransform;\n parent.appendChild(span);\n }\n}\n\n/** `el`'s text as `domToRuns` reads it: each break stand-in restored. */\nfunction sourceText(el: Element): string {\n let out = '';\n for (const n of el.childNodes) {\n if (n.nodeType === Node.TEXT_NODE) out += (n as Text).data;\n else if (n instanceof Element) out += n.hasAttribute(BREAK_ATTR) ? restoreBreak(n) : sourceText(n);\n }\n return out;\n}\n\n/** Whether `span`'s children are the pieces `writeSmallCaps` would write. */\nfunction piecesMatch(span: HTMLElement, transform: TextTransform): boolean {\n const want = smallCapsPieces(sourceText(span), transform);\n const have: Array<{ text: string; small: boolean }> = [];\n for (const n of span.childNodes) {\n let small: boolean;\n let text: string;\n if (n.nodeType === Node.TEXT_NODE) { small = false; text = (n as Text).data; }\n else if (n instanceof HTMLElement && n.hasAttribute(BREAK_ATTR)) { small = false; text = restoreBreak(n); }\n else if (n instanceof HTMLElement && isSmallCapsPiece(n) && n.children.length === 0) { small = true; text = n.textContent ?? ''; }\n else return false;\n if (text.length === 0) continue;\n const last = have[have.length - 1];\n if (last && last.small === small) last.text += text;\n else have.push({ text, small });\n }\n return want.length === have.length\n && want.every((p, i) => p.text === have[i].text && p.small === have[i].small);\n}\n\n/**\n * Put every run span's small-caps pieces back where its text now needs them.\n * Returns whether anything was rewritten, which moves the DOM selection: the\n * caller restores it by character offset.\n */\nexport function normalizeSmallCaps(parent: HTMLElement): boolean {\n let changed = false;\n const visit = (el: HTMLElement, variant: FontVariantCaps, transform: TextTransform): void => {\n const v = cssFontVariant(el) ?? variant;\n const tt = el.style.textTransform;\n const t = TRANSFORMS.has(tt) ? (tt as TextTransform) : transform;\n if (el.hasAttribute('data-run')) {\n if (v === 'small-caps') {\n if (!piecesMatch(el, t)) { writeSmallCaps(el, sourceText(el), t); changed = true; }\n } else if (el.querySelector('[data-small-caps]')) {\n const text = sourceText(el);\n el.replaceChildren();\n appendOverlayText(el, text);\n changed = true;\n }\n return;\n }\n for (const child of el.children) if (child instanceof HTMLElement) visit(child, v, t);\n };\n visit(parent, 'normal', 'none');\n return changed;\n}\n","/**\n * The edit overlay's reading direction, alignment, and tab stops, set so the\n * browser resolves them the way `layoutRuns` does for the canvas.\n */\nimport { paragraphDirection, resolveAlign, type ResolvedTextStyle } from '@weasel-js/text';\n\n/**\n * A stated direction goes on the overlay as CSS `direction`. `auto` becomes\n * `unicode-bidi: plaintext`, CSS's spelling of \"each paragraph reads the way\n * its first strong character does\", under which `start` and `end` follow each\n * paragraph too, so those are left for the browser to resolve.\n */\nexport function applyOverlayDirection(el: HTMLElement, style: ResolvedTextStyle): void {\n const auto = style.direction === 'auto';\n el.style.direction = auto ? '' : style.direction;\n el.style.setProperty('unicode-bidi', auto ? 'plaintext' : '');\n el.style.setProperty('tab-size', String(style.tabSize));\n const justify = style.align === 'justify';\n const edge = style.direction === 'auto'\n ? (justify ? 'start' : style.align)\n : resolveAlign(style.align, style.direction);\n el.style.textAlign = justify ? 'justify' : edge;\n // Pinned, so a justified paragraph's last line sits where the canvas puts it.\n el.style.setProperty('text-align-last', justify ? edge : '');\n}\n\n/** The absolute edge the overlay's text is set from, by its first paragraph. */\nexport function overlayAlignEdge(el: HTMLElement, style: ResolvedTextStyle): 'left' | 'center' | 'right' {\n return resolveAlign(style.align, paragraphDirection(el.textContent ?? '', style.direction));\n}\n","/**\n * What the overlay holds, as a node takes it — what a commit writes, and what\n * each keystroke or restyle reports as a draft — and handing it to the host:\n * a draft when it changed, a commit through the host's options.\n */\nimport { runsCarryStyling, runsToPlainText, type StyledRun, type TextStyle } from '@weasel-js/text';\nimport type { CaretHolder } from './overlaySeed';\nimport type { TextEditCommit, TextEditDraft, UseTextEditOptions } from './textEditTypes';\n\n/**\n * `read` — the overlay's runs as `domToRuns` gives them — less its caret\n * holder, as text, with the runs when they are in play: the node had some, or\n * the edit produced styling. A plain-text edit of a plain-text node is text alone.\n * `style`, the node style the edit rewrote, rides along where there is one.\n */\nexport function overlayDraft(\n read: StyledRun[],\n holder: CaretHolder | null,\n priorRuns: readonly StyledRun[] | undefined,\n style: TextStyle | null = null,\n): TextEditCommit {\n const runs = holder?.trim(read) ?? read;\n const inPlay = (priorRuns != null && priorRuns.length > 0) || runsCarryStyling(runs);\n // Read from the DOM, not `innerText`: a browser applies `text-transform`\n // to what that reports, and a break stand-in reads back as its `\\n`.\n const text = runsToPlainText(runs);\n return { text, ...(inPlay ? { runs } : {}), ...(style ? { style } : {}) };\n}\n\n/** Whether `draft` differs from the one `sent` holds as JSON, taking it as the one sent when it does. */\nexport function draftChanged(sent: { current: string }, draft: TextEditDraft): boolean {\n const json = JSON.stringify(draft);\n if (json === sent.current) return false;\n sent.current = json;\n return true;\n}\n\n/** Write a finished edit through `opts`: its `commit` where there is one, else each setter it has. */\nexport function writeEdit(\n opts: Pick<UseTextEditOptions, 'commit' | 'setRuns' | 'setStyle' | 'setText'>,\n id: string,\n edit: TextEditCommit,\n): void {\n if (opts.commit) return opts.commit(id, edit);\n if (edit.style) opts.setStyle?.(id, edit.style);\n opts.setText?.(id, edit.text);\n if (opts.setRuns && edit.runs) opts.setRuns(id, edit.runs);\n}\n","import { verticalAlignOffset } from '@weasel-js/text';\nimport type { TextEditScreenPose } from './textEditTypes';\n\n/**\n * The overlay's CSS `transform`, for an origin of `0 0`: the pose's `zoom`,\n * its `frame` about the box center, and the pull back by `anchor` of the\n * overlay's own width that aligns an unwrapped line. `left` and `top` are\n * where the overlay's origin sits before any of it, in container pixels.\n */\nexport function overlayTransform(pose: TextEditScreenPose, left: number, top: number, anchor: number): string {\n const zoom = pose.zoom ?? 1;\n const parts: string[] = [];\n if (pose.frame) {\n const [a, b, c, d] = pose.frame;\n // The origin's offset from the box center, which the frame turns with\n // everything else.\n const dx = left - (pose.x + (pose.width * zoom) / 2);\n const dy = top - (pose.y + (pose.height * zoom) / 2);\n const m = [a * zoom, b * zoom, c * zoom, d * zoom, (a - 1) * dx + c * dy, b * dx + (d - 1) * dy];\n parts.push(`matrix(${m.join(', ')})`);\n } else if (zoom !== 1) {\n parts.push(`scale(${zoom})`);\n }\n if (anchor !== 0) parts.push(`translateX(${-anchor * 100}%)`);\n return parts.length > 0 ? parts.join(' ') : 'none';\n}\n\n/**\n * The overlay's `clip-path`: the pose box grown by `clip`, in the overlay's\n * own pre-transform pixels, so its transform carries the cut with the text.\n * The box's corner sits at the overlay's origin less the pull back by\n * `anchor` of its width, and pose units are its pixels.\n */\nexport function overlayClipPath(\n el: HTMLElement,\n pose: TextEditScreenPose,\n left: number,\n top: number,\n anchor: number,\n clip: NonNullable<TextEditScreenPose['clip']>,\n): string {\n const zoom = pose.zoom ?? 1;\n const x0 = (pose.x - left) / zoom + anchor * el.offsetWidth - clip.left;\n const y0 = (pose.y - top) / zoom - clip.top;\n const x1 = x0 + clip.left + pose.width + clip.right;\n const y1 = y0 + clip.top + pose.height + clip.bottom;\n return `polygon(${x0}px ${y0}px, ${x1}px ${y0}px, ${x1}px ${y1}px, ${x0}px ${y1}px)`;\n}\n\n/**\n * The overlay's `top`, in container pixels, for content `contentHeight` tall\n * (pre-scale, like the rest of `pose`): the pose's top, shifted by the same\n * `verticalAlign` slack the canvas applies, plus `drop` — how far below the\n * CSS line's baseline the canvas puts its own, from {@link baselineDrop}.\n * @internal\n */\nexport function overlayTop(pose: TextEditScreenPose, contentHeight: number, drop = 0): number {\n const slack = verticalAlignOffset(pose.verticalAlign, pose.height, contentHeight);\n return pose.y + (slack + drop) * (pose.zoom ?? 1);\n}\n","import { isSolidPaint } from '@weasel-js/paint';\nimport { cssFontFamily, isCanvasFont } from '@weasel-js/font';\nimport { fontString, numericWeight, smallCapsScaleFor, type ResolvedTextStyle } from '@weasel-js/text';\nimport { SMALL_CAPS_SCALE_PROPERTY } from './domRuns';\nimport { applyOverlayDirection } from './overlayDirection';\n\n/** Dress the edit overlay in the node's resolved style, so it looks like the\n * canvas the moment editing starts. */\nexport function applyOverlayStyle(el: HTMLDivElement, style: ResolvedTextStyle): void {\n el.style.position = 'absolute';\n el.style.pointerEvents = 'auto';\n el.style.boxSizing = 'border-box';\n el.style.margin = '0';\n el.style.padding = '0';\n el.style.border = '0';\n el.style.outline = 'none';\n el.style.background = 'transparent';\n // Unfilled text still edits in black: the overlay has to be legible, and\n // there is no CSS spelling of \"no fill\" that leaves the glyphs visible.\n const paint = style.fill?.paint;\n el.style.color = isSolidPaint(paint) ? paint.color : '#000';\n el.style.caretColor = style.caretColor;\n // The canvas's face, not the browser's reading of the family name.\n const fontFamily = cssFontFamily(style.fontFamily, {\n weight: numericWeight(style.fontWeight), style: style.fontStyle,\n });\n el.style.font = fontString({ ...style, fontFamily });\n // Linux Chromium otherwise rounds every advance to a whole pixel at DPR 1, while\n // the canvas lays out a face's own fractional ones: 'Small Caps' at 24px ran 3px\n // long. A canvas font is measured by the browser's default rendering, so keeps it.\n el.style.textRendering = isCanvasFont(style.fontFamily) ? '' : 'geometricPrecision';\n el.style.lineHeight = String(style.lineHeight);\n applyOverlayDirection(el, style);\n const decorations: string[] = [];\n if (style.underline) decorations.push('underline');\n if (style.strikethrough) decorations.push('line-through');\n if (style.overline) decorations.push('overline');\n el.style.textDecoration = decorations.length > 0 ? decorations.join(' ') : 'none';\n el.style.textTransform = style.textTransform;\n // The CSS spelling for what a browser reads; the scale for the pieces\n // `runsToDom` splits inheriting runs into, so they match the canvas.\n el.style.fontVariant = style.fontVariantCaps;\n el.style.setProperty(\n SMALL_CAPS_SCALE_PROPERTY,\n style.fontVariantCaps === 'small-caps'\n ? String(smallCapsScaleFor(style.fontFamily, numericWeight(style.fontWeight), style.fontStyle))\n : '',\n );\n // Line breaks follow the node's declared `wrap`, as the canvas's do. Layout\n // breaks only between words, never inside one.\n el.style.whiteSpace = style.wrap ? 'pre-wrap' : 'pre';\n el.style.overflowWrap = 'normal';\n el.style.wordBreak = 'normal';\n}\n","/**\n * What the edit overlay holds when an edit opens, and the one character it can\n * come to hold that is not the node's text.\n *\n * A browser draws no empty last line for text that ends in a line break, so\n * when an edit leaves the caret on one it keeps a second newline there: the\n * caret holder, which reading the text back drops. Text seeded already ending\n * in a break is different. The canvas draws no last line for it either, and\n * Chromium takes the break that is there as the holder and adds none, so that\n * newline is the node's own and stays until an edit removes it.\n */\n\nimport { isHardLineBreak, runsToPlainText, type StyledRun } from '@weasel-js/text';\nimport { appendOverlayText, domToRuns, runsToDom, type OverlayRunBase } from './domRuns';\n\nconst endsInBreak = (text: string): boolean =>\n text.length > 0 && isHardLineBreak(text.charCodeAt(text.length - 1));\n\n/** Which trailing newline of an overlay's text, if any, is the browser's. */\nexport interface CaretHolder {\n /** Call after anything that edits the overlay's text. */\n edited(overlay: HTMLElement): void;\n /** `runs` as read from the overlay, without the holder. */\n trim(runs: StyledRun[]): StyledRun[];\n}\n\n/**\n * Fill `overlay` with a node's text: its runs when it has any, one run when\n * small caps needs its lowercase in pieces only a run span holds, and bare text\n * otherwise.\n */\nexport function seedOverlay(\n overlay: HTMLElement,\n text: string,\n runs: readonly StyledRun[] | undefined,\n base: OverlayRunBase,\n): CaretHolder {\n const styled = runs !== undefined && runs.length > 0;\n if (styled) runsToDom(runs, overlay, base);\n else if (base.fontVariantCaps === 'small-caps') runsToDom([{ text }], overlay, base);\n // Not `innerText`, which turns each newline into a `<br>` the caret\n // walkers cannot count and U+2028 into a space.\n else appendOverlayText(overlay, text);\n\n let ownBreak = endsInBreak(styled ? runsToPlainText(runs) : text);\n return {\n edited(el) {\n if (ownBreak && !endsInBreak(runsToPlainText(domToRuns(el)))) ownBreak = false;\n },\n trim: (read) => (ownBreak ? read : trimCaretHolder(read)),\n };\n}\n\n/** An empty run left behind is dropped: it would answer `runsCarryStyling` by existing. */\nfunction trimCaretHolder(runs: StyledRun[]): StyledRun[] {\n const last = runs[runs.length - 1];\n if (last === undefined || !last.text.endsWith('\\n')) return runs;\n const trimmed = { ...last, text: last.text.slice(0, -1) };\n const head = runs.slice(0, -1);\n return trimmed.text === '' ? head : [...head, trimmed];\n}\n","/** The DOM selection inside the edit overlay, as character offsets and back, and handing focus back to the overlay. */\n\nimport type { StyledRun } from '@weasel-js/text';\nimport { charOffsetToDomPosition, domPositionToCharOffset, runsToDom, type OverlayRunBase } from './domRuns';\nimport type { TextEditSelection } from './textEditTypes';\n\n/**\n * Character offsets of the current DOM selection within `overlay`, or `null`\n * when there is no selection or it lies outside the overlay.\n */\nexport function readSelectionOffsets(overlay: HTMLElement): TextEditSelection | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const range = sel.getRangeAt(0);\n if (!overlay.contains(range.startContainer) || !overlay.contains(range.endContainer)) {\n return null;\n }\n // `Range` boundary points are already in document order, so this is the\n // normalization for a backwards drag — anchor/focus are not consulted.\n const start = domPositionToCharOffset(overlay, range.startContainer, range.startOffset);\n const end = domPositionToCharOffset(overlay, range.endContainer, range.endOffset);\n return start <= end ? { start, end } : { start: end, end: start };\n}\n\n/** Put the DOM selection on the characters `[start, end)` of `overlay`. */\nexport function selectOffsets(overlay: HTMLElement, start: number, end: number): void {\n const a = charOffsetToDomPosition(overlay, start);\n const b = charOffsetToDomPosition(overlay, end);\n const sel = window.getSelection();\n if (!a || !b || !sel) return;\n const range = document.createRange();\n range.setStart(a.node, a.offset);\n range.setEnd(b.node, b.offset);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/**\n * Replace the overlay's contents with `runs` and put the selection back on\n * `[start, end)`, which rewriting the DOM destroys.\n *\n * The selection is **not** restored while focus sits in a text-entry control.\n * Browsers route editing commands by selection rather than by focus, so with\n * the range restored, the Enter that commits a number field also runs\n * `insertParagraph` over it — replacing the text that was just styled with a\n * line break. (Observed in Chrome.) Focus on a *button* still restores:\n * buttons turn keystrokes into clicks, not into editing commands.\n */\nexport function writeRunsPreservingSelection(\n overlay: HTMLElement,\n runs: readonly StyledRun[],\n start: number,\n end: number,\n base: OverlayRunBase,\n): void {\n const active = document.activeElement;\n const inTextEntry =\n active !== overlay &&\n !overlay.contains(active) &&\n (active instanceof HTMLInputElement ||\n active instanceof HTMLTextAreaElement ||\n (active instanceof HTMLElement && active.isContentEditable));\n runsToDom(runs, overlay, base);\n if (!inTextEntry) selectOffsets(overlay, start, end);\n}\n\n/**\n * Return focus to the overlay after a styling arrived from editor chrome: a\n * control that took focus to be clicked still holds it when the patch lands,\n * so the next keystroke would go to that button.\n *\n * Two things are left holding focus deliberately: a text entry in the chrome\n * (the user is still typing a font size) and anything inside an open dialog,\n * which is where a color picker's live `onChange` fires from.\n */\nexport function restoreOverlayFocus(overlay: HTMLElement, range: TextEditSelection): void {\n const active = document.activeElement;\n if (active === overlay || overlay.contains(active)) return;\n if (\n active instanceof HTMLInputElement\n || active instanceof HTMLTextAreaElement\n || (active instanceof HTMLElement && active.isContentEditable)\n || (active instanceof Element && active.closest('[role=\"dialog\"]') !== null)\n ) return;\n overlay.focus();\n selectOffsets(overlay, range.start, range.end);\n}\n\n/** Whether two published ranges are the same, either being none. */\nexport function sameSelection(a: TextEditSelection | null, b: TextEditSelection | null): boolean {\n if (a === null || b === null) return a === b;\n return a.start === b.start && a.end === b.end;\n}\n","/**\n * Clipboard contents as runs. Pasted markup never reaches the overlay's DOM:\n * it is parsed apart from the page and read here, so whatever an application\n * put on the clipboard arrives as text with line breaks, tabs, and emphasis.\n *\n * Emphasis is all that is kept of its styling: bold, italic, the three rules,\n * and super- and subscript. A browser writes every copied element's computed\n * face, size, and color into the markup, the source page's defaults among\n * them, so those cannot be told from styling someone chose, and the pasted\n * text takes them from where it lands.\n */\n\nimport type { StyledRun } from '@weasel-js/text';\nimport { EMPTY_STYLE, styleStateFromElement, toRun, type StyleState } from './domRuns';\n\n/** Elements whose contents are not text a reader sees. */\nconst UNSEEN: ReadonlySet<string> = new Set([\n 'HEAD', 'IFRAME', 'NOSCRIPT', 'OBJECT', 'SCRIPT', 'STYLE', 'TEMPLATE', 'TITLE',\n]);\n\n/** Elements that start and end on a line of their own. */\nconst BLOCKS: ReadonlySet<string> = new Set([\n 'ADDRESS', 'ARTICLE', 'ASIDE', 'BLOCKQUOTE', 'CAPTION', 'DD', 'DETAILS', 'DIV', 'DL', 'DT', 'FIELDSET',\n 'FIGCAPTION', 'FIGURE', 'FOOTER', 'FORM', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER', 'HR', 'LI', 'MAIN',\n 'NAV', 'OL', 'P', 'PRE', 'SECTION', 'SUMMARY', 'TABLE', 'TR', 'UL',\n]);\n\nconst CELLS: ReadonlySet<string> = new Set(['TD', 'TH']);\n\n/** Whether `el` keeps its white space, given whether its parent does. */\nfunction keepsSpace(el: HTMLElement, inherited: boolean): boolean {\n const collapse = el.style.getPropertyValue('white-space-collapse');\n const ws = collapse || el.style.getPropertyValue('white-space');\n if (ws === '') return el.tagName === 'PRE' || inherited;\n return /^(pre|pre-wrap|break-spaces|preserve)\\b/.test(ws);\n}\n\n/** The run fields a paste keeps. A weight of 600 or more reads as bold. */\nfunction emphasis(text: string, style: StyleState): StyledRun {\n const read = toRun(text, style);\n const run: StyledRun = { text };\n if (read.bold || (read.fontWeight ?? 0) >= 600) run.bold = true;\n for (const key of ['italic', 'underline', 'strikethrough', 'overline'] as const) if (read[key]) run[key] = true;\n if (read.script) run.script = read.script;\n return run;\n}\n\n/**\n * The text of `html` as runs. A block opens and closes a line, a table cell\n * follows the one before it after a tab, and white space collapses as a\n * browser collapses it unless the markup says to keep it.\n */\nexport function htmlToRuns(html: string): StyledRun[] {\n const body = new DOMParser().parseFromString(html, 'text/html').body;\n const runs: StyledRun[] = [];\n /** What has to precede the next text: a line break a block boundary asked for, a tab between cells. */\n let gap = { line: false, tab: false };\n /** Whether the current line has text on it, and whether that text ends in a collapsed space. */\n let onLine = false;\n let spaced = false;\n\n const write = (text: string, style: StyleState): void => {\n const lead = (gap.line && runs.length > 0 ? '\\n' : '') + (gap.tab ? '\\t' : '');\n runs.push(emphasis(lead + text, style));\n gap = { line: false, tab: false };\n onLine = true;\n spaced = false;\n };\n /** A collapsed space that turned out to end its line draws nothing. */\n const trimSpace = (): void => {\n const last = runs[runs.length - 1];\n if (spaced && last) last.text = last.text.slice(0, -1);\n spaced = false;\n };\n const boundary = (): void => {\n trimSpace();\n gap = { line: gap.line || onLine, tab: false };\n onLine = false;\n };\n\n const visit = (node: Node, style: StyleState, keep: boolean): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n const data = (node as Text).data.replace(/\\r\\n?/g, '\\n');\n if (keep) { if (data.length > 0) write(data, style); return; }\n data.split(/[ \\t\\n\\f]+/).forEach((word, i) => {\n // The space goes in with the text node that held it, as a browser draws it.\n if (i > 0 && onLine && !spaced) { write(' ', style); spaced = true; }\n if (word.length > 0) write(word, style);\n });\n return;\n }\n if (!(node instanceof HTMLElement) || UNSEEN.has(node.tagName)) return;\n if (node.tagName === 'BR') {\n // Chrome ends a copied fragment with one that stands for no text.\n if (node.classList.contains('Apple-interchange-newline')) return;\n trimSpace();\n write('\\n', style);\n onLine = false;\n return;\n }\n const block = BLOCKS.has(node.tagName);\n if (block) boundary();\n if (CELLS.has(node.tagName) && node.previousElementSibling !== null) { trimSpace(); gap.tab = true; }\n const next = styleStateFromElement(node, style);\n const keeps = keepsSpace(node, keep);\n for (const child of node.childNodes) visit(child, next, keeps);\n if (block) boundary();\n };\n visit(body, EMPTY_STYLE, false);\n trimSpace();\n\n // Neighbors alike in what was kept, which differed only in what was not.\n const kept = (run: StyledRun): string => JSON.stringify({ ...run, text: '' });\n const merged: StyledRun[] = [];\n for (const run of runs) {\n const last = merged[merged.length - 1];\n if (run.text.length === 0) continue;\n if (last && kept(last) === kept(run)) last.text += run.text;\n else merged.push(run);\n }\n return merged;\n}\n\n/**\n * What a paste or a drop carries, as runs: its markup where it has any that\n * holds text, otherwise its plain text.\n */\nexport function clipboardRuns(data: DataTransfer): StyledRun[] {\n const html = data.getData('text/html');\n const fromHtml = html ? htmlToRuns(html) : [];\n if (fromHtml.length > 0) return fromHtml;\n const plain = data.getData('text/plain').replace(/\\r\\n/g, '\\n');\n return plain.length > 0 ? [{ text: plain }] : [];\n}\n","/** Text going into runs at a character range, for typing under an armed style and for a paste. */\n\nimport { applyStyleToRange, type RunStylePatch, type StyledRun } from '@weasel-js/text';\n\n/**\n * `runs` with the characters `[start, end)` replaced by `insert`, splitting\n * whichever runs span the two ends. The result is normalized (empty runs\n * dropped, identical neighbors merged) by the same algebra every other write\n * goes through.\n */\nexport function replaceRunRange(\n runs: readonly StyledRun[],\n start: number,\n end: number,\n insert: readonly StyledRun[],\n): StyledRun[] {\n const out: StyledRun[] = [];\n let pos = 0;\n let placed = false;\n const place = (): void => {\n if (!placed) out.push(...insert.map((r) => ({ ...r })));\n placed = true;\n };\n for (const r of runs) {\n const from = pos;\n pos += r.text.length;\n if (from < start) out.push({ ...r, text: r.text.slice(0, start - from) });\n if (pos >= start) place();\n if (pos > end) out.push({ ...r, text: r.text.slice(Math.max(0, end - from)) });\n }\n place();\n // An empty patch over an empty range: this is the array-wide normalization\n // pass, not a styling.\n return applyStyleToRange(out, 0, 0, {});\n}\n\n/**\n * The styling a character typed at offset `at` joins: the run to its left's,\n * or the first run's at the very start of the text.\n */\nexport function runStyleAt(runs: readonly StyledRun[], at: number): RunStylePatch {\n let pos = 0;\n let found: StyledRun | undefined = runs[0];\n for (const r of runs) {\n if (r.text.length === 0) continue;\n if (pos >= at && pos > 0) break;\n found = r;\n pos += r.text.length;\n }\n if (!found) return {};\n const style: Partial<StyledRun> = { ...found };\n delete style.text;\n return style;\n}\n","/**\n * Text entering the edit overlay. The browser inserts a typed character\n * itself, which keeps the keystroke on its undo stack and lets input that\n * names its own range (a text replacement, the double-space period) land\n * there. The hook inserts by hand only where the character has to open a run\n * of its own: under an armed style, and at a caret between two run spans.\n *\n * A paste or a drop is never the browser's to insert: it would land as\n * whatever markup the clipboard held. It is read into runs and written\n * through them.\n */\n\nimport { runsToPlainText, supersededKey, type RunStylePatch, type StyledRun } from '@weasel-js/text';\nimport { domPositionToCharOffset, domToRuns, normalizeSmallCaps, type OverlayRunBase } from './domRuns';\nimport { readSelectionOffsets, selectOffsets, writeRunsPreservingSelection } from './overlaySelection';\nimport { clipboardRuns } from './pasteRuns';\nimport { replaceRunRange, runStyleAt } from './runSplice';\nimport type { TextEditSelection } from './textEditTypes';\n\n/**\n * Put the caret *between* two run spans when `offset` falls on the boundary\n * of one, rather than at the same offset inside the left span's text node.\n * A caret inside a span has the next character absorbed by that run —\n * otherwise the character after a superscript is superscript too. Leaves the\n * selection alone when the offset falls mid-run.\n */\nfunction placeCaretBetweenRuns(overlay: HTMLElement, runs: readonly StyledRun[], offset: number): void {\n let acc = 0;\n let index = -1;\n for (let i = 0; i < runs.length; i++) {\n acc += runs[i].text.length;\n if (acc === offset) { index = i; break; }\n if (acc > offset) return;\n }\n const span = index >= 0 ? overlay.children[index] : null;\n const sel = window.getSelection();\n if (!span || !sel) return;\n const range = document.createRange();\n range.setStartAfter(span);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/** Put small-caps letters back in the pieces their case belongs in after\n * an edit, keeping the caret. Never mid-composition: rewriting the DOM\n * under an IME ends the composition. */\nfunction resplitSmallCaps(overlay: HTMLElement, e?: Event): void {\n if (e instanceof InputEvent && e.isComposing) return;\n const at = readSelectionOffsets(overlay);\n if (normalizeSmallCaps(overlay) && at) selectOffsets(overlay, at.start, at.end);\n}\n\n/** Whether `ie` names a range of its own to replace, apart from a collapsed caret. */\nfunction namesItsRange(ie: InputEvent, caret: Range): boolean {\n const target = ie.getTargetRanges?.()[0];\n return target !== undefined && caret.collapsed && !target.collapsed;\n}\n\n/** The characters `ie` replaces: the range it names, else the selection. */\nfunction replacedOffsets(overlay: HTMLElement, ie: InputEvent, host: TypingHost): TextEditSelection | null {\n const target = ie.getTargetRanges?.()[0];\n if (target && overlay.contains(target.startContainer) && overlay.contains(target.endContainer)) {\n const a = domPositionToCharOffset(overlay, target.startContainer, target.startOffset);\n const b = domPositionToCharOffset(overlay, target.endContainer, target.endOffset);\n return { start: Math.min(a, b), end: Math.max(a, b) };\n }\n return readSelectionOffsets(overlay) ?? host.lastRange();\n}\n\n/**\n * `pasted` styled for where it lands: the run it joins and any armed style\n * underneath, its own emphasis on top.\n */\nfunction styledForRange(\n pasted: readonly StyledRun[], runs: readonly StyledRun[], at: TextEditSelection, pending: RunStylePatch,\n): StyledRun[] {\n // Over a selection, the first character replaced; at a caret, the one before it.\n const base: Record<string, unknown> = { ...runStyleAt(runs, at.start === at.end ? at.start : at.start + 1) };\n for (const [key, value] of Object.entries(pending)) {\n if (value === undefined || value === false) delete base[key];\n else base[key] = value;\n }\n return pasted.map((run) => {\n const styled: Record<string, unknown> = { ...base, ...run };\n const superseded = supersededKey(run);\n if (superseded !== undefined) delete styled[superseded];\n return styled as unknown as StyledRun;\n });\n}\n\nconst PASTES: ReadonlySet<string> = new Set(['insertFromPaste', 'insertFromDrop']);\n\n/** What the typing handlers read from, and report to, the edit that owns the overlay. */\nexport interface TypingHost {\n /** The style armed for the next character; no keys when none is. */\n pending: () => RunStylePatch;\n /** The node style run spans are split by. */\n base: () => OverlayRunBase;\n /** The last range published inside the overlay, for when the DOM selection has left it. */\n lastRange: () => TextEditSelection | null;\n /** The runs were rewritten with new text in them, any armed style spent, and the caret now sits at `caret`. */\n onWritten: (caret: number) => void;\n /** The overlay's text changed, by the browser's hand or this module's. */\n onEdited: () => void;\n}\n\n/** The overlay's `beforeinput` and `input` listeners. */\nexport function typingHandlers(overlay: HTMLElement, host: TypingHost): {\n onBeforeInput: (ie: InputEvent) => void;\n onInput: (e: Event) => void;\n} {\n const edited = (e?: Event): void => {\n resplitSmallCaps(overlay, e);\n host.onEdited();\n };\n\n const onPaste = (ie: InputEvent): void => {\n // An engine that hands the event no data inserts for itself.\n const at = ie.dataTransfer ? replacedOffsets(overlay, ie, host) : null;\n if (!ie.dataTransfer || !at) return;\n ie.preventDefault();\n const pasted = clipboardRuns(ie.dataTransfer);\n if (pasted.length === 0) return;\n const runs = domToRuns(overlay);\n const next = replaceRunRange(runs, at.start, at.end, styledForRange(pasted, runs, at, host.pending()));\n const after = at.start + runsToPlainText(pasted).length;\n writeRunsPreservingSelection(overlay, next, after, after, host.base());\n host.onWritten(after);\n host.onEdited();\n };\n\n const onBeforeInput = (ie: InputEvent): void => {\n if (PASTES.has(ie.inputType)) { onPaste(ie); return; }\n if (ie.inputType !== 'insertText' || !ie.data) return;\n const sel = window.getSelection();\n const caret = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n if (caret && namesItsRange(ie, caret)) return;\n\n const pending = host.pending();\n if (Object.keys(pending).length > 0) {\n // Rebuild from the runs rather than splicing a span into the DOM.\n // `insertNode` at a caret sitting inside a run span nests the new\n // span *within* it, and `domToRuns` reads styling down the ancestor\n // chain — so a pending style that has to shed the surrounding run's\n // flag would inherit it.\n const at = readSelectionOffsets(overlay) ?? host.lastRange();\n if (!at || at.start !== at.end) return;\n ie.preventDefault();\n const typed = { ...pending, text: ie.data } as StyledRun;\n const next = replaceRunRange(domToRuns(overlay), at.start, at.start, [typed]);\n const after = at.start + ie.data.length;\n writeRunsPreservingSelection(overlay, next, after, after, host.base());\n placeCaretBetweenRuns(overlay, next, after);\n host.onWritten(after);\n host.onEdited();\n return;\n }\n\n // A caret between two run spans, or in an overlay with no text yet. A\n // browser types into the span before it; a text node of its own keeps\n // the character out of that run, and the caret left inside the node\n // hands the characters after it back to the browser.\n if (!sel || !caret || !caret.collapsed || caret.startContainer.nodeType === Node.TEXT_NODE) return;\n if (!overlay.contains(caret.startContainer)) return;\n ie.preventDefault();\n const textNode = document.createTextNode(ie.data);\n caret.insertNode(textNode);\n sel.collapse(textNode, ie.data.length);\n edited();\n };\n\n return { onBeforeInput, onInput: edited };\n}\n","import type { StyleToggle } from './textEditTypes';\n\n/**\n * The shortcut each styling answers to. Strikethrough takes Cmd+Shift+X\n * (Docs' binding) and MUST require shift: bare Cmd+X is cut, and swallowing\n * it here would break cutting text mid-edit. Superscript takes Word's\n * Cmd+Shift+=; subscript takes Cmd+Shift+- rather than Word's Cmd+-, because\n * the unshifted pair is browser zoom, which a page cannot cancel.\n *\n * Matching is on the *unshifted* character: a US layout reports Cmd+Shift+=\n * as `'+'` and Cmd+Shift+- as `'_'`.\n *\n * Underline has to be intercepted, not merely supported. Left alone, the\n * browser runs its own `formatUnderline` and `domToRuns`' `<u>` flattening\n * makes that *look* like it worked while bypassing `patchForToggle`\n * entirely — no toggle-off, no pending style for a collapsed caret.\n */\nconst STYLE_SHORTCUTS: ReadonlyArray<{ key: string; shift: boolean; toggle: StyleToggle }> = [\n { key: 'b', shift: false, toggle: 'bold' },\n { key: 'i', shift: false, toggle: 'italic' },\n { key: 'u', shift: false, toggle: 'underline' },\n { key: 'x', shift: true, toggle: 'strikethrough' },\n { key: '=', shift: true, toggle: 'super' },\n { key: '-', shift: true, toggle: 'sub' },\n];\n\n/** The characters shift produces from the keys the table names. */\nconst UNSHIFT: Readonly<Record<string, string>> = { '+': '=', _: '-' };\n\n/** The styling `e` toggles, or null when it isn't a styling shortcut. */\nexport function toggleForKey(e: KeyboardEvent): StyleToggle | null {\n if (!e.metaKey && !e.ctrlKey) return null;\n const raw = e.key.toLowerCase();\n const key = UNSHIFT[raw] ?? raw;\n return STYLE_SHORTCUTS.find((s) => s.key === key && s.shift === e.shiftKey)?.toggle ?? null;\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type { UseTextEditOptions } from './textEditTypes';\n\n/**\n * The id of the node being edited, and the setter that reports each change:\n * `onEnd` for the edit it closes, then `onStart` for the one it opens. The\n * report is made from the call, so nothing following the edit ever renders\n * with the two out of step.\n */\nexport function useEditingId(\n opts: { readonly current: Pick<UseTextEditOptions, 'onStart' | 'onEnd'> },\n): [string | null, (id: string | null) => void] {\n const [editingId, setState] = useState<string | null>(null);\n const live = useRef<string | null>(null);\n const setEditingId = useCallback((id: string | null) => {\n const prev = live.current;\n if (prev === id) return;\n live.current = id;\n setState(id);\n if (prev !== null) opts.current.onEnd?.(prev);\n if (id !== null) opts.current.onStart?.(id);\n }, [opts]);\n return [editingId, setEditingId];\n}\n","/** The option, return, and pose types of `useTextEdit`. */\nimport type {\n FlagKey, RangeStyle, RunStylePatch, StyledRun, TextPaint, TextStyle, TextVerticalAlign,\n} from '@weasel-js/text';\n\n/**\n * A styling a shortcut or a control toggles. The additive booleans, plus the\n * two `script` values — which are exclusive rather than additive, so they\n * toggle against one enum rather than each owning a boolean.\n */\nexport type StyleToggle = FlagKey | 'super' | 'sub';\n\n/**\n * The caret's character range within the text being edited. Half-open\n * `[start, end)` over the concatenated run text, normalized so `start <= end`\n * regardless of which way the user dragged. `start === end` is a collapsed\n * caret — a real position, not the absence of one, which is why the hook\n * reports `null` rather than a zero-width range when there is no caret.\n */\nexport interface TextEditSelection {\n start: number;\n end: number;\n}\n\n/** Screen-space pose passed to `useTextEdit` so the overlay can be placed and sized in CSS pixels. */\nexport interface TextEditScreenPose {\n /** Top-left in CSS pixels relative to `container`. Always screen pixels,\n * including when `zoom` is set — the scale is anchored at this point, not\n * translated by it. */\n x: number;\n y: number;\n /** Pre-scale — CSS pixels, or world units when `zoom` is set. */\n width: number;\n height: number;\n /** Pre-scale font size: `style.fontSize * zoom` when `zoom` is omitted, the\n * world-unit `style.fontSize` when it is set. */\n fontSize: number;\n /** Effective on-screen line height multiplier (defaults to style.lineHeight). */\n lineHeight?: number;\n /**\n * Where the text sits within `height`, as the canvas places it. `'center'`\n * and `'bottom'` size the overlay to its own content and offset it by the\n * slack, re-measured as typing changes the line count. Default `'top'`.\n */\n verticalAlign?: TextVerticalAlign;\n /**\n * CSS scale applied to the overlay (`transform: scale(zoom)`, anchored at\n * its top-left). Every other size on this pose, and every typographic\n * metric the hook writes, is then **pre-scale** — pass world units and the\n * transform does the world→screen conversion.\n *\n * This is the only way run-level typography can be correct at a zoom other\n * than 1. Omit it (the default, `1`) and the pose is plain screen pixels —\n * the hook then infers the world→screen factor from\n * `fontSize / style.fontSize` to scale node-level `letterSpacing`, and\n * run-level overrides are left unscaled.\n */\n zoom?: number;\n /**\n * The frame the text is drawn in, when its box is turned or skewed: the\n * linear part `[a, b, c, d]` (`x' = a·x + c·y`, `y' = b·x + d·y`) applied\n * about the box's center. `x`, `y`, `width`, and `height` stay those of\n * the box before it. Absent is the identity.\n */\n frame?: readonly [a: number, b: number, c: number, d: number];\n /**\n * Cut the overlay's text at the box `x`/`y`/`width`/`height` name, grown by\n * these on each side, in the same pre-scale units. It turns with `frame`,\n * so it holds to the box as the canvas draws it. Absent, the text may run\n * past the box, cut only by `getClipRect`.\n */\n clip?: { top: number; right: number; bottom: number; left: number };\n}\n\n/** A box in CSS pixels relative to `useTextEdit`'s `container`. */\nexport interface TextEditClipRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** What one edit session changed, as `UseTextEditOptions.commit` receives it. */\nexport interface TextEditCommit {\n text: string;\n runs?: StyledRun[];\n /** The node's own style, where the edit rewrote it. */\n style?: TextStyle;\n}\n\n/** What the overlay holds mid-edit, as {@link UseTextEditOptions.onDraft} reports it: what a commit would write now. */\nexport type TextEditDraft = TextEditCommit;\n\n/** Options for `useTextEdit`. */\nexport interface UseTextEditOptions {\n /** Element the overlay is appended to. Must be `position: relative`/absolute. */\n container: HTMLElement | null;\n /** Read the current text for `id`. */\n getText: (id: string) => string;\n /** Read style for `id` (used for font setup on the overlay). */\n getStyle: (id: string) => TextStyle | undefined;\n /**\n * Read the node's paint for `id` — its `data.fill` / `data.stroke`. The\n * overlay paints its text and caret from the fill, so omitting this\n * renders every node's editor in the default black however the node\n * itself is painted.\n */\n getPaint?: (id: string) => TextPaint | undefined;\n /**\n * Write style back for `id`. Optional; needed only to turn a flag **off**\n * inside a node whose own `TextStyle` sets it. Run flags are additive, so\n * that edit is expressed by lowering the node flag and raising it on the\n * runs outside the selection — which needs somewhere to put the new node\n * style. Without this or `commit`, such a toggle is declined and nothing\n * changes. See `flagRange` in `@weasel-js/text`.\n *\n * Called when the edit commits, never during it: the session holds the\n * rewritten style until then (see `UseTextEditReturn.nodeStyle`), so a\n * canceled edit writes nothing.\n */\n setStyle?: (id: string, style: TextStyle) => void;\n /** Read screen-space pose for `id`. Called per frame while editing. */\n getScreenPose: (id: string) => TextEditScreenPose | null;\n /**\n * The box, in CSS pixels relative to `container`, the overlay is visible\n * within — where the canvas clips the glyphs the overlay stands in for.\n * Re-read every frame. Omit it, or return `null`, to clip nothing.\n *\n * The clip cannot scroll, so a caret moving past its edge leaves the page\n * where it is; a scrollable container would drag the canvas after the caret.\n */\n getClipRect?: () => TextEditClipRect | null;\n /** Commit text. Caller wraps in op/undo. Required unless `commit` is given. */\n setText?: (id: string, text: string) => void;\n /**\n * Take the whole edit in one call, so the caller can make it one write and\n * one undo step. When given, it replaces `setText`, `setRuns`, and\n * `setStyle`, none of which is called. `runs` is present when runs are in\n * play (see `setRuns`), `style` when the edit rewrote the node's own style\n * (see `setStyle`).\n */\n commit?: (id: string, edit: TextEditCommit) => void;\n /**\n * Called on each edit to the overlay's text, and on each restyle of it, with\n * what a commit would write now: `runs` present when runs are in play (see\n * `setRuns`), `style` when the edit rewrote the node's own. For a host\n * whose canvas shows the text somewhere besides the overlay, such as a copy\n * laid along a path, to follow the typing. Not a commit: a cancel follows\n * as it would without it.\n */\n onDraft?: (id: string, draft: TextEditDraft) => void;\n /**\n * Optional: read the current rich-text runs for `id`. When provided AND\n * returns a non-empty array, the overlay renders the runs as styled\n * `<span data-run>` elements; otherwise the overlay is seeded with plain\n * text via `getText`.\n */\n getRuns?: (id: string) => readonly StyledRun[] | undefined;\n /**\n * Optional: commit rich-text runs back to the node. When omitted, only\n * `setText` is called with the plain-text form on commit. When provided,\n * commit calls both `setText` (with `runsToPlainText(runs)`) and\n * `setRuns(id, runs)` — but only when runs are actually in play: the node\n * already had some, or the edit produced styling. A plain-text edit of a\n * plain-text node still calls `setText` alone.\n */\n setRuns?: (id: string, runs: StyledRun[]) => void;\n /**\n * Is `el` part of the editor's own chrome — a character-options bar, a\n * color popover, anything whose whole purpose is to style the text being\n * edited? Focus moving into one does not end the edit.\n *\n * Without this, clicking a size field blurs the overlay, blur commits, and\n * the caret the control was about to act on is gone. Toggle buttons can\n * dodge it by `preventDefault()`-ing their own mousedown, but a field the\n * user has to type into cannot.\n *\n * Chrome focus does not disturb the reported `selection` either — see\n * `UseTextEditReturn.selection`.\n */\n isEditorChrome?: (el: Element) => boolean;\n /** What Escape does to the edit: `'cancel'` (the default) drops it,\n * `'commit'` keeps the text as Enter would. */\n escape?: 'cancel' | 'commit';\n /** Called as an edit of `id` opens, from the call that opens it. */\n onStart?: (id: string) => void;\n /**\n * Called as the edit of `id` closes, however it does: a commit, a cancel,\n * a click away, or another edit opening over it. A commit has been written\n * by then. Not called when the hook unmounts with an edit open.\n */\n onEnd?: (id: string) => void;\n /**\n * How long, in ms, an edit opening waits for the overlay's face before\n * showing the text in the fallback. Defaults to {@link TEXT_EDIT_FONT_HOLD}.\n *\n * The overlay stands in for canvas text the host has hidden, so the wait\n * shows nothing at all; past it, the fallback shows and reflows to the real\n * face when that lands. A face already loaded shows at once. `0` never waits.\n */\n fontHold?: number;\n}\n\n/**\n * The default {@link UseTextEditOptions.fontHold}: at 100ms a blank edit\n * still reads as an instant response, and it is the block period CSS gives\n * `font-display: fallback` for the same trade.\n */\nexport const TEXT_EDIT_FONT_HOLD = 100;\n\n/** Options for `useTextEdit().startEdit`. */\nexport interface StartEditOptions {\n /** Where to place the caret on edit start. Number = caret offset (0..text.length);\n * `'all'` selects the whole text (default). */\n caret?: number | 'all';\n}\n\n/** Return shape of `useTextEdit`. */\nexport interface UseTextEditReturn {\n editingId: string | null;\n startEdit: (id: string, opts?: StartEditOptions) => void;\n cancelEdit: () => void;\n /** End the edit and write it. An edit that leaves the text, the runs, and\n * the node's style as it found them writes nothing. */\n commit: () => void;\n isEditing: (id: string) => boolean;\n /**\n * The node-wide style this edit has rewritten and not yet written back, or\n * `null` when it has rewritten none (the node's own style stands) or\n * nothing is being edited. Lowering a flag the node sets rewrites it; the\n * write waits for the commit. A control showing the node's style during an\n * edit reads this first.\n */\n nodeStyle: TextStyle | null;\n /**\n * The caret's character range, or `null` when nothing is being edited. A\n * collapsed caret reports `{ start: n, end: n }`, so `null` and \"caret at\n * n\" stay distinguishable — a styling written at a collapsed caret arms\n * {@link UseTextEditReturn.pendingStyle} instead of restyling a range.\n *\n * Follows the DOM selection, which browsers report from a task\n * rather than synchronously; anything this hook writes itself updates it\n * synchronously. A DOM selection that leaves the overlay does **not** clear\n * it: that is what happens when the user clicks a styling control, and\n * reporting `null` there would read as \"collapsed caret\" and send the\n * control's patch to the node instead of to the range. It is cleared on\n * `startEdit` and when the edit ends.\n */\n selection: TextEditSelection | null;\n /**\n * The styling shared by every run in `selection` — a concrete value where\n * the range agrees, `MIXED` where it doesn't. `null` exactly when\n * `selection` is `null`. A collapsed caret reports the styling *at* the\n * caret (the run to its left, or the run to its right at offset 0), which\n * is what the next typed character inherits.\n *\n * This does not include {@link UseTextEditReturn.pendingStyle}. A control\n * showing what the next character will look like wants both, merged in\n * that order; one showing what is already written wants only this.\n */\n rangeStyle: RangeStyle | null;\n /**\n * Styling armed at a collapsed caret, applied to the next character typed\n * and then dropped. `{}` when nothing is armed — which is always the case\n * while `selection` covers a real range, since a range is styled directly.\n * Moving the caret abandons it.\n */\n pendingStyle: RunStylePatch;\n /**\n * What a styling control shows during an edit: the node's own style and\n * paint, `rangeStyle` over it, and `pendingStyle` last — what the user\n * will see themselves type. `null` when nothing is being edited.\n */\n effectiveStyle: RangeStyle | null;\n /**\n * Write `patch` over `selection`. A no-op with no active edit or an empty\n * patch. Over a real range this restyles the runs under it; at a collapsed\n * caret it merges into `pendingStyle` instead, so the styling lands on\n * what gets typed next rather than on text the user didn't select.\n *\n * Lowering a flag the *node* sets is neither of those — a run cannot say\n * \"not italic\" — so it rewrites instead: the node flag is cleared and raised\n * on every run outside the range. Bold is spared that: a run's own\n * `fontWeight` can say \"regular\", so it is written over the range.\n *\n * The caret survives, so a second style can be applied without\n * re-selecting, and `rangeStyle` reflects the write before this returns.\n */\n applyStyleToSelection: (patch: RunStylePatch) => void;\n /** Toggle one styling over `selection` — set it if the range doesn't\n * uniformly carry it, clear it if it does. */\n toggleStyle: (toggle: StyleToggle) => void;\n}\n","/**\n * In-place text editing via a contenteditable overlay positioned over the\n * text node's screen-space pose. Enter / blur commit; Shift+Enter inserts a\n * newline. The text layer should hide the node it's currently editing\n * (`isHidden: (n) => n.id === editingId`) so the overlay isn't drawn twice.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useLatest, useVisibleRaf } from '@weasel-js/react';\nimport type { ResolvedTextStyle, TextStyle } from '@weasel-js/text';\nimport {\n numericWeight, resolveTextStyle, scriptMetricsFor,\n} from '@weasel-js/text';\nimport { cssFontFamilyLoading } from '@weasel-js/font';\nimport { layoutTextPose } from '@weasel-js/text';\nimport type { StyledRun } from '@weasel-js/text';\nimport { domToRuns, type OverlayRunBase } from './domRuns';\nimport {\n applyStyleToRange, effectiveRangeStyle, nodeHasFlag, patchRangeStyle, rangeWeight, setFlagOverRange,\n styleAtRange, supersededKey, unboldPatch, type FlagKey, type RangeStyle, type RunStylePatch,\n} from '@weasel-js/text';\nimport { overlayAlignEdge } from './overlayDirection';\nimport { draftChanged, overlayDraft, writeEdit } from './overlayDraft';\nimport { overlayClipPath, overlayTop, overlayTransform } from './overlayFrame';\nexport { overlayTop };\nimport { applyOverlayStyle } from './overlayStyle';\nimport { seedOverlay, type CaretHolder } from './overlaySeed';\nimport {\n readSelectionOffsets, restoreOverlayFocus, sameSelection, writeRunsPreservingSelection,\n} from './overlaySelection';\nimport { typingHandlers } from './overlayTyping';\nimport { toggleForKey } from './styleShortcuts';\nimport { useEditingId } from './editSession';\nimport { TEXT_EDIT_FONT_HOLD } from './textEditTypes';\nimport type {\n StartEditOptions, StyleToggle, TextEditClipRect, TextEditScreenPose, TextEditSelection, UseTextEditOptions,\n UseTextEditReturn,\n} from './textEditTypes';\n\n/**\n * The patch that toggles `toggle` against the styling in `current`: if it is\n * already carried, clear it; otherwise set it — so a mixed range turns fully\n * on. `nodeStyle` is read as well as `current`: a node flag renders on every\n * run whether or not the runs carry it, so the runs alone would read Cmd+B\n * inside a `fontWeight: 700` node as \"not bold\" and *add* bold.\n */\nfunction patchForToggle(\n current: RangeStyle,\n toggle: StyleToggle,\n nodeStyle: TextStyle,\n): RunStylePatch {\n if (toggle === 'super' || toggle === 'sub') {\n return { script: current.script === toggle ? undefined : toggle };\n }\n const on = toggle === 'bold'\n ? rangeWeight(current, nodeStyle).bold === true\n : current[toggle] === true || nodeHasFlag(nodeStyle, toggle);\n return { [toggle]: !on };\n}\n\n/**\n * The styling at a collapsed caret: the run to its left, or — at the very\n * start of the text — the run to its right. This is what the next typed\n * character inherits.\n */\nfunction styleAtCaret(runs: readonly StyledRun[], at: number): RangeStyle {\n return at > 0 ? styleAtRange(runs, at - 1, at) : styleAtRange(runs, 0, 1);\n}\n\n/** No pending style. One frozen object so re-publishing an already-empty\n * pending style doesn't re-render every consumer. */\nconst NO_PENDING: RunStylePatch = Object.freeze({});\n\n/**\n * Merge `patch` into a pending style. A key set to `false` or `undefined` is\n * deleted rather than stored, and bold and a weight supersede each other —\n * the canonical form a stored run keeps.\n */\nfunction mergePending(prev: RunStylePatch, patch: RunStylePatch): RunStylePatch {\n const next: Record<string, unknown> = { ...prev };\n const superseded = supersededKey(patch);\n if (superseded !== undefined) delete next[superseded];\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || value === false) delete next[key];\n else next[key] = value;\n }\n return next as RunStylePatch;\n}\n\n/** In-place text editing via a contenteditable overlay positioned over the text node's screen-space pose. */\nexport function useTextEdit(\n opts: UseTextEditOptions,\n): UseTextEditReturn {\n const optsRef = useLatest(opts);\n\n const [editingId, setEditingId] = useEditingId(optsRef);\n // `applyStyleToSelection` needs the node being edited to reach its\n // `TextStyle`, and is called from event handlers rather than from render.\n const editingIdRef = useLatest(editingId);\n const overlayRef = useRef<HTMLDivElement | null>(null);\n /** The editing node's resolved style, which run spans inheriting small caps\n * are split by whenever the runs are rewritten. */\n const baseRef = useRef<OverlayRunBase>(resolveTextStyle(undefined));\n const [nodeStyle, setNodeStyle] = useState<TextStyle | null>(null);\n /** `nodeStyle`, read synchronously by the handlers that rewrite and commit it. */\n const nodeStyleRef = useRef<TextStyle | null>(null);\n const holdNodeStyle = useCallback((style: TextStyle | null) => {\n nodeStyleRef.current = style;\n setNodeStyle(style);\n }, []);\n const styleOf = useCallback(\n (id: string): TextStyle | undefined => nodeStyleRef.current ?? optsRef.current.getStyle(id),\n [optsRef],\n );\n // The overlay-follow loop is built inside the editing effect; the gate's\n // frame callback reaches it through this ref.\n const tickRef = useRef<() => void>(() => {});\n const frameLoop = useVisibleRaf(() => { tickRef.current(); });\n const initialCaretRef = useRef<number | 'all'>('all');\n /** What the overlay read back as when the edit opened, before any input. */\n const openedRef = useRef<string | null>(null);\n const sentRef = useRef(''); // the last draft sent, as JSON; before the first, the overlay as it opened\n const holderRef = useRef<CaretHolder | null>(null);\n const priorRunsRef = useRef<readonly StyledRun[] | undefined>(undefined); // the node's, as the edit opened\n const [selection, setSelection] = useState<TextEditSelection | null>(null);\n const [rangeStyle, setRangeStyle] = useState<RangeStyle | null>(null);\n const [pendingStyle, setPendingStyle] = useState<RunStylePatch>(NO_PENDING);\n /** The pending style, read synchronously by `beforeinput` — which fires\n * well before React has re-rendered with the state above. */\n const pendingRef = useRef<RunStylePatch>(NO_PENDING);\n /** The caret offset the pending style was armed at, or `null` when nothing\n * is armed. Publishing any other range abandons it. */\n const pendingAtRef = useRef<number | null>(null);\n\n const armPending = useCallback((next: RunStylePatch, at: number) => {\n const empty = Object.keys(next).length === 0;\n pendingRef.current = empty ? NO_PENDING : next;\n pendingAtRef.current = empty ? null : at;\n setPendingStyle(pendingRef.current);\n }, []);\n\n const dropPending = useCallback(() => {\n if (pendingAtRef.current === null) return;\n pendingRef.current = NO_PENDING;\n pendingAtRef.current = null;\n setPendingStyle(NO_PENDING);\n }, []);\n\n /** The published range, mirrored in a ref: the fallback when the DOM\n * selection has moved into editing chrome. */\n const selectionRef = useRef<TextEditSelection | null>(null);\n\n /** Publish `range` and the styling the overlay currently carries across it. */\n const publishRange = useCallback((overlay: HTMLElement, range: TextEditSelection) => {\n const collapsed = range.start === range.end;\n // A pending style belongs to the caret position it was armed at. Any\n // other range means the caret moved, which abandons it.\n if (pendingAtRef.current !== null\n && !(collapsed && range.start === pendingAtRef.current)) {\n dropPending();\n }\n selectionRef.current = range;\n setSelection((prev) => (sameSelection(prev, range) ? prev : range));\n const runs = domToRuns(overlay);\n setRangeStyle(collapsed\n ? styleAtCaret(runs, range.start)\n : styleAtRange(runs, range.start, range.end));\n }, [dropPending]);\n\n const syncSelection = useCallback(() => {\n const overlay = overlayRef.current;\n if (!overlay) return;\n const next = readSelectionOffsets(overlay);\n // A selection outside the overlay means focus moved into a control, which\n // is when the range matters most: leave it published rather than clear it.\n if (next === null) return;\n publishRange(overlay, next);\n }, [publishRange]);\n\n /** Drop the published range — the edit session it described is over. */\n const clearSelection = useCallback(() => {\n selectionRef.current = null;\n setSelection(null);\n setRangeStyle(null);\n dropPending();\n }, [dropPending]);\n\n const cancelEdit = useCallback(() => setEditingId(null), [setEditingId]);\n\n const commit = useCallback(() => {\n const id = editingId;\n const overlay = overlayRef.current;\n if (id == null || !overlay) return void setEditingId(null);\n // Runs are written when the node already had them — or stale styling\n // survives a Cmd-B that turned it off — or when the edit produced\n // styling. A plain-text edit of a plain-text node commits text alone.\n const read = domToRuns(overlay);\n const style = nodeStyleRef.current;\n // Compared untrimmed: a seeded trailing newline reads back the same at\n // both ends, where the trimmed form would differ from the node's text.\n if (!style && JSON.stringify(read) === openedRef.current) {\n setEditingId(null);\n return;\n }\n holdNodeStyle(null);\n writeEdit(optsRef.current, id, overlayDraft(read, holderRef.current, priorRunsRef.current, style));\n setEditingId(null);\n }, [editingId, optsRef, holdNodeStyle, setEditingId]);\n\n const startEdit = useCallback((id: string, opts?: StartEditOptions) => {\n initialCaretRef.current = opts?.caret ?? 'all';\n setEditingId(id);\n }, [setEditingId]);\n\n const isEditing = useCallback((id: string) => editingId === id, [editingId]);\n\n const sendDraft = useCallback((overlay: HTMLElement) => {\n const id = editingIdRef.current;\n const draft = overlayDraft(domToRuns(overlay), holderRef.current, priorRunsRef.current, nodeStyleRef.current);\n if (id !== null && draftChanged(sentRef, draft)) optsRef.current.onDraft?.(id, draft);\n }, [editingIdRef, optsRef]);\n\n const applyStyleToSelection = useCallback(function applyStyle(patch: RunStylePatch) {\n const overlay = overlayRef.current;\n if (!overlay) return;\n // An empty patch would still round-trip the runs through\n // `applyStyleToRange`, whose normalization applies to the whole array.\n if (Object.keys(patch).length === 0) return;\n // Fall back to the last range that WAS in the overlay: the caller may be\n // a control that took focus (and with it the DOM selection) to be clicked.\n const range = readSelectionOffsets(overlay) ?? selectionRef.current;\n if (!range) return;\n\n // Lowering a flag the node itself sets is not expressible additively, so\n // it takes the rewrite in `setFlagOverRange`: clear the node flag, raise\n // it outside the range. It reaches existing text even from a collapsed caret.\n const id = editingIdRef.current;\n const canWriteStyle = optsRef.current.setStyle !== undefined || optsRef.current.commit !== undefined;\n const runs = domToRuns(overlay);\n if (patch.bold === false && !('fontWeight' in patch) && id !== null) {\n patch = { ...patch, ...unboldPatch(styleOf(id) ?? {}) };\n }\n const unsetFlag = id !== null && canWriteStyle\n ? (Object.keys(patch) as FlagKey[]).find((key) =>\n key !== 'bold'\n && patch[key] === false\n && nodeHasFlag(styleOf(id) ?? {}, key))\n : undefined;\n if (unsetFlag !== undefined && id !== null) {\n const r = setFlagOverRange(runs, styleOf(id) ?? {}, range.start, range.end, unsetFlag, false);\n holdNodeStyle(r.style);\n // The root's own decoration and slant reach every run by inheritance,\n // the range just cleared included.\n const resolved = resolveTextStyle(r.style, optsRef.current.getPaint?.(id));\n baseRef.current = resolved;\n applyOverlayStyle(overlay, resolved);\n writeRunsPreservingSelection(overlay, r.runs, range.start, range.end, resolved);\n publishRange(overlay, range);\n // The rewrite raised the flag on every existing run, so a caret sitting\n // at the end of one is now *inside* a flagged span and the next\n // character would be absorbed by it. Arming the `false` makes\n // `beforeinput` open a fresh span instead.\n if (range.start === range.end) {\n armPending({ ...pendingRef.current, [unsetFlag]: false }, range.start);\n }\n restoreOverlayFocus(overlay, range);\n // Whatever else the patch carried still applies on its own terms.\n const rest = { ...patch };\n delete rest[unsetFlag];\n if (Object.keys(rest).length > 0) applyStyle(rest);\n sendDraft(overlay);\n return;\n }\n\n // A collapsed caret has no run to restyle, so the styling is armed for\n // the next character instead of silently doing nothing.\n if (range.start === range.end) {\n armPending(mergePending(pendingRef.current, patch), range.start);\n restoreOverlayFocus(overlay, range);\n return;\n }\n\n const next = applyStyleToRange(runs, range.start, range.end, patch);\n writeRunsPreservingSelection(overlay, next, range.start, range.end, baseRef.current);\n restoreOverlayFocus(overlay, range);\n // Republish from the range we just styled, not from the DOM selection:\n // when the patch came from chrome the selection is in that control.\n publishRange(overlay, range);\n sendDraft(overlay);\n }, [publishRange, armPending, editingIdRef, optsRef, styleOf, holdNodeStyle, sendDraft]);\n\n const toggleStyle = useCallback((toggle: StyleToggle) => {\n const overlay = overlayRef.current;\n if (!overlay) return;\n const range = readSelectionOffsets(overlay) ?? selectionRef.current;\n if (!range) return;\n const runs = domToRuns(overlay);\n const id = editingIdRef.current;\n const nodeStyle = (id !== null ? styleOf(id) : undefined) ?? {};\n // At a collapsed caret the styling in play is what the caret sits in plus\n // whatever is already armed, so pressing Cmd+B twice disarms rather than\n // arming a second time.\n const current = range.start === range.end\n ? patchRangeStyle(styleAtCaret(runs, range.start), pendingRef.current)\n : styleAtRange(runs, range.start, range.end);\n applyStyleToSelection(patchForToggle(current, toggle, nodeStyle));\n }, [applyStyleToSelection, editingIdRef, styleOf]);\n\n useEffect(() => {\n if (editingId == null) return;\n const { container, getText, getStyle, getPaint } = optsRef.current;\n if (!container) return;\n holdNodeStyle(null);\n\n const style = resolveTextStyle(getStyle(editingId), getPaint?.(editingId));\n const overlay = document.createElement('div');\n const overlayClass = `weasel-text-edit-${++OVERLAY_SEQ}`;\n overlay.classList.add(overlayClass);\n overlay.setAttribute('contenteditable', 'true');\n overlay.spellcheck = false;\n baseRef.current = style;\n const initialRuns = (priorRunsRef.current = optsRef.current.getRuns?.(editingId));\n holderRef.current = seedOverlay(overlay, getText(editingId), initialRuns, style);\n openedRef.current = JSON.stringify(domToRuns(overlay));\n sentRef.current = JSON.stringify(overlayDraft(domToRuns(overlay), holderRef.current, initialRuns));\n applyOverlayStyle(overlay, style);\n const hold = holdForFaces(style, initialRuns ?? []);\n if (hold) overlay.style.opacity = '0';\n const styleEl = installSelectionStyle(overlayClass, style);\n const clipBox = createClipBox();\n clipBox.appendChild(overlay);\n container.appendChild(clipBox);\n overlayRef.current = overlay;\n\n const place = () => {\n const clip = optsRef.current.getClipRect?.() ?? null;\n placeOverlay(overlay, clipBox, optsRef.current.getScreenPose(editingId), clip, style);\n };\n place();\n // Measured again on release: the first `place` ran in the fallback face.\n let held = hold !== null;\n const release = () => {\n if (!held) return;\n held = false;\n clearTimeout(holdTimer);\n place();\n overlay.style.opacity = '';\n };\n const holdTimer = held ? setTimeout(release, optsRef.current.fontHold ?? TEXT_EDIT_FONT_HOLD) : undefined;\n void hold?.then(release);\n\n const range = document.createRange();\n const initial = initialCaretRef.current;\n if (initial === 'all') {\n range.selectNodeContents(overlay);\n } else {\n placeCaretAt(overlay, range, initial);\n }\n // Focus first, then place the caret: focusing an editable host itself\n // moves the selection (jsdom collapses to the start; browsers vary).\n overlay.focus();\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n // Publish now rather than on the `selectionchange` task — a control mounted\n // alongside the editor would otherwise render one frame with no selection.\n syncSelection();\n\n const onKeyDown = (e: KeyboardEvent) => {\n // The key belongs to the IME: Enter confirms a candidate, Escape dismisses\n // them. Safari reports it after `compositionend`, as keyCode 229.\n if (e.isComposing || e.keyCode === 229) return;\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n commit();\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n if (optsRef.current.escape === 'commit') commit();\n else cancelEdit();\n return;\n }\n const toggle = toggleForKey(e);\n if (toggle) {\n e.preventDefault();\n toggleStyle(toggle);\n }\n };\n const onBlur = (e: FocusEvent) => {\n const next = e.relatedTarget;\n if (isChrome(optsRef.current, next)) return;\n commit();\n };\n\n const { onBeforeInput, onInput } = typingHandlers(overlay, {\n pending: () => pendingRef.current,\n base: () => baseRef.current,\n lastRange: () => selectionRef.current,\n onWritten: (caret) => {\n dropPending();\n publishRange(overlay, { start: caret, end: caret });\n },\n onEdited: () => {\n holderRef.current?.edited(overlay);\n place();\n sendDraft(overlay);\n },\n });\n\n // Blur can't be the only way out: once focus has moved into editing\n // chrome, nothing blurs when the user clicks away. Capture phase so this\n // runs ahead of whatever the click was aimed at.\n const onPointerDownOutside = (e: Event) => {\n const target = e.target;\n if (!(target instanceof Node) || overlay.contains(target)) return;\n if (isChrome(optsRef.current, target)) return;\n commit();\n };\n\n overlay.addEventListener('keydown', onKeyDown);\n overlay.addEventListener('blur', onBlur);\n // Typing can change the line count; re-placing here rather than on the\n // next frame keeps a center/bottom-aligned overlay from jumping a frame late.\n overlay.addEventListener('input', onInput);\n overlay.addEventListener('beforeinput', onBeforeInput);\n document.addEventListener('pointerdown', onPointerDownOutside, true);\n // `selectionchange` only exists on the document.\n document.addEventListener('selectionchange', syncSelection);\n\n // Follows the node's screen pose every frame — behind the visibility gate,\n // so an overlay left open in a background tab costs nothing.\n tickRef.current = () => {\n place();\n frameLoop.request();\n };\n frameLoop.request();\n\n return () => {\n held = false;\n clearTimeout(holdTimer);\n frameLoop.cancel();\n tickRef.current = () => {};\n overlay.removeEventListener('keydown', onKeyDown);\n overlay.removeEventListener('blur', onBlur);\n overlay.removeEventListener('input', onInput);\n overlay.removeEventListener('beforeinput', onBeforeInput);\n document.removeEventListener('pointerdown', onPointerDownOutside, true);\n document.removeEventListener('selectionchange', syncSelection);\n clipBox.remove();\n styleEl?.remove();\n overlayRef.current = null;\n holdNodeStyle(null);\n clearSelection();\n };\n }, [editingId, opts.container, optsRef, commit, cancelEdit, syncSelection, clearSelection,\n frameLoop, toggleStyle, dropPending, publishRange, holdNodeStyle, sendDraft]);\n\n return {\n editingId, startEdit, cancelEdit, commit, isEditing, nodeStyle,\n selection, rangeStyle, pendingStyle, applyStyleToSelection, toggleStyle,\n effectiveStyle: shownStyle(opts, editingId, nodeStyle, rangeStyle, pendingStyle),\n };\n}\n\nfunction isChrome(opts: UseTextEditOptions, el: EventTarget | null): boolean {\n return el instanceof Element && (opts.isEditorChrome?.(el) ?? false);\n}\n\nfunction shownStyle(\n opts: UseTextEditOptions,\n editingId: string | null,\n nodeStyle: TextStyle | null,\n rangeStyle: RangeStyle | null,\n pendingStyle: RunStylePatch,\n): RangeStyle | null {\n if (editingId === null) return null;\n return effectiveRangeStyle(\n patchRangeStyle(rangeStyle ?? {}, pendingStyle),\n nodeStyle ?? opts.getStyle(editingId),\n opts.getPaint?.(editingId),\n );\n}\n\nlet OVERLAY_SEQ = 0;\n\n/**\n * The loads the overlay's faces are still waiting on — the node's and each\n * run's that names its own family — or `null` when every one is in hand.\n */\nfunction holdForFaces(style: ResolvedTextStyle, runs: readonly StyledRun[]): Promise<unknown> | null {\n const pending = [\n cssFontFamilyLoading(style.fontFamily, {\n weight: numericWeight(style.fontWeight), style: style.fontStyle,\n }),\n ...runs.filter((r) => r.fontFamily != null).map((r) => cssFontFamilyLoading(r.fontFamily!, {\n weight: r.fontWeight ?? (r.bold ? 700 : undefined),\n style: r.italic ? 'italic' : undefined,\n })),\n ].filter((p) => p !== null);\n return pending.length === 0 ? null : Promise.all(pending);\n}\n\n/**\n * Place a collapsed caret `offset` characters into the overlay's text,\n * walking its text nodes. Out-of-range offsets clamp to the end.\n */\nfunction placeCaretAt(root: HTMLElement, range: Range, offset: number): void {\n let remaining = offset;\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n let node: Text | null = walker.nextNode() as Text | null;\n while (node) {\n const len = node.data.length;\n if (remaining <= len) {\n range.setStart(node, remaining);\n range.setEnd(node, remaining);\n return;\n }\n remaining -= len;\n node = walker.nextNode() as Text | null;\n }\n range.selectNodeContents(root);\n range.collapse(false);\n}\n\n/** The overlay's positioning parent. Passes pointer input through everywhere\n * but the overlay itself, which spans no more than the canvas it covers. */\nfunction createClipBox(): HTMLDivElement {\n const el = document.createElement('div');\n el.style.position = 'absolute';\n el.style.margin = '0';\n el.style.padding = '0';\n el.style.border = '0';\n el.style.pointerEvents = 'none';\n return el;\n}\n\n/**\n * Inject a `<style>` element scoped to `overlayClass` so the edit overlay's\n * `::selection` matches the configured colors, or `null` when none are set.\n */\nfunction installSelectionStyle(\n overlayClass: string,\n style: ResolvedTextStyle,\n): HTMLStyleElement | null {\n if (style.selectionBackground == null && style.selectionColor == null) return null;\n const el = document.createElement('style');\n const decls: string[] = [];\n if (style.selectionBackground != null) {\n decls.push(`background: ${style.selectionBackground};`);\n }\n if (style.selectionColor != null) {\n decls.push(`color: ${style.selectionColor};`);\n }\n el.textContent = `.${overlayClass}::selection { ${decls.join(' ')} }`;\n document.head.appendChild(el);\n return el;\n}\n\nconst ALIGN_ANCHOR = { left: 0, center: 0.5, right: 1 } as const;\n\n/**\n * The canvas and CSS both hang a line's baseline half the leading plus one\n * ascent below the line top, from the same ascent rule, but each engine\n * rounds the font's metrics and that leading its own way, and a face that\n * states no ascent and descent hangs from its ascent alone. So the difference\n * is read from both sides rather than predicted: the canvas's from its own layout, the\n * overlay's from a zero-height inline box on a hidden line set exactly as the\n * overlay is. Pre-scale; `0` when either side has nothing to measure.\n * @internal\n */\nexport function baselineDrop(el: HTMLElement, style: ResolvedTextStyle, pose: TextEditScreenPose, lineHeight: number): number {\n const canvas = layoutTextPose({\n x: 0, y: 0, width: pose.width, height: pose.height, text: ' ',\n style: {\n fontFamily: style.fontFamily, fontWeight: style.fontWeight, fontStyle: style.fontStyle,\n fontSize: pose.fontSize, lineHeight, script: style.script,\n },\n }).laid.lines[0]?.baselineY ?? 0;\n const css = cssBaseline(el);\n return canvas > 0 && css > 0 ? canvas - css : 0;\n}\n\nconst CSS_BASELINES = new Map<string, number>();\n\nfunction cssBaseline(el: HTMLElement): number {\n const parent = el.parentElement;\n if (!parent) return 0;\n const { fontFamily, fontWeight, fontStyle, fontSize, lineHeight, textRendering } = el.style;\n const key = [fontFamily, fontWeight, fontStyle, fontSize, lineHeight, textRendering].join('|');\n const cached = CSS_BASELINES.get(key);\n if (cached !== undefined) return cached;\n const line = document.createElement('div');\n Object.assign(line.style, {\n position: 'absolute', left: '0', top: '0', width: '100px', margin: '0', padding: '0', border: '0',\n visibility: 'hidden', whiteSpace: 'pre', fontFamily, fontWeight, fontStyle, fontSize, lineHeight, textRendering,\n });\n const mark = document.createElement('span');\n Object.assign(mark.style, { display: 'inline-block', width: '0', height: '0', verticalAlign: 'baseline' });\n line.appendChild(mark);\n parent.appendChild(line);\n const box = line.getBoundingClientRect();\n // Rect over layout width undoes any transform on an ancestor.\n const scale = box.width / 100;\n const baseline = scale > 0 ? (mark.getBoundingClientRect().top - box.top) / scale : 0;\n line.remove();\n // A web font still loading is measured as its fallback; ask again later.\n if (baseline > 0 && document.fonts?.status !== 'loading') {\n if (CSS_BASELINES.size >= 64) CSS_BASELINES.clear();\n CSS_BASELINES.set(key, baseline);\n }\n return baseline;\n}\n\nfunction placeOverlay(\n el: HTMLDivElement,\n clipBox: HTMLDivElement,\n pose: TextEditScreenPose | null,\n clip: TextEditClipRect | null,\n style: ResolvedTextStyle,\n): void {\n if (!pose) {\n el.style.display = 'none';\n return;\n }\n // `clip` rather than `hidden`: a `hidden` box is still scrollable, and the\n // browser scrolls it to keep the caret in view.\n clipBox.style.overflow = clip ? 'clip' : 'visible';\n clipBox.style.left = `${clip?.x ?? 0}px`;\n clipBox.style.top = `${clip?.y ?? 0}px`;\n clipBox.style.width = `${clip?.width ?? 0}px`;\n clipBox.style.height = `${clip?.height ?? 0}px`;\n el.style.display = '';\n // An unwrapped line can be wider than its box, and the canvas aligns it\n // about the box's left edge, center, or right edge regardless. `left` puts\n // that anchor there and a trailing translate pulls the overlay back by that\n // fraction of its own width.\n const anchor = style.wrap ? 0 : ALIGN_ANCHOR[overlayAlignEdge(el, style)];\n const left = pose.x + pose.width * (pose.zoom ?? 1) * anchor;\n el.style.left = `${left - (clip?.x ?? 0)}px`;\n el.style.width = style.wrap ? `${pose.width}px` : 'max-content';\n el.style.minWidth = style.wrap ? '' : `${pose.width}px`;\n // A node-level script draws the glyphs smaller and raised on the line the\n // plain text would hold, so the line height is pinned in pixels of the\n // unscripted size rather than left to scale with the font.\n const script = style.script\n ? scriptMetricsFor(style.fontFamily, numericWeight(style.fontWeight), style.fontStyle)[style.script]\n : undefined;\n const lineHeight = pose.lineHeight ?? style.lineHeight;\n el.style.fontSize = `${pose.fontSize * (script?.size ?? 1)}px`;\n el.style.lineHeight = script ? `${pose.fontSize * lineHeight}px` : String(lineHeight);\n // A top-aligned overlay fills its box, so a click anywhere in it lands in\n // the editor. Any other alignment needs the content's own height, which a\n // min-height would mask; `offsetHeight` is pre-transform, in pose units.\n const aligned = pose.verticalAlign !== undefined && pose.verticalAlign !== 'top';\n el.style.minHeight = aligned ? '' : `${pose.height}px`;\n const drop = baselineDrop(el, style, pose, lineHeight) - (script?.shift ?? 0) * pose.fontSize;\n const top = overlayTop(pose, aligned ? el.offsetHeight : pose.height, drop);\n el.style.top = `${top - (clip?.y ?? 0)}px`;\n // A declared `zoom` means every size on the pose is pre-scale and the\n // overlay carries the view scale as a transform. Anchored at the top-left so\n // `left`/`top` stay screen pixels.\n el.style.transformOrigin = '0 0';\n el.style.transform = overlayTransform(pose, left, top, anchor);\n el.style.clipPath = pose.clip ? overlayClipPath(el, pose, left, top, anchor, pose.clip) : '';\n // `letter-spacing` is not part of the CSS `font` shorthand. Under a\n // transform the world value is the value. Without one, `pose.fontSize` is\n // `style.fontSize * zoom`, so their ratio is the world→screen factor; run\n // overrides, which `runsToDom` writes in world units, then stay unscaled,\n // so that path is only correct at zoom 1.\n const scale =\n pose.zoom !== undefined ? 1 : style.fontSize > 0 ? pose.fontSize / style.fontSize : 1;\n el.style.letterSpacing = `${style.letterSpacing * scale}px`;\n}\n"]}
1
+ {"version":3,"sources":["../src/domOffsets.ts","../src/runStyle.ts","../src/domRuns.ts","../src/overlayDirection.ts","../src/overlayDraft.ts","../src/overlayFrame.ts","../src/overlayStyle.ts","../src/overlaySeed.ts","../src/overlaySelection.ts","../src/pasteRuns.ts","../src/runSplice.ts","../src/overlayTyping.ts","../src/styleShortcuts.ts","../src/editSession.ts","../src/textEditTypes.ts","../src/useTextEdit.ts"],"names":["isSolidPaint","cssFontFamily","numericWeight","smallCapsScaleFor","isHardLineBreak","runsToPlainText","supersededKey","useRef","useState","useCallback","opts","applyStyleToRange","nodeStyle"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Character offsets in the edit overlay's DOM, counted the way `domToRuns`\n * reads its text: every text node's characters, plus one newline for each\n * break element a browser or a paste can leave behind.\n */\n\n/** One stretch of the overlay's text, in document order. */\nexport type OverlayPiece =\n | { text: Text }\n /** A newline with no text node of its own: a `<br>`, or the boundary a block opens. */\n | { br: Element }\n | { block: Element };\n\n/** Elements whose boundary reads as a newline. */\nexport const BLOCK_TAGS: ReadonlySet<string> = new Set(['DIV', 'P']);\n\n/**\n * `parent`'s text as pieces. A block (`<div>`, `<p>`) reads as a newline\n * before its contents unless it opens the text, which is how a browser renders\n * the boundary. Both offset walkers below read through here, and `domToRuns`\n * applies the same rule from `BLOCK_TAGS` in its own styled walk.\n */\nexport function overlayPieces(parent: Element): OverlayPiece[] {\n const out: OverlayPiece[] = [];\n const visit = (node: Node): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n if ((node as Text).data.length > 0) out.push({ text: node as Text });\n return;\n }\n if (!(node instanceof Element)) return;\n if (node.tagName === 'BR') { out.push({ br: node }); return; }\n if (BLOCK_TAGS.has(node.tagName) && out.length > 0) out.push({ block: node });\n for (const child of node.childNodes) visit(child);\n };\n for (const child of parent.childNodes) visit(child);\n return out;\n}\n\nconst indexIn = (el: Element): number => Array.prototype.indexOf.call(el.parentNode!.childNodes, el);\n\n/** The DOM position just past a break piece, where the next character goes. */\nfunction afterBreak(piece: { br: Element } | { block: Element }): { node: Node; offset: number } {\n return 'br' in piece\n ? { node: piece.br.parentNode!, offset: indexIn(piece.br) + 1 }\n : { node: piece.block, offset: 0 };\n}\n\n/**\n * The DOM position of plain-text character position `offset`: a text node\n * and an offset into it wherever one holds the position, otherwise an element\n * and a child index (just past a `<br>` that ends the text). Offsets beyond\n * the text clamp to its end. Returns `{ node: parent, offset: 0 }` for an\n * overlay with no text.\n */\nexport function charOffsetToDomPosition(\n parent: HTMLElement,\n offset: number,\n): { node: Node; offset: number } | null {\n let remaining = offset;\n let end: { node: Node; offset: number } = { node: parent, offset: 0 };\n /** Set while the position sits just past a break, with no text met since. */\n let pending: { node: Node; offset: number } | null = null;\n for (const piece of overlayPieces(parent)) {\n if ('text' in piece) {\n const len = piece.text.data.length;\n if (remaining <= len) return { node: piece.text, offset: remaining };\n remaining -= len;\n end = { node: piece.text, offset: len };\n pending = null;\n continue;\n }\n if (remaining === 0) {\n return pending ?? ('br' in piece\n ? { node: piece.br.parentNode!, offset: indexIn(piece.br) }\n : afterBreak(piece));\n }\n remaining -= 1;\n end = afterBreak(piece);\n pending = remaining === 0 ? end : null;\n }\n return end;\n}\n\n/**\n * Inverse of `charOffsetToDomPosition`: the characters that precede the DOM\n * position `(node, offset)`.\n *\n * When `node` is an element the DOM offset indexes *child nodes*, not\n * characters — `(overlay, 0)` is the start of the text and `(overlay,\n * childNodes.length)` its end. That shape is not exotic: `Range.\n * selectNodeContents`, which `useTextEdit` uses for its select-all caret,\n * produces exactly it. So an element position is resolved by counting the\n * pieces that end at or before the boundary point.\n */\nexport function domPositionToCharOffset(\n parent: HTMLElement,\n node: Node,\n offset: number,\n): number {\n const pieces = overlayPieces(parent);\n let total = 0;\n if (node.nodeType === Node.TEXT_NODE) {\n for (const piece of pieces) {\n if (!('text' in piece)) { total += 1; continue; }\n if (piece.text === node) return total + offset;\n total += piece.text.data.length;\n }\n return total;\n }\n const point = document.createRange();\n point.setStart(node, Math.max(0, Math.min(offset, node.childNodes.length)));\n point.collapse(true);\n for (const piece of pieces) {\n if ('text' in piece) {\n // A text node cannot contain the point, so it is wholly before or after.\n if (point.comparePoint(piece.text, 0) < 0) total += piece.text.data.length;\n } else {\n const past = afterBreak(piece);\n if (point.comparePoint(past.node, past.offset) <= 0) total += 1;\n }\n }\n return total;\n}\n","/**\n * A run's style as the overlay's DOM carries it: what an element and its\n * ancestors say, read into a `StyleState`, and a `StyledRun` built from one.\n */\n\nimport type { Fill, Stroke } from '@weasel-js/paint';\nimport type { FontVariantCaps, StyledRun, TextTransform } from '@weasel-js/text';\n\n/** Holds, as JSON, a run fill its span's CSS color cannot say: a gradient, a\n * pattern, or `null` for no fill. */\nexport const FILL_ATTR = 'data-fill';\n\n/** Holds, as JSON, a run's stroke, which the overlay does not draw. */\nexport const STROKE_ATTR = 'data-stroke';\n\n/** Holds a run's glyph turn in degrees, which CSS has no per-glyph spelling for. */\nexport const ROTATE_ATTR = 'data-rotate';\n\nexport interface StyleState {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n overline: boolean;\n fontWeight?: number;\n fontSize?: number;\n fontFamily?: string;\n color?: string;\n /** `FILL_ATTR`'s value, which wins over `color`. */\n fillJson?: string;\n /** `STROKE_ATTR`'s value. */\n strokeJson?: string;\n rotate?: number;\n letterSpacing?: number;\n script?: 'super' | 'sub';\n baselineShift?: number;\n fontScale?: number;\n textTransform?: TextTransform;\n fontVariantCaps?: FontVariantCaps;\n lang?: string;\n}\n\nexport const TRANSFORMS: ReadonlySet<string> = new Set(['none', 'uppercase', 'lowercase', 'capitalize']);\n\nexport const EMPTY_STYLE: StyleState = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n overline: false,\n};\n\n/**\n * Parse a CSS `letter-spacing` value into world units. Pasted markup can carry\n * a unit other than `px`; it is read as its bare number and flagged, since\n * `0.1em` becomes `0.1` world units, off by a factor of the font size.\n */\nfunction parseLetterSpacing(raw: string): number | undefined {\n const n = parseFloat(raw);\n if (!Number.isFinite(n)) return undefined;\n const unit = /^-?[\\d.]+([a-z%]+)$/i.exec(raw.trim())?.[1]?.toLowerCase();\n if (unit && unit !== 'px') {\n console.warn(\n `weasel domRuns: letter-spacing \"${raw}\" uses unit \"${unit}\", which is not converted; treated as ${n} world units`,\n );\n }\n return n;\n}\n\n/** A small-caps piece is presentation `runsToDom` split a run into, not styling. */\nexport const isSmallCapsPiece = (el: Element): boolean => el.hasAttribute('data-small-caps');\n\n/** The element's own `font-variant`, from the shorthand or the caps longhand\n * pasted markup may carry alone. */\nexport function cssFontVariant(el: HTMLElement): FontVariantCaps | undefined {\n const v = el.style.fontVariant || el.style.getPropertyValue('font-variant-caps');\n return v === 'small-caps' || v === 'normal' ? v : undefined;\n}\n\n/** `el`'s `name` attribute where it holds JSON. Pasted markup can carry\n * anything there, and `toRun` parses it. */\nfunction jsonAttr(el: Element, name: string): string | undefined {\n const raw = el.getAttribute(name);\n if (raw == null) return undefined;\n try {\n JSON.parse(raw);\n return raw;\n } catch {\n return undefined;\n }\n}\n\nexport function styleStateFromElement(el: Element, parent: StyleState): StyleState {\n if (isSmallCapsPiece(el)) return parent;\n const next: StyleState = { ...parent };\n const tag = el.tagName;\n if (tag === 'B' || tag === 'STRONG') {\n next.bold = true;\n next.fontWeight = undefined;\n }\n if (tag === 'I' || tag === 'EM') next.italic = true;\n // `runsToDom` never emits these, but a browser contenteditable can: Cmd+U\n // runs the native `underline` command, which produces `<u>` in Chrome.\n if (tag === 'U') next.underline = true;\n if (tag === 'S' || tag === 'STRIKE' || tag === 'DEL') next.strikethrough = true;\n if (tag === 'SUP') next.script = 'super';\n if (tag === 'SUB') next.script = 'sub';\n if (el instanceof HTMLElement) {\n // 700 and 400 are the bold flag on and off, which is what pasted markup\n // means by them. A run's own weight is written with an attribute beside\n // the CSS, so a stored 400 or 700 comes back as the weight it was.\n const fw = el.style.fontWeight;\n const ownWeight = Number(el.getAttribute('data-font-weight') ?? fw);\n if (el.hasAttribute('data-font-weight') || !['', '700', 'bold', '400', 'normal'].includes(fw)) {\n if (Number.isFinite(ownWeight) && ownWeight > 0) {\n next.fontWeight = ownWeight;\n next.bold = false;\n }\n } else if (fw !== '') {\n next.bold = fw === '700' || fw === 'bold';\n next.fontWeight = undefined;\n }\n const fs = el.style.fontStyle;\n if (fs === 'italic') next.italic = true;\n if (fs === 'normal') next.italic = false;\n // `text-decoration` does not inherit, it *propagates*, and a descendant\n // cannot cancel what an ancestor drew — so OR the flags in rather than\n // overwriting, and an explicit `none` cancels nothing.\n //\n // A declaration block carrying only the longhand serializes the shorthand\n // as `''`, so fall back to `text-decoration-line`.\n const td = el.style.textDecoration || el.style.textDecorationLine;\n if (td && !td.includes('none')) {\n next.underline ||= td.includes('underline');\n next.strikethrough ||= td.includes('line-through');\n next.overline ||= td.includes('overline');\n }\n // A percentage is `fontScale`; any other unit is an absolute size.\n if (el.style.fontSize) {\n const size = parseFloat(el.style.fontSize);\n if (Number.isFinite(size)) {\n if (el.style.fontSize.trim().endsWith('%')) next.fontScale = size / 100;\n else next.fontSize = size;\n }\n }\n const va = el.style.verticalAlign;\n if (va === 'super' || va === 'sub') next.script = va === 'super' ? 'super' : 'sub';\n if (va === 'baseline') next.script = undefined;\n const rawShift = el.getAttribute('data-baseline-shift');\n if (rawShift != null) {\n const shift = parseFloat(rawShift);\n if (Number.isFinite(shift)) next.baselineShift = shift;\n }\n const tt = el.style.textTransform;\n if (TRANSFORMS.has(tt)) next.textTransform = tt as TextTransform;\n const fv = cssFontVariant(el);\n if (fv) next.fontVariantCaps = fv;\n // Empty states the language is unknown, which the run model reads as none.\n if (el.hasAttribute('lang')) next.lang = el.lang || undefined;\n // The attribute holds the run's family; the CSS holds the face it maps to.\n const family = el.getAttribute('data-font-family') ?? el.style.fontFamily;\n if (family) next.fontFamily = family;\n const strokeJson = jsonAttr(el, STROKE_ATTR);\n if (strokeJson !== undefined) next.strokeJson = strokeJson;\n const rotate = parseFloat(el.getAttribute(ROTATE_ATTR) ?? '');\n if (Number.isFinite(rotate)) next.rotate = rotate;\n const fillJson = jsonAttr(el, FILL_ATTR);\n if (fillJson !== undefined) {\n next.fillJson = fillJson;\n next.color = undefined;\n } else if (el.style.color) {\n next.color = el.style.color;\n next.fillJson = undefined;\n }\n const ls = el.style.letterSpacing;\n if (ls === 'normal') {\n next.letterSpacing = undefined;\n } else if (ls) {\n const px = parseLetterSpacing(ls);\n if (px != null) next.letterSpacing = px;\n }\n }\n return next;\n}\n\nexport function styleEquals(a: StyleState, b: StyleState): boolean {\n return (\n a.bold === b.bold &&\n a.italic === b.italic &&\n a.underline === b.underline &&\n a.strikethrough === b.strikethrough &&\n a.overline === b.overline &&\n a.fontWeight === b.fontWeight &&\n a.fontSize === b.fontSize &&\n a.fontFamily === b.fontFamily &&\n a.color === b.color &&\n a.fillJson === b.fillJson &&\n a.strokeJson === b.strokeJson &&\n a.rotate === b.rotate &&\n a.letterSpacing === b.letterSpacing &&\n a.script === b.script &&\n a.baselineShift === b.baselineShift &&\n a.fontScale === b.fontScale &&\n a.textTransform === b.textTransform &&\n a.fontVariantCaps === b.fontVariantCaps &&\n a.lang === b.lang\n );\n}\n\nexport function toRun(text: string, style: StyleState): StyledRun {\n const run: StyledRun = { text };\n if (style.bold) run.bold = true;\n if (style.italic) run.italic = true;\n if (style.fontWeight != null) run.fontWeight = style.fontWeight;\n if (style.fontSize != null) run.fontSize = style.fontSize;\n if (style.fontFamily != null) run.fontFamily = style.fontFamily;\n if (style.fillJson !== undefined) run.fill = JSON.parse(style.fillJson) as Fill | null;\n else if (style.color != null) run.fill = { paint: { kind: 'solid', color: style.color } };\n if (style.strokeJson !== undefined) run.stroke = JSON.parse(style.strokeJson) as Stroke;\n if (style.rotate != null) run.rotate = style.rotate;\n // `letterSpacing: 0` is a meaningful override (it cancels node-level\n // tracking for this run), so test for presence, not truthiness.\n if (style.letterSpacing != null) run.letterSpacing = style.letterSpacing;\n // Run-level flags are additive over the node style — a run cannot un-set\n // one — so an undecorated run gets an absent key, never `false`.\n if (style.underline) run.underline = true;\n if (style.strikethrough) run.strikethrough = true;\n if (style.overline) run.overline = true;\n if (style.script != null) run.script = style.script;\n // Both are meaningful at values that test falsy — a 0 shift cancels an\n // inherited script's rise — so test for presence, as `letterSpacing` does.\n if (style.baselineShift != null) run.baselineShift = style.baselineShift;\n if (style.fontScale != null) run.fontScale = style.fontScale;\n if (style.textTransform != null) run.textTransform = style.textTransform;\n if (style.fontVariantCaps != null) run.fontVariantCaps = style.fontVariantCaps;\n if (style.lang) run.lang = style.lang;\n return run;\n}\n\n","/**\n * DOM ↔ `StyledRun[]` serializers for the contenteditable overlay: a flat\n * sequence of `<span data-run>` elements, one per run. The browser breaks at\n * `\\n` and at no other UAX #14 hard break, so each of those is written as a\n * `<span data-break>` holding a `\\n` in its place — one character for one,\n * which keeps DOM offsets equal to source offsets.\n *\n * A small-caps run's lowercase letters sit in `<span data-small-caps>` pieces,\n * uppercased and sized at the scale the canvas draws them with, since a\n * browser's own synthesis uses a fixed factor of its own.\n */\n\nimport { isSolidPaint, type Paint } from '@weasel-js/paint';\nimport {\n DEFAULT_TEXT_STYLE, isHardLineBreak, numericWeight, smallCapsScaleFor, smallCapsText, transformRunTexts,\n SMALL_CAPS_SCALE,\n type FontVariantCaps, type ResolvedTextStyle, type StyledRun, type TextTransform,\n} from '@weasel-js/text';\nimport { cssFontFamily } from '@weasel-js/font';\nimport { BLOCK_TAGS } from './domOffsets';\nimport {\n cssFontVariant, EMPTY_STYLE, FILL_ATTR, isSmallCapsPiece, ROTATE_ATTR, STROKE_ATTR, styleEquals,\n styleStateFromElement, toRun, TRANSFORMS, type StyleState,\n} from './runStyle';\n\nexport { charOffsetToDomPosition, domPositionToCharOffset } from './domOffsets';\n\nfunction solidColor(p: Paint | null | undefined): string | null {\n if (!p) return null;\n if (isSolidPaint(p)) return p.color;\n return null;\n}\n\nconst BREAK_ATTR = 'data-break';\n\n/** A break stand-in's source text: its hard break, and anything typed into it after. */\nfunction restoreBreak(el: Element): string {\n const text = el.textContent ?? '';\n const code = parseInt(el.getAttribute(BREAK_ATTR) ?? '', 16);\n return text.startsWith('\\n') && Number.isFinite(code) ? String.fromCharCode(code) + text.slice(1) : text;\n}\n\n/**\n * Append `text` to `parent` as the overlay sets it: a hard break the browser\n * would not break at becomes a `<span data-break>` holding a `\\n`, carrying\n * the original's code as hex. A CR that opens a CRLF is left as it is — the\n * LF breaks, and the CR draws nothing.\n */\nexport function appendOverlayText(parent: Node, text: string): void {\n let from = 0;\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i);\n if (c === 10 || !isHardLineBreak(c) || (c === 13 && text.charCodeAt(i + 1) === 10)) continue;\n if (i > from) parent.appendChild(document.createTextNode(text.slice(from, i)));\n const span = document.createElement('span');\n span.setAttribute(BREAK_ATTR, c.toString(16));\n span.textContent = '\\n';\n parent.appendChild(span);\n from = i + 1;\n }\n if (from < text.length) parent.appendChild(document.createTextNode(text.slice(from)));\n}\n\n/** Walk an overlay tree and emit a coalesced `StyledRun[]`. */\nexport function domToRuns(parent: HTMLElement): StyledRun[] {\n const fragments: Array<{ text: string; style: StyleState }> = [];\n\n function visit(node: Node, style: StyleState): void {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = (node as Text).data;\n if (text.length > 0) fragments.push({ text, style });\n return;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as Element;\n if (el.tagName === 'BR') {\n fragments.push({ text: '\\n', style });\n return;\n }\n if (el.hasAttribute(BREAK_ATTR)) {\n const restored = restoreBreak(el);\n if (restored.length > 0) fragments.push({ text: restored, style });\n return;\n }\n if (BLOCK_TAGS.has(el.tagName) && fragments.length > 0) {\n fragments.push({ text: '\\n', style });\n }\n const nextStyle = styleStateFromElement(el, style);\n for (const child of Array.from(el.childNodes)) {\n visit(child, nextStyle);\n }\n }\n\n for (const child of Array.from(parent.childNodes)) {\n visit(child, EMPTY_STYLE);\n }\n\n const runs: StyledRun[] = [];\n let i = 0;\n while (i < fragments.length) {\n let j = i + 1;\n while (j < fragments.length && styleEquals(fragments[i].style, fragments[j].style)) {\n j++;\n }\n const merged = fragments.slice(i, j).map((f) => f.text).join('');\n runs.push(toRun(merged, fragments[i].style));\n i = j;\n }\n return runs;\n}\n\n/** What a run inherits from its node, for the overlay's small caps: which\n * runs have it, and the face and transform that decide their pieces. */\nexport type OverlayRunBase = Pick<\n ResolvedTextStyle, 'fontFamily' | 'fontWeight' | 'fontStyle' | 'textTransform' | 'fontVariantCaps' | 'lang'\n>;\n\n/** The custom property carrying a small-caps run's scale down to its pieces. */\nexport const SMALL_CAPS_SCALE_PROPERTY = '--weasel-small-caps';\n\n/** A run's source text cut where small caps changes size, per `smallCapsText`\n * over the text as `transform` draws it. */\nfunction smallCapsPieces(\n text: string, transform: TextTransform, lang: string | undefined,\n): Array<{ text: string; small: boolean }> {\n const [shown] = transformRunTexts([text], [transform], [lang]);\n const caps = smallCapsText(shown.text, shown.srcMap, lang);\n const small = new Array<boolean>(text.length).fill(false);\n caps.small?.forEach((s, i) => {\n if (s) small[caps.srcMap ? caps.srcMap.starts[i] : i] = true;\n });\n const out: Array<{ text: string; small: boolean }> = [];\n let at = 0;\n for (const ch of text) {\n const last = out[out.length - 1];\n if (last && last.small === small[at]) last.text += ch;\n else out.push({ text: ch, small: small[at] });\n at += ch.length;\n }\n return out;\n}\n\n/** Replace `span`'s children with `text`, its small-caps letters in pieces. */\nfunction writeSmallCaps(span: HTMLElement, text: string, transform: TextTransform, lang: string | undefined): void {\n span.replaceChildren();\n for (const p of smallCapsPieces(text, transform, lang)) {\n if (!p.small) { appendOverlayText(span, p.text); continue; }\n const piece = document.createElement('span');\n piece.setAttribute('data-small-caps', '');\n piece.style.fontSize = `calc(var(${SMALL_CAPS_SCALE_PROPERTY}, ${SMALL_CAPS_SCALE}) * 1em)`;\n piece.style.textTransform = 'uppercase';\n piece.textContent = p.text;\n span.appendChild(piece);\n }\n}\n\n/**\n * Replace `parent`'s children with one `<span data-run>` per run. `base` is\n * the node's style, which a run inheriting small caps is split by.\n */\nexport function runsToDom(\n runs: readonly StyledRun[],\n parent: HTMLElement,\n base: OverlayRunBase = DEFAULT_TEXT_STYLE,\n): void {\n parent.replaceChildren();\n for (const run of runs) {\n const span = document.createElement('span');\n span.setAttribute('data-run', '');\n if ((run.fontVariantCaps ?? base.fontVariantCaps) === 'small-caps') {\n const scale = smallCapsScaleFor(\n run.fontFamily ?? base.fontFamily,\n run.fontWeight ?? (run.bold ? 700 : numericWeight(base.fontWeight)),\n run.italic ? 'italic' : base.fontStyle,\n );\n span.style.setProperty(SMALL_CAPS_SCALE_PROPERTY, String(scale));\n writeSmallCaps(span, run.text, run.textTransform ?? base.textTransform, run.lang ?? base.lang);\n } else {\n appendOverlayText(span, run.text);\n }\n // CSS as well as the pieces: it is what pasted markup says, and it gives a\n // letter typed outside a piece a small cap until the next normalize.\n if (run.fontVariantCaps != null) span.style.fontVariant = run.fontVariantCaps;\n if (run.fontWeight != null) {\n span.style.fontWeight = String(run.fontWeight);\n span.setAttribute('data-font-weight', String(run.fontWeight));\n } else if (run.bold) span.style.fontWeight = '700';\n if (run.italic) span.style.fontStyle = 'italic';\n // An absolute size wins over a relative one, as it does in `resolveRuns`.\n if (run.fontSize != null) span.style.fontSize = `${run.fontSize}px`;\n else if (run.fontScale != null) span.style.fontSize = `${run.fontScale * 100}%`;\n if (run.fontFamily != null) {\n span.style.fontFamily = cssFontFamily(run.fontFamily, {\n weight: run.fontWeight ?? (run.bold ? 700 : undefined),\n style: run.italic ? 'italic' : undefined,\n });\n span.setAttribute('data-font-family', run.fontFamily);\n }\n const color = solidColor(run.fill?.paint);\n if (color != null) span.style.color = color;\n else if (run.fill !== undefined) span.setAttribute(FILL_ATTR, JSON.stringify(run.fill));\n // Black, as an unfilled node edits in: no CSS color leaves it legible.\n if (run.fill === null) span.style.color = '#000';\n if (run.stroke !== undefined) span.setAttribute(STROKE_ATTR, JSON.stringify(run.stroke));\n if (run.rotate != null) span.setAttribute(ROTATE_ATTR, String(run.rotate));\n if (run.lang) span.lang = run.lang;\n // Decoration goes on the span as an inline style rather than `<u>`/`<s>`\n // wrappers: one representation for `domToRuns` to unwrap, and one element\n // per run so the caret-offset walkers stay flat.\n const decorations: string[] = [];\n if (run.underline) decorations.push('underline');\n if (run.strikethrough) decorations.push('line-through');\n if (run.overline) decorations.push('overline');\n if (decorations.length > 0) span.style.textDecoration = decorations.join(' ');\n if (run.script != null) span.style.verticalAlign = run.script;\n // No CSS spelling: `vertical-align` takes a length or a percentage of the\n // *line height*, and this is a fraction of the parent's font size.\n if (run.baselineShift != null) {\n span.setAttribute('data-baseline-shift', String(run.baselineShift));\n }\n // World units — the overlay's own node-level tracking is screen-scaled,\n // but a run override is stored as-is so the round-trip is lossless.\n if (run.letterSpacing != null) span.style.letterSpacing = `${run.letterSpacing}px`;\n // CSS draws the transform, so the span's text stays the source and the\n // caret-offset walkers below need no map.\n if (run.textTransform != null) span.style.textTransform = run.textTransform;\n parent.appendChild(span);\n }\n}\n\n/** `el`'s text as `domToRuns` reads it: each break stand-in restored. */\nfunction sourceText(el: Element): string {\n let out = '';\n for (const n of el.childNodes) {\n if (n.nodeType === Node.TEXT_NODE) out += (n as Text).data;\n else if (n instanceof Element) out += n.hasAttribute(BREAK_ATTR) ? restoreBreak(n) : sourceText(n);\n }\n return out;\n}\n\n/** Whether `span`'s children are the pieces `writeSmallCaps` would write. */\nfunction piecesMatch(span: HTMLElement, transform: TextTransform, lang: string | undefined): boolean {\n const want = smallCapsPieces(sourceText(span), transform, lang);\n const have: Array<{ text: string; small: boolean }> = [];\n for (const n of span.childNodes) {\n let small: boolean;\n let text: string;\n if (n.nodeType === Node.TEXT_NODE) { small = false; text = (n as Text).data; }\n else if (n instanceof HTMLElement && n.hasAttribute(BREAK_ATTR)) { small = false; text = restoreBreak(n); }\n else if (n instanceof HTMLElement && isSmallCapsPiece(n) && n.children.length === 0) { small = true; text = n.textContent ?? ''; }\n else return false;\n if (text.length === 0) continue;\n const last = have[have.length - 1];\n if (last && last.small === small) last.text += text;\n else have.push({ text, small });\n }\n return want.length === have.length\n && want.every((p, i) => p.text === have[i].text && p.small === have[i].small);\n}\n\n/**\n * Put every run span's small-caps pieces back where its text now needs them.\n * Returns whether anything was rewritten, which moves the DOM selection: the\n * caller restores it by character offset.\n */\nexport function normalizeSmallCaps(parent: HTMLElement): boolean {\n let changed = false;\n const visit = (\n el: HTMLElement, variant: FontVariantCaps, transform: TextTransform, inherited: string | undefined,\n ): void => {\n const v = cssFontVariant(el) ?? variant;\n const tt = el.style.textTransform;\n const t = TRANSFORMS.has(tt) ? (tt as TextTransform) : transform;\n const lang = el.hasAttribute('lang') ? el.lang || undefined : inherited;\n if (el.hasAttribute('data-run')) {\n if (v === 'small-caps') {\n if (!piecesMatch(el, t, lang)) { writeSmallCaps(el, sourceText(el), t, lang); changed = true; }\n } else if (el.querySelector('[data-small-caps]')) {\n const text = sourceText(el);\n el.replaceChildren();\n appendOverlayText(el, text);\n changed = true;\n }\n return;\n }\n for (const child of el.children) if (child instanceof HTMLElement) visit(child, v, t, lang);\n };\n visit(parent, 'normal', 'none', undefined);\n return changed;\n}\n","/**\n * The edit overlay's reading direction, alignment, and tab stops, set so the\n * browser resolves them the way `layoutRuns` does for the canvas.\n */\nimport { paragraphDirection, resolveAlign, type ResolvedTextStyle } from '@weasel-js/text';\n\n/**\n * A stated direction goes on the overlay as CSS `direction`. `auto` becomes\n * `unicode-bidi: plaintext`, CSS's spelling of \"each paragraph reads the way\n * its first strong character does\", under which `start` and `end` follow each\n * paragraph too, so those are left for the browser to resolve.\n */\nexport function applyOverlayDirection(el: HTMLElement, style: ResolvedTextStyle): void {\n const auto = style.direction === 'auto';\n el.style.direction = auto ? '' : style.direction;\n el.style.setProperty('unicode-bidi', auto ? 'plaintext' : '');\n el.style.setProperty('tab-size', String(style.tabSize));\n const justify = style.align === 'justify';\n const edge = style.direction === 'auto'\n ? (justify ? 'start' : style.align)\n : resolveAlign(style.align, style.direction);\n el.style.textAlign = justify ? 'justify' : edge;\n // Pinned, so a justified paragraph's last line sits where the canvas puts it.\n el.style.setProperty('text-align-last', justify ? edge : '');\n}\n\n/** The absolute edge the overlay's text is set from, by its first paragraph. */\nexport function overlayAlignEdge(el: HTMLElement, style: ResolvedTextStyle): 'left' | 'center' | 'right' {\n return resolveAlign(style.align, paragraphDirection(el.textContent ?? '', style.direction));\n}\n","/**\n * What the overlay holds, as a node takes it — what a commit writes, and what\n * each keystroke or restyle reports as a draft — and handing it to the host:\n * a draft when it changed, a commit through the host's options.\n */\nimport { runsCarryStyling, runsToPlainText, type StyledRun, type TextStyle } from '@weasel-js/text';\nimport type { CaretHolder } from './overlaySeed';\nimport type { TextEditCommit, TextEditDraft, UseTextEditOptions } from './textEditTypes';\n\n/**\n * `read` — the overlay's runs as `domToRuns` gives them — less its caret\n * holder, as text, with the runs when they are in play: the node had some, or\n * the edit produced styling. A plain-text edit of a plain-text node is text alone.\n * `style`, the node style the edit rewrote, rides along where there is one.\n */\nexport function overlayDraft(\n read: StyledRun[],\n holder: CaretHolder | null,\n priorRuns: readonly StyledRun[] | undefined,\n style: TextStyle | null = null,\n): TextEditCommit {\n const runs = holder?.trim(read) ?? read;\n const inPlay = (priorRuns != null && priorRuns.length > 0) || runsCarryStyling(runs);\n // Read from the DOM, not `innerText`: a browser applies `text-transform`\n // to what that reports, and a break stand-in reads back as its `\\n`.\n const text = runsToPlainText(runs);\n return { text, ...(inPlay ? { runs } : {}), ...(style ? { style } : {}) };\n}\n\n/** Whether `draft` differs from the one `sent` holds as JSON, taking it as the one sent when it does. */\nexport function draftChanged(sent: { current: string }, draft: TextEditDraft): boolean {\n const json = JSON.stringify(draft);\n if (json === sent.current) return false;\n sent.current = json;\n return true;\n}\n\n/** Write a finished edit through `opts`: its `commit` where there is one, else each setter it has. */\nexport function writeEdit(\n opts: Pick<UseTextEditOptions, 'commit' | 'setRuns' | 'setStyle' | 'setText'>,\n id: string,\n edit: TextEditCommit,\n): void {\n if (opts.commit) return opts.commit(id, edit);\n if (edit.style) opts.setStyle?.(id, edit.style);\n opts.setText?.(id, edit.text);\n if (opts.setRuns && edit.runs) opts.setRuns(id, edit.runs);\n}\n","import { verticalAlignOffset } from '@weasel-js/text';\nimport type { TextEditScreenPose } from './textEditTypes';\n\n/**\n * The overlay's CSS `transform`, for an origin of `0 0`: the pose's `zoom`,\n * its `frame` about the box center, and the pull back by `anchor` of the\n * overlay's own width that aligns an unwrapped line. `left` and `top` are\n * where the overlay's origin sits before any of it, in container pixels.\n */\nexport function overlayTransform(pose: TextEditScreenPose, left: number, top: number, anchor: number): string {\n const zoom = pose.zoom ?? 1;\n const parts: string[] = [];\n if (pose.frame) {\n const [a, b, c, d] = pose.frame;\n // The origin's offset from the box center, which the frame turns with\n // everything else.\n const dx = left - (pose.x + (pose.width * zoom) / 2);\n const dy = top - (pose.y + (pose.height * zoom) / 2);\n const m = [a * zoom, b * zoom, c * zoom, d * zoom, (a - 1) * dx + c * dy, b * dx + (d - 1) * dy];\n parts.push(`matrix(${m.join(', ')})`);\n } else if (zoom !== 1) {\n parts.push(`scale(${zoom})`);\n }\n if (anchor !== 0) parts.push(`translateX(${-anchor * 100}%)`);\n return parts.length > 0 ? parts.join(' ') : 'none';\n}\n\n/**\n * The overlay's `clip-path`: the pose box grown by `clip`, in the overlay's\n * own pre-transform pixels, so its transform carries the cut with the text.\n * The box's corner sits at the overlay's origin less the pull back by\n * `anchor` of its width, and pose units are its pixels.\n */\nexport function overlayClipPath(\n el: HTMLElement,\n pose: TextEditScreenPose,\n left: number,\n top: number,\n anchor: number,\n clip: NonNullable<TextEditScreenPose['clip']>,\n): string {\n const zoom = pose.zoom ?? 1;\n const x0 = (pose.x - left) / zoom + anchor * el.offsetWidth - clip.left;\n const y0 = (pose.y - top) / zoom - clip.top;\n const x1 = x0 + clip.left + pose.width + clip.right;\n const y1 = y0 + clip.top + pose.height + clip.bottom;\n return `polygon(${x0}px ${y0}px, ${x1}px ${y0}px, ${x1}px ${y1}px, ${x0}px ${y1}px)`;\n}\n\n/**\n * The overlay's `top`, in container pixels, for content `contentHeight` tall\n * (pre-scale, like the rest of `pose`): the pose's top, shifted by the same\n * `verticalAlign` slack the canvas applies, plus `drop` — how far below the\n * CSS line's baseline the canvas puts its own, from {@link baselineDrop}.\n * @internal\n */\nexport function overlayTop(pose: TextEditScreenPose, contentHeight: number, drop = 0): number {\n const slack = verticalAlignOffset(pose.verticalAlign, pose.height, contentHeight);\n return pose.y + (slack + drop) * (pose.zoom ?? 1);\n}\n","import { isSolidPaint } from '@weasel-js/paint';\nimport { cssFontFamily, isCanvasFont } from '@weasel-js/font';\nimport { fontString, numericWeight, smallCapsScaleFor, type ResolvedTextStyle } from '@weasel-js/text';\nimport { SMALL_CAPS_SCALE_PROPERTY } from './domRuns';\nimport { applyOverlayDirection } from './overlayDirection';\n\n/** Dress the edit overlay in the node's resolved style, so it looks like the\n * canvas the moment editing starts. */\nexport function applyOverlayStyle(el: HTMLDivElement, style: ResolvedTextStyle): void {\n el.style.position = 'absolute';\n el.style.pointerEvents = 'auto';\n el.style.boxSizing = 'border-box';\n el.style.margin = '0';\n el.style.padding = '0';\n el.style.border = '0';\n el.style.outline = 'none';\n el.style.background = 'transparent';\n // Unfilled text still edits in black: the overlay has to be legible, and\n // there is no CSS spelling of \"no fill\" that leaves the glyphs visible.\n const paint = style.fill?.paint;\n el.style.color = isSolidPaint(paint) ? paint.color : '#000';\n el.style.caretColor = style.caretColor;\n // The canvas's face, not the browser's reading of the family name.\n const fontFamily = cssFontFamily(style.fontFamily, {\n weight: numericWeight(style.fontWeight), style: style.fontStyle,\n });\n el.style.font = fontString({ ...style, fontFamily });\n // Linux Chromium otherwise rounds every advance to a whole pixel at DPR 1, while\n // the canvas lays out a face's own fractional ones: 'Small Caps' at 24px ran 3px\n // long. A canvas font is measured by the browser's default rendering, so keeps it.\n el.style.textRendering = isCanvasFont(style.fontFamily) ? '' : 'geometricPrecision';\n el.style.lineHeight = String(style.lineHeight);\n applyOverlayDirection(el, style);\n // The browser's CSS `text-transform` and its spell checker read it.\n if (style.lang) el.lang = style.lang;\n else el.removeAttribute('lang');\n const decorations: string[] = [];\n if (style.underline) decorations.push('underline');\n if (style.strikethrough) decorations.push('line-through');\n if (style.overline) decorations.push('overline');\n el.style.textDecoration = decorations.length > 0 ? decorations.join(' ') : 'none';\n el.style.textTransform = style.textTransform;\n // The CSS spelling for what a browser reads; the scale for the pieces\n // `runsToDom` splits inheriting runs into, so they match the canvas.\n el.style.fontVariant = style.fontVariantCaps;\n el.style.setProperty(\n SMALL_CAPS_SCALE_PROPERTY,\n style.fontVariantCaps === 'small-caps'\n ? String(smallCapsScaleFor(style.fontFamily, numericWeight(style.fontWeight), style.fontStyle))\n : '',\n );\n // Line breaks follow the node's declared `wrap`, as the canvas's do. Layout\n // breaks only between words, never inside one.\n el.style.whiteSpace = style.wrap ? 'pre-wrap' : 'pre';\n el.style.overflowWrap = 'normal';\n el.style.wordBreak = 'normal';\n}\n","/**\n * What the edit overlay holds when an edit opens, and the one character it can\n * come to hold that is not the node's text.\n *\n * A browser draws no empty last line for text that ends in a line break, so\n * when an edit leaves the caret on one it keeps a second newline there: the\n * caret holder, which reading the text back drops. Text seeded already ending\n * in a break is different. The canvas draws no last line for it either, and\n * Chromium takes the break that is there as the holder and adds none, so that\n * newline is the node's own and stays until an edit removes it.\n */\n\nimport { isHardLineBreak, runsToPlainText, type StyledRun } from '@weasel-js/text';\nimport { appendOverlayText, domToRuns, runsToDom, type OverlayRunBase } from './domRuns';\n\nconst endsInBreak = (text: string): boolean =>\n text.length > 0 && isHardLineBreak(text.charCodeAt(text.length - 1));\n\n/** Which trailing newline of an overlay's text, if any, is the browser's. */\nexport interface CaretHolder {\n /** Call after anything that edits the overlay's text. */\n edited(overlay: HTMLElement): void;\n /** `runs` as read from the overlay, without the holder. */\n trim(runs: StyledRun[]): StyledRun[];\n}\n\n/**\n * Fill `overlay` with a node's text: its runs when it has any, one run when\n * small caps needs its lowercase in pieces only a run span holds, and bare text\n * otherwise.\n */\nexport function seedOverlay(\n overlay: HTMLElement,\n text: string,\n runs: readonly StyledRun[] | undefined,\n base: OverlayRunBase,\n): CaretHolder {\n const styled = runs !== undefined && runs.length > 0;\n if (styled) runsToDom(runs, overlay, base);\n else if (base.fontVariantCaps === 'small-caps') runsToDom([{ text }], overlay, base);\n // Not `innerText`, which turns each newline into a `<br>` the caret\n // walkers cannot count and U+2028 into a space.\n else appendOverlayText(overlay, text);\n\n let ownBreak = endsInBreak(styled ? runsToPlainText(runs) : text);\n return {\n edited(el) {\n if (ownBreak && !endsInBreak(runsToPlainText(domToRuns(el)))) ownBreak = false;\n },\n trim: (read) => (ownBreak ? read : trimCaretHolder(read)),\n };\n}\n\n/** An empty run left behind is dropped: it would answer `runsCarryStyling` by existing. */\nfunction trimCaretHolder(runs: StyledRun[]): StyledRun[] {\n const last = runs[runs.length - 1];\n if (last === undefined || !last.text.endsWith('\\n')) return runs;\n const trimmed = { ...last, text: last.text.slice(0, -1) };\n const head = runs.slice(0, -1);\n return trimmed.text === '' ? head : [...head, trimmed];\n}\n","/** The DOM selection inside the edit overlay, as character offsets and back, and handing focus back to the overlay. */\n\nimport type { StyledRun } from '@weasel-js/text';\nimport { charOffsetToDomPosition, domPositionToCharOffset, runsToDom, type OverlayRunBase } from './domRuns';\nimport type { TextEditSelection } from './textEditTypes';\n\n/**\n * Character offsets of the current DOM selection within `overlay`, or `null`\n * when there is no selection or it lies outside the overlay.\n */\nexport function readSelectionOffsets(overlay: HTMLElement): TextEditSelection | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const range = sel.getRangeAt(0);\n if (!overlay.contains(range.startContainer) || !overlay.contains(range.endContainer)) {\n return null;\n }\n // `Range` boundary points are already in document order, so this is the\n // normalization for a backwards drag — anchor/focus are not consulted.\n const start = domPositionToCharOffset(overlay, range.startContainer, range.startOffset);\n const end = domPositionToCharOffset(overlay, range.endContainer, range.endOffset);\n return start <= end ? { start, end } : { start: end, end: start };\n}\n\n/** Put the DOM selection on the characters `[start, end)` of `overlay`. */\nexport function selectOffsets(overlay: HTMLElement, start: number, end: number): void {\n const a = charOffsetToDomPosition(overlay, start);\n const b = charOffsetToDomPosition(overlay, end);\n const sel = window.getSelection();\n if (!a || !b || !sel) return;\n const range = document.createRange();\n range.setStart(a.node, a.offset);\n range.setEnd(b.node, b.offset);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/**\n * Replace the overlay's contents with `runs` and put the selection back on\n * `[start, end)`, which rewriting the DOM destroys.\n *\n * The selection is **not** restored while focus sits in a text-entry control.\n * Browsers route editing commands by selection rather than by focus, so with\n * the range restored, the Enter that commits a number field also runs\n * `insertParagraph` over it — replacing the text that was just styled with a\n * line break. (Observed in Chrome.) Focus on a *button* still restores:\n * buttons turn keystrokes into clicks, not into editing commands.\n */\nexport function writeRunsPreservingSelection(\n overlay: HTMLElement,\n runs: readonly StyledRun[],\n start: number,\n end: number,\n base: OverlayRunBase,\n): void {\n const active = document.activeElement;\n const inTextEntry =\n active !== overlay &&\n !overlay.contains(active) &&\n (active instanceof HTMLInputElement ||\n active instanceof HTMLTextAreaElement ||\n (active instanceof HTMLElement && active.isContentEditable));\n runsToDom(runs, overlay, base);\n if (!inTextEntry) selectOffsets(overlay, start, end);\n}\n\n/**\n * Return focus to the overlay after a styling arrived from editor chrome: a\n * control that took focus to be clicked still holds it when the patch lands,\n * so the next keystroke would go to that button.\n *\n * Two things are left holding focus deliberately: a text entry in the chrome\n * (the user is still typing a font size) and anything inside an open dialog,\n * which is where a color picker's live `onChange` fires from.\n */\nexport function restoreOverlayFocus(overlay: HTMLElement, range: TextEditSelection): void {\n const active = document.activeElement;\n if (active === overlay || overlay.contains(active)) return;\n if (\n active instanceof HTMLInputElement\n || active instanceof HTMLTextAreaElement\n || (active instanceof HTMLElement && active.isContentEditable)\n || (active instanceof Element && active.closest('[role=\"dialog\"]') !== null)\n ) return;\n overlay.focus();\n selectOffsets(overlay, range.start, range.end);\n}\n\n/** Whether two published ranges are the same, either being none. */\nexport function sameSelection(a: TextEditSelection | null, b: TextEditSelection | null): boolean {\n if (a === null || b === null) return a === b;\n return a.start === b.start && a.end === b.end;\n}\n","/**\n * Clipboard contents as runs. Pasted markup never reaches the overlay's DOM:\n * it is parsed apart from the page and read here, so whatever an application\n * put on the clipboard arrives as text with line breaks, tabs, and emphasis.\n *\n * Emphasis is all that is kept of its styling: bold, italic, the three rules,\n * and super- and subscript. A browser writes every copied element's computed\n * face, size, and color into the markup, the source page's defaults among\n * them, so those cannot be told from styling someone chose, and the pasted\n * text takes them from where it lands.\n */\n\nimport type { StyledRun } from '@weasel-js/text';\nimport { EMPTY_STYLE, styleStateFromElement, toRun, type StyleState } from './runStyle';\n\n/** Elements whose contents are not text a reader sees. */\nconst UNSEEN: ReadonlySet<string> = new Set([\n 'HEAD', 'IFRAME', 'NOSCRIPT', 'OBJECT', 'SCRIPT', 'STYLE', 'TEMPLATE', 'TITLE',\n]);\n\n/** Elements that start and end on a line of their own. */\nconst BLOCKS: ReadonlySet<string> = new Set([\n 'ADDRESS', 'ARTICLE', 'ASIDE', 'BLOCKQUOTE', 'CAPTION', 'DD', 'DETAILS', 'DIV', 'DL', 'DT', 'FIELDSET',\n 'FIGCAPTION', 'FIGURE', 'FOOTER', 'FORM', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER', 'HR', 'LI', 'MAIN',\n 'NAV', 'OL', 'P', 'PRE', 'SECTION', 'SUMMARY', 'TABLE', 'TR', 'UL',\n]);\n\nconst CELLS: ReadonlySet<string> = new Set(['TD', 'TH']);\n\n/** Whether `el` keeps its white space, given whether its parent does. */\nfunction keepsSpace(el: HTMLElement, inherited: boolean): boolean {\n const collapse = el.style.getPropertyValue('white-space-collapse');\n const ws = collapse || el.style.getPropertyValue('white-space');\n if (ws === '') return el.tagName === 'PRE' || inherited;\n return /^(pre|pre-wrap|break-spaces|preserve)\\b/.test(ws);\n}\n\n/** The run fields a paste keeps. A weight of 600 or more reads as bold. */\nfunction emphasis(text: string, style: StyleState): StyledRun {\n const read = toRun(text, style);\n const run: StyledRun = { text };\n if (read.bold || (read.fontWeight ?? 0) >= 600) run.bold = true;\n for (const key of ['italic', 'underline', 'strikethrough', 'overline'] as const) if (read[key]) run[key] = true;\n if (read.script) run.script = read.script;\n return run;\n}\n\n/**\n * The text of `html` as runs. A block opens and closes a line, a table cell\n * follows the one before it after a tab, and white space collapses as a\n * browser collapses it unless the markup says to keep it.\n */\nexport function htmlToRuns(html: string): StyledRun[] {\n const body = new DOMParser().parseFromString(html, 'text/html').body;\n const runs: StyledRun[] = [];\n /** What has to precede the next text: a line break a block boundary asked for, a tab between cells. */\n let gap = { line: false, tab: false };\n /** Whether the current line has text on it, and whether that text ends in a collapsed space. */\n let onLine = false;\n let spaced = false;\n\n const write = (text: string, style: StyleState): void => {\n const lead = (gap.line && runs.length > 0 ? '\\n' : '') + (gap.tab ? '\\t' : '');\n runs.push(emphasis(lead + text, style));\n gap = { line: false, tab: false };\n onLine = true;\n spaced = false;\n };\n /** A collapsed space that turned out to end its line draws nothing. */\n const trimSpace = (): void => {\n const last = runs[runs.length - 1];\n if (spaced && last) last.text = last.text.slice(0, -1);\n spaced = false;\n };\n const boundary = (): void => {\n trimSpace();\n gap = { line: gap.line || onLine, tab: false };\n onLine = false;\n };\n\n const visit = (node: Node, style: StyleState, keep: boolean): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n const data = (node as Text).data.replace(/\\r\\n?/g, '\\n');\n if (keep) { if (data.length > 0) write(data, style); return; }\n data.split(/[ \\t\\n\\f]+/).forEach((word, i) => {\n // The space goes in with the text node that held it, as a browser draws it.\n if (i > 0 && onLine && !spaced) { write(' ', style); spaced = true; }\n if (word.length > 0) write(word, style);\n });\n return;\n }\n if (!(node instanceof HTMLElement) || UNSEEN.has(node.tagName)) return;\n if (node.tagName === 'BR') {\n // Chrome ends a copied fragment with one that stands for no text.\n if (node.classList.contains('Apple-interchange-newline')) return;\n trimSpace();\n write('\\n', style);\n onLine = false;\n return;\n }\n const block = BLOCKS.has(node.tagName);\n if (block) boundary();\n if (CELLS.has(node.tagName) && node.previousElementSibling !== null) { trimSpace(); gap.tab = true; }\n const next = styleStateFromElement(node, style);\n const keeps = keepsSpace(node, keep);\n for (const child of node.childNodes) visit(child, next, keeps);\n if (block) boundary();\n };\n visit(body, EMPTY_STYLE, false);\n trimSpace();\n\n // Neighbors alike in what was kept, which differed only in what was not.\n const kept = (run: StyledRun): string => JSON.stringify({ ...run, text: '' });\n const merged: StyledRun[] = [];\n for (const run of runs) {\n const last = merged[merged.length - 1];\n if (run.text.length === 0) continue;\n if (last && kept(last) === kept(run)) last.text += run.text;\n else merged.push(run);\n }\n return merged;\n}\n\n/**\n * What a paste or a drop carries, as runs: its markup where it has any that\n * holds text, otherwise its plain text.\n */\nexport function clipboardRuns(data: DataTransfer): StyledRun[] {\n const html = data.getData('text/html');\n const fromHtml = html ? htmlToRuns(html) : [];\n if (fromHtml.length > 0) return fromHtml;\n const plain = data.getData('text/plain').replace(/\\r\\n/g, '\\n');\n return plain.length > 0 ? [{ text: plain }] : [];\n}\n","/** Text going into runs at a character range, for typing under an armed style and for a paste. */\n\nimport { applyStyleToRange, type RunStylePatch, type StyledRun } from '@weasel-js/text';\n\n/**\n * `runs` with the characters `[start, end)` replaced by `insert`, splitting\n * whichever runs span the two ends. The result is normalized (empty runs\n * dropped, identical neighbors merged) by the same algebra every other write\n * goes through.\n */\nexport function replaceRunRange(\n runs: readonly StyledRun[],\n start: number,\n end: number,\n insert: readonly StyledRun[],\n): StyledRun[] {\n const out: StyledRun[] = [];\n let pos = 0;\n let placed = false;\n const place = (): void => {\n if (!placed) out.push(...insert.map((r) => ({ ...r })));\n placed = true;\n };\n for (const r of runs) {\n const from = pos;\n pos += r.text.length;\n if (from < start) out.push({ ...r, text: r.text.slice(0, start - from) });\n if (pos >= start) place();\n if (pos > end) out.push({ ...r, text: r.text.slice(Math.max(0, end - from)) });\n }\n place();\n // An empty patch over an empty range: this is the array-wide normalization\n // pass, not a styling.\n return applyStyleToRange(out, 0, 0, {});\n}\n\n/**\n * The styling a character typed at offset `at` joins: the run to its left's,\n * or the first run's at the very start of the text.\n */\nexport function runStyleAt(runs: readonly StyledRun[], at: number): RunStylePatch {\n let pos = 0;\n let found: StyledRun | undefined = runs[0];\n for (const r of runs) {\n if (r.text.length === 0) continue;\n if (pos >= at && pos > 0) break;\n found = r;\n pos += r.text.length;\n }\n if (!found) return {};\n const style: Partial<StyledRun> = { ...found };\n delete style.text;\n return style;\n}\n","/**\n * Text entering the edit overlay. The browser inserts a typed character\n * itself, which keeps the keystroke on its undo stack and lets input that\n * names its own range (a text replacement, the double-space period) land\n * there. The hook inserts by hand only where the character has to open a run\n * of its own: under an armed style, and at a caret between two run spans.\n *\n * A paste or a drop is never the browser's to insert: it would land as\n * whatever markup the clipboard held. It is read into runs and written\n * through them.\n */\n\nimport { runsToPlainText, supersededKey, type RunStylePatch, type StyledRun } from '@weasel-js/text';\nimport { domPositionToCharOffset, domToRuns, normalizeSmallCaps, type OverlayRunBase } from './domRuns';\nimport { readSelectionOffsets, selectOffsets, writeRunsPreservingSelection } from './overlaySelection';\nimport { clipboardRuns } from './pasteRuns';\nimport { replaceRunRange, runStyleAt } from './runSplice';\nimport type { TextEditSelection } from './textEditTypes';\n\n/**\n * Put the caret *between* two run spans when `offset` falls on the boundary\n * of one, rather than at the same offset inside the left span's text node.\n * A caret inside a span has the next character absorbed by that run —\n * otherwise the character after a superscript is superscript too. Leaves the\n * selection alone when the offset falls mid-run.\n */\nfunction placeCaretBetweenRuns(overlay: HTMLElement, runs: readonly StyledRun[], offset: number): void {\n let acc = 0;\n let index = -1;\n for (let i = 0; i < runs.length; i++) {\n acc += runs[i].text.length;\n if (acc === offset) { index = i; break; }\n if (acc > offset) return;\n }\n const span = index >= 0 ? overlay.children[index] : null;\n const sel = window.getSelection();\n if (!span || !sel) return;\n const range = document.createRange();\n range.setStartAfter(span);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/** Put small-caps letters back in the pieces their case belongs in after\n * an edit, keeping the caret. Never mid-composition: rewriting the DOM\n * under an IME ends the composition. */\nfunction resplitSmallCaps(overlay: HTMLElement, e?: Event): void {\n if (e instanceof InputEvent && e.isComposing) return;\n const at = readSelectionOffsets(overlay);\n if (normalizeSmallCaps(overlay) && at) selectOffsets(overlay, at.start, at.end);\n}\n\n/** Whether `ie` names a range of its own to replace, apart from a collapsed caret. */\nfunction namesItsRange(ie: InputEvent, caret: Range): boolean {\n const target = ie.getTargetRanges?.()[0];\n return target !== undefined && caret.collapsed && !target.collapsed;\n}\n\n/** The characters `ie` replaces: the range it names, else the selection. */\nfunction replacedOffsets(overlay: HTMLElement, ie: InputEvent, host: TypingHost): TextEditSelection | null {\n const target = ie.getTargetRanges?.()[0];\n if (target && overlay.contains(target.startContainer) && overlay.contains(target.endContainer)) {\n const a = domPositionToCharOffset(overlay, target.startContainer, target.startOffset);\n const b = domPositionToCharOffset(overlay, target.endContainer, target.endOffset);\n return { start: Math.min(a, b), end: Math.max(a, b) };\n }\n return readSelectionOffsets(overlay) ?? host.lastRange();\n}\n\n/**\n * `pasted` styled for where it lands: the run it joins and any armed style\n * underneath, its own emphasis on top.\n */\nfunction styledForRange(\n pasted: readonly StyledRun[], runs: readonly StyledRun[], at: TextEditSelection, pending: RunStylePatch,\n): StyledRun[] {\n // Over a selection, the first character replaced; at a caret, the one before it.\n const base: Record<string, unknown> = { ...runStyleAt(runs, at.start === at.end ? at.start : at.start + 1) };\n for (const [key, value] of Object.entries(pending)) {\n if (value === undefined || value === false) delete base[key];\n else base[key] = value;\n }\n return pasted.map((run) => {\n const styled: Record<string, unknown> = { ...base, ...run };\n const superseded = supersededKey(run);\n if (superseded !== undefined) delete styled[superseded];\n return styled as unknown as StyledRun;\n });\n}\n\nconst PASTES: ReadonlySet<string> = new Set(['insertFromPaste', 'insertFromDrop']);\n\n/** What the typing handlers read from, and report to, the edit that owns the overlay. */\nexport interface TypingHost {\n /** The style armed for the next character; no keys when none is. */\n pending: () => RunStylePatch;\n /** The node style run spans are split by. */\n base: () => OverlayRunBase;\n /** The last range published inside the overlay, for when the DOM selection has left it. */\n lastRange: () => TextEditSelection | null;\n /** The runs were rewritten with new text in them, any armed style spent, and the caret now sits at `caret`. */\n onWritten: (caret: number) => void;\n /** The overlay's text changed, by the browser's hand or this module's. */\n onEdited: () => void;\n}\n\n/** The overlay's `beforeinput` and `input` listeners. */\nexport function typingHandlers(overlay: HTMLElement, host: TypingHost): {\n onBeforeInput: (ie: InputEvent) => void;\n onInput: (e: Event) => void;\n} {\n const edited = (e?: Event): void => {\n resplitSmallCaps(overlay, e);\n host.onEdited();\n };\n\n const onPaste = (ie: InputEvent): void => {\n // An engine that hands the event no data inserts for itself.\n const at = ie.dataTransfer ? replacedOffsets(overlay, ie, host) : null;\n if (!ie.dataTransfer || !at) return;\n ie.preventDefault();\n const pasted = clipboardRuns(ie.dataTransfer);\n if (pasted.length === 0) return;\n const runs = domToRuns(overlay);\n const next = replaceRunRange(runs, at.start, at.end, styledForRange(pasted, runs, at, host.pending()));\n const after = at.start + runsToPlainText(pasted).length;\n writeRunsPreservingSelection(overlay, next, after, after, host.base());\n host.onWritten(after);\n host.onEdited();\n };\n\n const onBeforeInput = (ie: InputEvent): void => {\n if (PASTES.has(ie.inputType)) { onPaste(ie); return; }\n if (ie.inputType !== 'insertText' || !ie.data) return;\n const sel = window.getSelection();\n const caret = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n if (caret && namesItsRange(ie, caret)) return;\n\n const pending = host.pending();\n if (Object.keys(pending).length > 0) {\n // Rebuild from the runs rather than splicing a span into the DOM.\n // `insertNode` at a caret sitting inside a run span nests the new\n // span *within* it, and `domToRuns` reads styling down the ancestor\n // chain — so a pending style that has to shed the surrounding run's\n // flag would inherit it.\n const at = readSelectionOffsets(overlay) ?? host.lastRange();\n if (!at || at.start !== at.end) return;\n ie.preventDefault();\n const typed = { ...pending, text: ie.data } as StyledRun;\n const next = replaceRunRange(domToRuns(overlay), at.start, at.start, [typed]);\n const after = at.start + ie.data.length;\n writeRunsPreservingSelection(overlay, next, after, after, host.base());\n placeCaretBetweenRuns(overlay, next, after);\n host.onWritten(after);\n host.onEdited();\n return;\n }\n\n // A caret between two run spans, or in an overlay with no text yet. A\n // browser types into the span before it; a text node of its own keeps\n // the character out of that run, and the caret left inside the node\n // hands the characters after it back to the browser.\n if (!sel || !caret || !caret.collapsed || caret.startContainer.nodeType === Node.TEXT_NODE) return;\n if (!overlay.contains(caret.startContainer)) return;\n ie.preventDefault();\n const textNode = document.createTextNode(ie.data);\n caret.insertNode(textNode);\n sel.collapse(textNode, ie.data.length);\n edited();\n };\n\n return { onBeforeInput, onInput: edited };\n}\n","import type { StyleToggle } from './textEditTypes';\n\n/**\n * The shortcut each styling answers to. Strikethrough takes Cmd+Shift+X\n * (Docs' binding) and MUST require shift: bare Cmd+X is cut, and swallowing\n * it here would break cutting text mid-edit. Superscript takes Word's\n * Cmd+Shift+=; subscript takes Cmd+Shift+- rather than Word's Cmd+-, because\n * the unshifted pair is browser zoom, which a page cannot cancel.\n *\n * Matching is on the *unshifted* character: a US layout reports Cmd+Shift+=\n * as `'+'` and Cmd+Shift+- as `'_'`.\n *\n * Underline has to be intercepted, not merely supported. Left alone, the\n * browser runs its own `formatUnderline` and `domToRuns`' `<u>` flattening\n * makes that *look* like it worked while bypassing `patchForToggle`\n * entirely — no toggle-off, no pending style for a collapsed caret.\n */\nconst STYLE_SHORTCUTS: ReadonlyArray<{ key: string; shift: boolean; toggle: StyleToggle }> = [\n { key: 'b', shift: false, toggle: 'bold' },\n { key: 'i', shift: false, toggle: 'italic' },\n { key: 'u', shift: false, toggle: 'underline' },\n { key: 'x', shift: true, toggle: 'strikethrough' },\n { key: '=', shift: true, toggle: 'super' },\n { key: '-', shift: true, toggle: 'sub' },\n];\n\n/** The characters shift produces from the keys the table names. */\nconst UNSHIFT: Readonly<Record<string, string>> = { '+': '=', _: '-' };\n\n/** The styling `e` toggles, or null when it isn't a styling shortcut. */\nexport function toggleForKey(e: KeyboardEvent): StyleToggle | null {\n if (!e.metaKey && !e.ctrlKey) return null;\n const raw = e.key.toLowerCase();\n const key = UNSHIFT[raw] ?? raw;\n return STYLE_SHORTCUTS.find((s) => s.key === key && s.shift === e.shiftKey)?.toggle ?? null;\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type { UseTextEditOptions } from './textEditTypes';\n\n/**\n * The id of the node being edited, and the setter that reports each change:\n * `onEnd` for the edit it closes, then `onStart` for the one it opens. The\n * report is made from the call, so nothing following the edit ever renders\n * with the two out of step.\n */\nexport function useEditingId(\n opts: { readonly current: Pick<UseTextEditOptions, 'onStart' | 'onEnd'> },\n): [string | null, (id: string | null) => void] {\n const [editingId, setState] = useState<string | null>(null);\n const live = useRef<string | null>(null);\n const setEditingId = useCallback((id: string | null) => {\n const prev = live.current;\n if (prev === id) return;\n live.current = id;\n setState(id);\n if (prev !== null) opts.current.onEnd?.(prev);\n if (id !== null) opts.current.onStart?.(id);\n }, [opts]);\n return [editingId, setEditingId];\n}\n","/** The option, return, and pose types of `useTextEdit`. */\nimport type {\n FlagKey, RangeStyle, RunStylePatch, StyledRun, TextPaint, TextStyle, TextVerticalAlign,\n} from '@weasel-js/text';\n\n/**\n * A styling a shortcut or a control toggles. The additive booleans, plus the\n * two `script` values — which are exclusive rather than additive, so they\n * toggle against one enum rather than each owning a boolean.\n */\nexport type StyleToggle = FlagKey | 'super' | 'sub';\n\n/**\n * The caret's character range within the text being edited. Half-open\n * `[start, end)` over the concatenated run text, normalized so `start <= end`\n * regardless of which way the user dragged. `start === end` is a collapsed\n * caret — a real position, not the absence of one, which is why the hook\n * reports `null` rather than a zero-width range when there is no caret.\n */\nexport interface TextEditSelection {\n start: number;\n end: number;\n}\n\n/** Screen-space pose passed to `useTextEdit` so the overlay can be placed and sized in CSS pixels. */\nexport interface TextEditScreenPose {\n /** Top-left in CSS pixels relative to `container`. Always screen pixels,\n * including when `zoom` is set — the scale is anchored at this point, not\n * translated by it. */\n x: number;\n y: number;\n /** Pre-scale — CSS pixels, or world units when `zoom` is set. */\n width: number;\n height: number;\n /** Pre-scale font size: `style.fontSize * zoom` when `zoom` is omitted, the\n * world-unit `style.fontSize` when it is set. */\n fontSize: number;\n /** Effective on-screen line height multiplier (defaults to style.lineHeight). */\n lineHeight?: number;\n /**\n * Where the text sits within `height`, as the canvas places it. `'center'`\n * and `'bottom'` size the overlay to its own content and offset it by the\n * slack, re-measured as typing changes the line count. Default `'top'`.\n */\n verticalAlign?: TextVerticalAlign;\n /**\n * CSS scale applied to the overlay (`transform: scale(zoom)`, anchored at\n * its top-left). Every other size on this pose, and every typographic\n * metric the hook writes, is then **pre-scale** — pass world units and the\n * transform does the world→screen conversion.\n *\n * This is the only way run-level typography can be correct at a zoom other\n * than 1. Omit it (the default, `1`) and the pose is plain screen pixels —\n * the hook then infers the world→screen factor from\n * `fontSize / style.fontSize` to scale node-level `letterSpacing`, and\n * run-level overrides are left unscaled.\n */\n zoom?: number;\n /**\n * The frame the text is drawn in, when its box is turned or skewed: the\n * linear part `[a, b, c, d]` (`x' = a·x + c·y`, `y' = b·x + d·y`) applied\n * about the box's center. `x`, `y`, `width`, and `height` stay those of\n * the box before it. Absent is the identity.\n */\n frame?: readonly [a: number, b: number, c: number, d: number];\n /**\n * Cut the overlay's text at the box `x`/`y`/`width`/`height` name, grown by\n * these on each side, in the same pre-scale units. It turns with `frame`,\n * so it holds to the box as the canvas draws it. Absent, the text may run\n * past the box, cut only by `getClipRect`.\n */\n clip?: { top: number; right: number; bottom: number; left: number };\n}\n\n/** A box in CSS pixels relative to `useTextEdit`'s `container`. */\nexport interface TextEditClipRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** What one edit session changed, as `UseTextEditOptions.commit` receives it. */\nexport interface TextEditCommit {\n text: string;\n runs?: StyledRun[];\n /** The node's own style, where the edit rewrote it. */\n style?: TextStyle;\n}\n\n/** What the overlay holds mid-edit, as {@link UseTextEditOptions.onDraft} reports it: what a commit would write now. */\nexport type TextEditDraft = TextEditCommit;\n\n/** Options for `useTextEdit`. */\nexport interface UseTextEditOptions {\n /** Element the overlay is appended to. Must be `position: relative`/absolute. */\n container: HTMLElement | null;\n /** Read the current text for `id`. */\n getText: (id: string) => string;\n /** Read style for `id` (used for font setup on the overlay). */\n getStyle: (id: string) => TextStyle | undefined;\n /**\n * Read the node's paint for `id` — its `data.fill` / `data.stroke`. The\n * overlay paints its text and caret from the fill, so omitting this\n * renders every node's editor in the default black however the node\n * itself is painted.\n */\n getPaint?: (id: string) => TextPaint | undefined;\n /**\n * Write style back for `id`. Optional; needed only to turn a flag **off**\n * inside a node whose own `TextStyle` sets it. Run flags are additive, so\n * that edit is expressed by lowering the node flag and raising it on the\n * runs outside the selection — which needs somewhere to put the new node\n * style. Without this or `commit`, such a toggle is declined and nothing\n * changes. See `flagRange` in `@weasel-js/text`.\n *\n * Called when the edit commits, never during it: the session holds the\n * rewritten style until then (see `UseTextEditReturn.nodeStyle`), so a\n * canceled edit writes nothing.\n */\n setStyle?: (id: string, style: TextStyle) => void;\n /** Read screen-space pose for `id`. Called per frame while editing. */\n getScreenPose: (id: string) => TextEditScreenPose | null;\n /**\n * The box, in CSS pixels relative to `container`, the overlay is visible\n * within — where the canvas clips the glyphs the overlay stands in for.\n * Re-read every frame. Omit it, or return `null`, to clip nothing.\n *\n * The clip cannot scroll, so a caret moving past its edge leaves the page\n * where it is; a scrollable container would drag the canvas after the caret.\n */\n getClipRect?: () => TextEditClipRect | null;\n /** Commit text. Caller wraps in op/undo. Required unless `commit` is given. */\n setText?: (id: string, text: string) => void;\n /**\n * Take the whole edit in one call, so the caller can make it one write and\n * one undo step. When given, it replaces `setText`, `setRuns`, and\n * `setStyle`, none of which is called. `runs` is present when runs are in\n * play (see `setRuns`), `style` when the edit rewrote the node's own style\n * (see `setStyle`).\n */\n commit?: (id: string, edit: TextEditCommit) => void;\n /**\n * Called on each edit to the overlay's text, and on each restyle of it, with\n * what a commit would write now: `runs` present when runs are in play (see\n * `setRuns`), `style` when the edit rewrote the node's own. For a host\n * whose canvas shows the text somewhere besides the overlay, such as a copy\n * laid along a path, to follow the typing. Not a commit: a cancel follows\n * as it would without it.\n */\n onDraft?: (id: string, draft: TextEditDraft) => void;\n /**\n * Optional: read the current rich-text runs for `id`. When provided AND\n * returns a non-empty array, the overlay renders the runs as styled\n * `<span data-run>` elements; otherwise the overlay is seeded with plain\n * text via `getText`.\n */\n getRuns?: (id: string) => readonly StyledRun[] | undefined;\n /**\n * Optional: commit rich-text runs back to the node. When omitted, only\n * `setText` is called with the plain-text form on commit. When provided,\n * commit calls both `setText` (with `runsToPlainText(runs)`) and\n * `setRuns(id, runs)` — but only when runs are actually in play: the node\n * already had some, or the edit produced styling. A plain-text edit of a\n * plain-text node still calls `setText` alone.\n */\n setRuns?: (id: string, runs: StyledRun[]) => void;\n /**\n * Is `el` part of the editor's own chrome — a character-options bar, a\n * color popover, anything whose whole purpose is to style the text being\n * edited? Focus moving into one does not end the edit.\n *\n * Without this, clicking a size field blurs the overlay, blur commits, and\n * the caret the control was about to act on is gone. Toggle buttons can\n * dodge it by `preventDefault()`-ing their own mousedown, but a field the\n * user has to type into cannot.\n *\n * Chrome focus does not disturb the reported `selection` either — see\n * `UseTextEditReturn.selection`.\n */\n isEditorChrome?: (el: Element) => boolean;\n /** What Escape does to the edit: `'cancel'` (the default) drops it,\n * `'commit'` keeps the text as Enter would. */\n escape?: 'cancel' | 'commit';\n /** Called as an edit of `id` opens, from the call that opens it. */\n onStart?: (id: string) => void;\n /**\n * Called as the edit of `id` closes, however it does: a commit, a cancel,\n * a click away, or another edit opening over it. A commit has been written\n * by then. Not called when the hook unmounts with an edit open.\n */\n onEnd?: (id: string) => void;\n /**\n * How long, in ms, an edit opening waits for the overlay's face before\n * showing the text in the fallback. Defaults to {@link TEXT_EDIT_FONT_HOLD}.\n *\n * The overlay stands in for canvas text the host has hidden, so the wait\n * shows nothing at all; past it, the fallback shows and reflows to the real\n * face when that lands. A face already loaded shows at once. `0` never waits.\n */\n fontHold?: number;\n}\n\n/**\n * The default {@link UseTextEditOptions.fontHold}: at 100ms a blank edit\n * still reads as an instant response, and it is the block period CSS gives\n * `font-display: fallback` for the same trade.\n */\nexport const TEXT_EDIT_FONT_HOLD = 100;\n\n/** Options for `useTextEdit().startEdit`. */\nexport interface StartEditOptions {\n /** Where to place the caret on edit start. Number = caret offset (0..text.length);\n * `'all'` selects the whole text (default). */\n caret?: number | 'all';\n}\n\n/** Return shape of `useTextEdit`. */\nexport interface UseTextEditReturn {\n editingId: string | null;\n startEdit: (id: string, opts?: StartEditOptions) => void;\n cancelEdit: () => void;\n /** End the edit and write it. An edit that leaves the text, the runs, and\n * the node's style as it found them writes nothing. */\n commit: () => void;\n isEditing: (id: string) => boolean;\n /**\n * The node-wide style this edit has rewritten and not yet written back, or\n * `null` when it has rewritten none (the node's own style stands) or\n * nothing is being edited. Lowering a flag the node sets rewrites it; the\n * write waits for the commit. A control showing the node's style during an\n * edit reads this first.\n */\n nodeStyle: TextStyle | null;\n /**\n * The caret's character range, or `null` when nothing is being edited. A\n * collapsed caret reports `{ start: n, end: n }`, so `null` and \"caret at\n * n\" stay distinguishable — a styling written at a collapsed caret arms\n * {@link UseTextEditReturn.pendingStyle} instead of restyling a range.\n *\n * Follows the DOM selection, which browsers report from a task\n * rather than synchronously; anything this hook writes itself updates it\n * synchronously. A DOM selection that leaves the overlay does **not** clear\n * it: that is what happens when the user clicks a styling control, and\n * reporting `null` there would read as \"collapsed caret\" and send the\n * control's patch to the node instead of to the range. It is cleared on\n * `startEdit` and when the edit ends.\n */\n selection: TextEditSelection | null;\n /**\n * The styling shared by every run in `selection` — a concrete value where\n * the range agrees, `MIXED` where it doesn't. `null` exactly when\n * `selection` is `null`. A collapsed caret reports the styling *at* the\n * caret (the run to its left, or the run to its right at offset 0), which\n * is what the next typed character inherits.\n *\n * This does not include {@link UseTextEditReturn.pendingStyle}. A control\n * showing what the next character will look like wants both, merged in\n * that order; one showing what is already written wants only this.\n */\n rangeStyle: RangeStyle | null;\n /**\n * Styling armed at a collapsed caret, applied to the next character typed\n * and then dropped. `{}` when nothing is armed — which is always the case\n * while `selection` covers a real range, since a range is styled directly.\n * Moving the caret abandons it.\n */\n pendingStyle: RunStylePatch;\n /**\n * What a styling control shows during an edit: the node's own style and\n * paint, `rangeStyle` over it, and `pendingStyle` last — what the user\n * will see themselves type. `null` when nothing is being edited.\n */\n effectiveStyle: RangeStyle | null;\n /**\n * Write `patch` over `selection`. A no-op with no active edit or an empty\n * patch. Over a real range this restyles the runs under it; at a collapsed\n * caret it merges into `pendingStyle` instead, so the styling lands on\n * what gets typed next rather than on text the user didn't select.\n *\n * Lowering a flag the *node* sets is neither of those — a run cannot say\n * \"not italic\" — so it rewrites instead: the node flag is cleared and raised\n * on every run outside the range. Bold is spared that: a run's own\n * `fontWeight` can say \"regular\", so it is written over the range.\n *\n * The caret survives, so a second style can be applied without\n * re-selecting, and `rangeStyle` reflects the write before this returns.\n */\n applyStyleToSelection: (patch: RunStylePatch) => void;\n /** Toggle one styling over `selection` — set it if the range doesn't\n * uniformly carry it, clear it if it does. */\n toggleStyle: (toggle: StyleToggle) => void;\n}\n","/**\n * In-place text editing via a contenteditable overlay positioned over the\n * text node's screen-space pose. Enter / blur commit; Shift+Enter inserts a\n * newline. The text layer should hide the node it's currently editing\n * (`isHidden: (n) => n.id === editingId`) so the overlay isn't drawn twice.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useLatest, useVisibleRaf } from '@weasel-js/react';\nimport type { ResolvedTextStyle, TextStyle } from '@weasel-js/text';\nimport {\n numericWeight, resolveTextStyle, scriptMetricsFor,\n} from '@weasel-js/text';\nimport { cssFontFamilyLoading } from '@weasel-js/font';\nimport { editEnd, imeKey } from '@weasel-js/headless';\nimport { layoutTextPose } from '@weasel-js/text';\nimport type { StyledRun } from '@weasel-js/text';\nimport { domToRuns, type OverlayRunBase } from './domRuns';\nimport {\n applyStyleToRange, effectiveRangeStyle, nodeHasFlag, patchRangeStyle, rangeWeight, setFlagOverRange,\n styleAtRange, supersededKey, unboldPatch, type FlagKey, type RangeStyle, type RunStylePatch,\n} from '@weasel-js/text';\nimport { overlayAlignEdge } from './overlayDirection';\nimport { draftChanged, overlayDraft, writeEdit } from './overlayDraft';\nimport { overlayClipPath, overlayTop, overlayTransform } from './overlayFrame';\nexport { overlayTop };\nimport { applyOverlayStyle } from './overlayStyle';\nimport { seedOverlay, type CaretHolder } from './overlaySeed';\nimport {\n readSelectionOffsets, restoreOverlayFocus, sameSelection, writeRunsPreservingSelection,\n} from './overlaySelection';\nimport { typingHandlers } from './overlayTyping';\nimport { toggleForKey } from './styleShortcuts';\nimport { useEditingId } from './editSession';\nimport { TEXT_EDIT_FONT_HOLD } from './textEditTypes';\nimport type {\n StartEditOptions, StyleToggle, TextEditClipRect, TextEditScreenPose, TextEditSelection, UseTextEditOptions,\n UseTextEditReturn,\n} from './textEditTypes';\n\n/**\n * The patch that toggles `toggle` against the styling in `current`: if it is\n * already carried, clear it; otherwise set it — so a mixed range turns fully\n * on. `nodeStyle` is read as well as `current`: a node flag renders on every\n * run whether or not the runs carry it, so the runs alone would read Cmd+B\n * inside a `fontWeight: 700` node as \"not bold\" and *add* bold.\n */\nfunction patchForToggle(\n current: RangeStyle,\n toggle: StyleToggle,\n nodeStyle: TextStyle,\n): RunStylePatch {\n if (toggle === 'super' || toggle === 'sub') {\n return { script: current.script === toggle ? undefined : toggle };\n }\n const on = toggle === 'bold'\n ? rangeWeight(current, nodeStyle).bold === true\n : current[toggle] === true || nodeHasFlag(nodeStyle, toggle);\n return { [toggle]: !on };\n}\n\n/**\n * The styling at a collapsed caret: the run to its left, or — at the very\n * start of the text — the run to its right. This is what the next typed\n * character inherits.\n */\nfunction styleAtCaret(runs: readonly StyledRun[], at: number): RangeStyle {\n return at > 0 ? styleAtRange(runs, at - 1, at) : styleAtRange(runs, 0, 1);\n}\n\n/** No pending style. One frozen object so re-publishing an already-empty\n * pending style doesn't re-render every consumer. */\nconst NO_PENDING: RunStylePatch = Object.freeze({});\n\n/**\n * Merge `patch` into a pending style. A key set to `false` or `undefined` is\n * deleted rather than stored, and bold and a weight supersede each other —\n * the canonical form a stored run keeps.\n */\nfunction mergePending(prev: RunStylePatch, patch: RunStylePatch): RunStylePatch {\n const next: Record<string, unknown> = { ...prev };\n const superseded = supersededKey(patch);\n if (superseded !== undefined) delete next[superseded];\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || value === false) delete next[key];\n else next[key] = value;\n }\n return next as RunStylePatch;\n}\n\n/** In-place text editing via a contenteditable overlay positioned over the text node's screen-space pose. */\nexport function useTextEdit(\n opts: UseTextEditOptions,\n): UseTextEditReturn {\n const optsRef = useLatest(opts);\n\n const [editingId, setEditingId] = useEditingId(optsRef);\n // `applyStyleToSelection` needs the node being edited to reach its\n // `TextStyle`, and is called from event handlers rather than from render.\n const editingIdRef = useLatest(editingId);\n const overlayRef = useRef<HTMLDivElement | null>(null);\n /** The editing node's resolved style, which run spans inheriting small caps\n * are split by whenever the runs are rewritten. */\n const baseRef = useRef<OverlayRunBase>(resolveTextStyle(undefined));\n const [nodeStyle, setNodeStyle] = useState<TextStyle | null>(null);\n /** `nodeStyle`, read synchronously by the handlers that rewrite and commit it. */\n const nodeStyleRef = useRef<TextStyle | null>(null);\n const holdNodeStyle = useCallback((style: TextStyle | null) => {\n nodeStyleRef.current = style;\n setNodeStyle(style);\n }, []);\n const styleOf = useCallback(\n (id: string): TextStyle | undefined => nodeStyleRef.current ?? optsRef.current.getStyle(id),\n [optsRef],\n );\n // The overlay-follow loop is built inside the editing effect; the gate's\n // frame callback reaches it through this ref.\n const tickRef = useRef<() => void>(() => {});\n const frameLoop = useVisibleRaf(() => { tickRef.current(); });\n const initialCaretRef = useRef<number | 'all'>('all');\n /** What the overlay read back as when the edit opened, before any input. */\n const openedRef = useRef<string | null>(null);\n const sentRef = useRef(''); // the last draft sent, as JSON; before the first, the overlay as it opened\n const holderRef = useRef<CaretHolder | null>(null);\n const priorRunsRef = useRef<readonly StyledRun[] | undefined>(undefined); // the node's, as the edit opened\n const [selection, setSelection] = useState<TextEditSelection | null>(null);\n const [rangeStyle, setRangeStyle] = useState<RangeStyle | null>(null);\n const [pendingStyle, setPendingStyle] = useState<RunStylePatch>(NO_PENDING);\n /** The pending style, read synchronously by `beforeinput` — which fires\n * well before React has re-rendered with the state above. */\n const pendingRef = useRef<RunStylePatch>(NO_PENDING);\n /** The caret offset the pending style was armed at, or `null` when nothing\n * is armed. Publishing any other range abandons it. */\n const pendingAtRef = useRef<number | null>(null);\n\n const armPending = useCallback((next: RunStylePatch, at: number) => {\n const empty = Object.keys(next).length === 0;\n pendingRef.current = empty ? NO_PENDING : next;\n pendingAtRef.current = empty ? null : at;\n setPendingStyle(pendingRef.current);\n }, []);\n\n const dropPending = useCallback(() => {\n if (pendingAtRef.current === null) return;\n pendingRef.current = NO_PENDING;\n pendingAtRef.current = null;\n setPendingStyle(NO_PENDING);\n }, []);\n\n /** The published range, mirrored in a ref: the fallback when the DOM\n * selection has moved into editing chrome. */\n const selectionRef = useRef<TextEditSelection | null>(null);\n\n /** Publish `range` and the styling the overlay currently carries across it. */\n const publishRange = useCallback((overlay: HTMLElement, range: TextEditSelection) => {\n const collapsed = range.start === range.end;\n // A pending style belongs to the caret position it was armed at. Any\n // other range means the caret moved, which abandons it.\n if (pendingAtRef.current !== null\n && !(collapsed && range.start === pendingAtRef.current)) {\n dropPending();\n }\n selectionRef.current = range;\n setSelection((prev) => (sameSelection(prev, range) ? prev : range));\n const runs = domToRuns(overlay);\n setRangeStyle(collapsed\n ? styleAtCaret(runs, range.start)\n : styleAtRange(runs, range.start, range.end));\n }, [dropPending]);\n\n const syncSelection = useCallback(() => {\n const overlay = overlayRef.current;\n if (!overlay) return;\n const next = readSelectionOffsets(overlay);\n // A selection outside the overlay means focus moved into a control, which\n // is when the range matters most: leave it published rather than clear it.\n if (next === null) return;\n publishRange(overlay, next);\n }, [publishRange]);\n\n /** Drop the published range — the edit session it described is over. */\n const clearSelection = useCallback(() => {\n selectionRef.current = null;\n setSelection(null);\n setRangeStyle(null);\n dropPending();\n }, [dropPending]);\n\n const cancelEdit = useCallback(() => setEditingId(null), [setEditingId]);\n\n const commit = useCallback(() => {\n const id = editingId;\n const overlay = overlayRef.current;\n if (id == null || !overlay) return void setEditingId(null);\n // Runs are written when the node already had them — or stale styling\n // survives a Cmd-B that turned it off — or when the edit produced\n // styling. A plain-text edit of a plain-text node commits text alone.\n const read = domToRuns(overlay);\n const style = nodeStyleRef.current;\n // Compared untrimmed: a seeded trailing newline reads back the same at\n // both ends, where the trimmed form would differ from the node's text.\n if (!style && JSON.stringify(read) === openedRef.current) {\n setEditingId(null);\n return;\n }\n holdNodeStyle(null);\n writeEdit(optsRef.current, id, overlayDraft(read, holderRef.current, priorRunsRef.current, style));\n setEditingId(null);\n }, [editingId, optsRef, holdNodeStyle, setEditingId]);\n\n const startEdit = useCallback((id: string, opts?: StartEditOptions) => {\n initialCaretRef.current = opts?.caret ?? 'all';\n setEditingId(id);\n }, [setEditingId]);\n\n const isEditing = useCallback((id: string) => editingId === id, [editingId]);\n\n const sendDraft = useCallback((overlay: HTMLElement) => {\n const id = editingIdRef.current;\n const draft = overlayDraft(domToRuns(overlay), holderRef.current, priorRunsRef.current, nodeStyleRef.current);\n if (id !== null && draftChanged(sentRef, draft)) optsRef.current.onDraft?.(id, draft);\n }, [editingIdRef, optsRef]);\n\n const applyStyleToSelection = useCallback(function applyStyle(patch: RunStylePatch) {\n const overlay = overlayRef.current;\n if (!overlay) return;\n // An empty patch would still round-trip the runs through\n // `applyStyleToRange`, whose normalization applies to the whole array.\n if (Object.keys(patch).length === 0) return;\n // Fall back to the last range that WAS in the overlay: the caller may be\n // a control that took focus (and with it the DOM selection) to be clicked.\n const range = readSelectionOffsets(overlay) ?? selectionRef.current;\n if (!range) return;\n\n // Lowering a flag the node itself sets is not expressible additively, so\n // it takes the rewrite in `setFlagOverRange`: clear the node flag, raise\n // it outside the range. It reaches existing text even from a collapsed caret.\n const id = editingIdRef.current;\n const canWriteStyle = optsRef.current.setStyle !== undefined || optsRef.current.commit !== undefined;\n const runs = domToRuns(overlay);\n if (patch.bold === false && !('fontWeight' in patch) && id !== null) {\n patch = { ...patch, ...unboldPatch(styleOf(id) ?? {}) };\n }\n const unsetFlag = id !== null && canWriteStyle\n ? (Object.keys(patch) as FlagKey[]).find((key) =>\n key !== 'bold'\n && patch[key] === false\n && nodeHasFlag(styleOf(id) ?? {}, key))\n : undefined;\n if (unsetFlag !== undefined && id !== null) {\n const r = setFlagOverRange(runs, styleOf(id) ?? {}, range.start, range.end, unsetFlag, false);\n holdNodeStyle(r.style);\n // The root's own decoration and slant reach every run by inheritance,\n // the range just cleared included.\n const resolved = resolveTextStyle(r.style, optsRef.current.getPaint?.(id));\n baseRef.current = resolved;\n applyOverlayStyle(overlay, resolved);\n writeRunsPreservingSelection(overlay, r.runs, range.start, range.end, resolved);\n publishRange(overlay, range);\n // The rewrite raised the flag on every existing run, so a caret sitting\n // at the end of one is now *inside* a flagged span and the next\n // character would be absorbed by it. Arming the `false` makes\n // `beforeinput` open a fresh span instead.\n if (range.start === range.end) {\n armPending({ ...pendingRef.current, [unsetFlag]: false }, range.start);\n }\n restoreOverlayFocus(overlay, range);\n // Whatever else the patch carried still applies on its own terms.\n const rest = { ...patch };\n delete rest[unsetFlag];\n if (Object.keys(rest).length > 0) applyStyle(rest);\n sendDraft(overlay);\n return;\n }\n\n // A collapsed caret has no run to restyle, so the styling is armed for\n // the next character instead of silently doing nothing.\n if (range.start === range.end) {\n armPending(mergePending(pendingRef.current, patch), range.start);\n restoreOverlayFocus(overlay, range);\n return;\n }\n\n const next = applyStyleToRange(runs, range.start, range.end, patch);\n writeRunsPreservingSelection(overlay, next, range.start, range.end, baseRef.current);\n restoreOverlayFocus(overlay, range);\n // Republish from the range we just styled, not from the DOM selection:\n // when the patch came from chrome the selection is in that control.\n publishRange(overlay, range);\n sendDraft(overlay);\n }, [publishRange, armPending, editingIdRef, optsRef, styleOf, holdNodeStyle, sendDraft]);\n\n const toggleStyle = useCallback((toggle: StyleToggle) => {\n const overlay = overlayRef.current;\n if (!overlay) return;\n const range = readSelectionOffsets(overlay) ?? selectionRef.current;\n if (!range) return;\n const runs = domToRuns(overlay);\n const id = editingIdRef.current;\n const nodeStyle = (id !== null ? styleOf(id) : undefined) ?? {};\n // At a collapsed caret the styling in play is what the caret sits in plus\n // whatever is already armed, so pressing Cmd+B twice disarms rather than\n // arming a second time.\n const current = range.start === range.end\n ? patchRangeStyle(styleAtCaret(runs, range.start), pendingRef.current)\n : styleAtRange(runs, range.start, range.end);\n applyStyleToSelection(patchForToggle(current, toggle, nodeStyle));\n }, [applyStyleToSelection, editingIdRef, styleOf]);\n\n useEffect(() => {\n if (editingId == null) return;\n const { container, getText, getStyle, getPaint } = optsRef.current;\n if (!container) return;\n holdNodeStyle(null);\n\n const style = resolveTextStyle(getStyle(editingId), getPaint?.(editingId));\n const overlay = document.createElement('div');\n const overlayClass = `weasel-text-edit-${++OVERLAY_SEQ}`;\n overlay.classList.add(overlayClass);\n overlay.setAttribute('contenteditable', 'true');\n overlay.spellcheck = false;\n baseRef.current = style;\n const initialRuns = (priorRunsRef.current = optsRef.current.getRuns?.(editingId));\n holderRef.current = seedOverlay(overlay, getText(editingId), initialRuns, style);\n openedRef.current = JSON.stringify(domToRuns(overlay));\n sentRef.current = JSON.stringify(overlayDraft(domToRuns(overlay), holderRef.current, initialRuns));\n applyOverlayStyle(overlay, style);\n const hold = holdForFaces(style, initialRuns ?? []);\n if (hold) overlay.style.opacity = '0';\n const styleEl = installSelectionStyle(overlayClass, style);\n const clipBox = createClipBox();\n clipBox.appendChild(overlay);\n container.appendChild(clipBox);\n overlayRef.current = overlay;\n\n const place = () => {\n const clip = optsRef.current.getClipRect?.() ?? null;\n placeOverlay(overlay, clipBox, optsRef.current.getScreenPose(editingId), clip, style);\n };\n place();\n // Measured again on release: the first `place` ran in the fallback face.\n let held = hold !== null;\n const release = () => {\n if (!held) return;\n held = false;\n clearTimeout(holdTimer);\n place();\n overlay.style.opacity = '';\n };\n const holdTimer = held ? setTimeout(release, optsRef.current.fontHold ?? TEXT_EDIT_FONT_HOLD) : undefined;\n void hold?.then(release);\n\n const range = document.createRange();\n const initial = initialCaretRef.current;\n if (initial === 'all') {\n range.selectNodeContents(overlay);\n } else {\n placeCaretAt(overlay, range, initial);\n }\n // Focus first, then place the caret: focusing an editable host itself\n // moves the selection (jsdom collapses to the start; browsers vary).\n overlay.focus();\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n // Publish now rather than on the `selectionchange` task — a control mounted\n // alongside the editor would otherwise render one frame with no selection.\n syncSelection();\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (imeKey(e)) return;\n const ends = editEnd({ key: e.key, shift: e.shiftKey }, { escape: optsRef.current.escape, multiline: true });\n if (ends) {\n e.preventDefault();\n if (ends === 'commit') commit();\n else cancelEdit();\n return;\n }\n const toggle = toggleForKey(e);\n if (toggle) {\n e.preventDefault();\n toggleStyle(toggle);\n }\n };\n const onBlur = (e: FocusEvent) => {\n const next = e.relatedTarget;\n if (isChrome(optsRef.current, next)) return;\n commit();\n };\n\n const { onBeforeInput, onInput } = typingHandlers(overlay, {\n pending: () => pendingRef.current,\n base: () => baseRef.current,\n lastRange: () => selectionRef.current,\n onWritten: (caret) => {\n dropPending();\n publishRange(overlay, { start: caret, end: caret });\n },\n onEdited: () => {\n holderRef.current?.edited(overlay);\n place();\n sendDraft(overlay);\n },\n });\n\n // Blur can't be the only way out: once focus has moved into editing\n // chrome, nothing blurs when the user clicks away. Capture phase so this\n // runs ahead of whatever the click was aimed at.\n const onPointerDownOutside = (e: Event) => {\n const target = e.target;\n if (!(target instanceof Node) || overlay.contains(target)) return;\n if (isChrome(optsRef.current, target)) return;\n commit();\n };\n\n overlay.addEventListener('keydown', onKeyDown);\n overlay.addEventListener('blur', onBlur);\n // Typing can change the line count; re-placing here rather than on the\n // next frame keeps a center/bottom-aligned overlay from jumping a frame late.\n overlay.addEventListener('input', onInput);\n overlay.addEventListener('beforeinput', onBeforeInput);\n document.addEventListener('pointerdown', onPointerDownOutside, true);\n // `selectionchange` only exists on the document.\n document.addEventListener('selectionchange', syncSelection);\n\n // Follows the node's screen pose every frame — behind the visibility gate,\n // so an overlay left open in a background tab costs nothing.\n tickRef.current = () => {\n place();\n frameLoop.request();\n };\n frameLoop.request();\n\n return () => {\n held = false;\n clearTimeout(holdTimer);\n frameLoop.cancel();\n tickRef.current = () => {};\n overlay.removeEventListener('keydown', onKeyDown);\n overlay.removeEventListener('blur', onBlur);\n overlay.removeEventListener('input', onInput);\n overlay.removeEventListener('beforeinput', onBeforeInput);\n document.removeEventListener('pointerdown', onPointerDownOutside, true);\n document.removeEventListener('selectionchange', syncSelection);\n clipBox.remove();\n styleEl?.remove();\n overlayRef.current = null;\n holdNodeStyle(null);\n clearSelection();\n };\n }, [editingId, opts.container, optsRef, commit, cancelEdit, syncSelection, clearSelection,\n frameLoop, toggleStyle, dropPending, publishRange, holdNodeStyle, sendDraft]);\n\n return {\n editingId, startEdit, cancelEdit, commit, isEditing, nodeStyle,\n selection, rangeStyle, pendingStyle, applyStyleToSelection, toggleStyle,\n effectiveStyle: shownStyle(opts, editingId, nodeStyle, rangeStyle, pendingStyle),\n };\n}\n\nfunction isChrome(opts: UseTextEditOptions, el: EventTarget | null): boolean {\n return el instanceof Element && (opts.isEditorChrome?.(el) ?? false);\n}\n\nfunction shownStyle(\n opts: UseTextEditOptions,\n editingId: string | null,\n nodeStyle: TextStyle | null,\n rangeStyle: RangeStyle | null,\n pendingStyle: RunStylePatch,\n): RangeStyle | null {\n if (editingId === null) return null;\n return effectiveRangeStyle(\n patchRangeStyle(rangeStyle ?? {}, pendingStyle),\n nodeStyle ?? opts.getStyle(editingId),\n opts.getPaint?.(editingId),\n );\n}\n\nlet OVERLAY_SEQ = 0;\n\n/**\n * The loads the overlay's faces are still waiting on — the node's and each\n * run's that names its own family — or `null` when every one is in hand.\n */\nfunction holdForFaces(style: ResolvedTextStyle, runs: readonly StyledRun[]): Promise<unknown> | null {\n const pending = [\n cssFontFamilyLoading(style.fontFamily, {\n weight: numericWeight(style.fontWeight), style: style.fontStyle,\n }),\n ...runs.filter((r) => r.fontFamily != null).map((r) => cssFontFamilyLoading(r.fontFamily!, {\n weight: r.fontWeight ?? (r.bold ? 700 : undefined),\n style: r.italic ? 'italic' : undefined,\n })),\n ].filter((p) => p !== null);\n return pending.length === 0 ? null : Promise.all(pending);\n}\n\n/**\n * Place a collapsed caret `offset` characters into the overlay's text,\n * walking its text nodes. Out-of-range offsets clamp to the end.\n */\nfunction placeCaretAt(root: HTMLElement, range: Range, offset: number): void {\n let remaining = offset;\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n let node: Text | null = walker.nextNode() as Text | null;\n while (node) {\n const len = node.data.length;\n if (remaining <= len) {\n range.setStart(node, remaining);\n range.setEnd(node, remaining);\n return;\n }\n remaining -= len;\n node = walker.nextNode() as Text | null;\n }\n range.selectNodeContents(root);\n range.collapse(false);\n}\n\n/** The overlay's positioning parent. Passes pointer input through everywhere\n * but the overlay itself, which spans no more than the canvas it covers. */\nfunction createClipBox(): HTMLDivElement {\n const el = document.createElement('div');\n el.style.position = 'absolute';\n el.style.margin = '0';\n el.style.padding = '0';\n el.style.border = '0';\n el.style.pointerEvents = 'none';\n return el;\n}\n\n/**\n * Inject a `<style>` element scoped to `overlayClass` so the edit overlay's\n * `::selection` matches the configured colors, or `null` when none are set.\n */\nfunction installSelectionStyle(\n overlayClass: string,\n style: ResolvedTextStyle,\n): HTMLStyleElement | null {\n if (style.selectionBackground == null && style.selectionColor == null) return null;\n const el = document.createElement('style');\n const decls: string[] = [];\n if (style.selectionBackground != null) {\n decls.push(`background: ${style.selectionBackground};`);\n }\n if (style.selectionColor != null) {\n decls.push(`color: ${style.selectionColor};`);\n }\n el.textContent = `.${overlayClass}::selection { ${decls.join(' ')} }`;\n document.head.appendChild(el);\n return el;\n}\n\nconst ALIGN_ANCHOR = { left: 0, center: 0.5, right: 1 } as const;\n\n/**\n * The canvas and CSS both hang a line's baseline half the leading plus one\n * ascent below the line top, from the same ascent rule, but each engine\n * rounds the font's metrics and that leading its own way, and a face that\n * states no ascent and descent hangs from its ascent alone. So the difference\n * is read from both sides rather than predicted: the canvas's from its own layout, the\n * overlay's from a zero-height inline box on a hidden line set exactly as the\n * overlay is. Pre-scale; `0` when either side has nothing to measure.\n * @internal\n */\nexport function baselineDrop(el: HTMLElement, style: ResolvedTextStyle, pose: TextEditScreenPose, lineHeight: number): number {\n const canvas = layoutTextPose({\n x: 0, y: 0, width: pose.width, height: pose.height, text: ' ',\n style: {\n fontFamily: style.fontFamily, fontWeight: style.fontWeight, fontStyle: style.fontStyle,\n fontSize: pose.fontSize, lineHeight, script: style.script,\n },\n }).laid.lines[0]?.baselineY ?? 0;\n const css = cssBaseline(el);\n return canvas > 0 && css > 0 ? canvas - css : 0;\n}\n\nconst CSS_BASELINES = new Map<string, number>();\n\nfunction cssBaseline(el: HTMLElement): number {\n const parent = el.parentElement;\n if (!parent) return 0;\n const { fontFamily, fontWeight, fontStyle, fontSize, lineHeight, textRendering } = el.style;\n const key = [fontFamily, fontWeight, fontStyle, fontSize, lineHeight, textRendering].join('|');\n const cached = CSS_BASELINES.get(key);\n if (cached !== undefined) return cached;\n const line = document.createElement('div');\n Object.assign(line.style, {\n position: 'absolute', left: '0', top: '0', width: '100px', margin: '0', padding: '0', border: '0',\n visibility: 'hidden', whiteSpace: 'pre', fontFamily, fontWeight, fontStyle, fontSize, lineHeight, textRendering,\n });\n const mark = document.createElement('span');\n Object.assign(mark.style, { display: 'inline-block', width: '0', height: '0', verticalAlign: 'baseline' });\n line.appendChild(mark);\n parent.appendChild(line);\n const box = line.getBoundingClientRect();\n // Rect over layout width undoes any transform on an ancestor.\n const scale = box.width / 100;\n const baseline = scale > 0 ? (mark.getBoundingClientRect().top - box.top) / scale : 0;\n line.remove();\n // A web font still loading is measured as its fallback; ask again later.\n if (baseline > 0 && document.fonts?.status !== 'loading') {\n if (CSS_BASELINES.size >= 64) CSS_BASELINES.clear();\n CSS_BASELINES.set(key, baseline);\n }\n return baseline;\n}\n\nfunction placeOverlay(\n el: HTMLDivElement,\n clipBox: HTMLDivElement,\n pose: TextEditScreenPose | null,\n clip: TextEditClipRect | null,\n style: ResolvedTextStyle,\n): void {\n if (!pose) {\n el.style.display = 'none';\n return;\n }\n // `clip` rather than `hidden`: a `hidden` box is still scrollable, and the\n // browser scrolls it to keep the caret in view.\n clipBox.style.overflow = clip ? 'clip' : 'visible';\n clipBox.style.left = `${clip?.x ?? 0}px`;\n clipBox.style.top = `${clip?.y ?? 0}px`;\n clipBox.style.width = `${clip?.width ?? 0}px`;\n clipBox.style.height = `${clip?.height ?? 0}px`;\n el.style.display = '';\n // An unwrapped line can be wider than its box, and the canvas aligns it\n // about the box's left edge, center, or right edge regardless. `left` puts\n // that anchor there and a trailing translate pulls the overlay back by that\n // fraction of its own width.\n const anchor = style.wrap ? 0 : ALIGN_ANCHOR[overlayAlignEdge(el, style)];\n const left = pose.x + pose.width * (pose.zoom ?? 1) * anchor;\n el.style.left = `${left - (clip?.x ?? 0)}px`;\n el.style.width = style.wrap ? `${pose.width}px` : 'max-content';\n el.style.minWidth = style.wrap ? '' : `${pose.width}px`;\n // A node-level script draws the glyphs smaller and raised on the line the\n // plain text would hold, so the line height is pinned in pixels of the\n // unscripted size rather than left to scale with the font.\n const script = style.script\n ? scriptMetricsFor(style.fontFamily, numericWeight(style.fontWeight), style.fontStyle)[style.script]\n : undefined;\n const lineHeight = pose.lineHeight ?? style.lineHeight;\n el.style.fontSize = `${pose.fontSize * (script?.size ?? 1)}px`;\n el.style.lineHeight = script ? `${pose.fontSize * lineHeight}px` : String(lineHeight);\n // A top-aligned overlay fills its box, so a click anywhere in it lands in\n // the editor. Any other alignment needs the content's own height, which a\n // min-height would mask; `offsetHeight` is pre-transform, in pose units.\n const aligned = pose.verticalAlign !== undefined && pose.verticalAlign !== 'top';\n el.style.minHeight = aligned ? '' : `${pose.height}px`;\n const drop = baselineDrop(el, style, pose, lineHeight) - (script?.shift ?? 0) * pose.fontSize;\n const top = overlayTop(pose, aligned ? el.offsetHeight : pose.height, drop);\n el.style.top = `${top - (clip?.y ?? 0)}px`;\n // A declared `zoom` means every size on the pose is pre-scale and the\n // overlay carries the view scale as a transform. Anchored at the top-left so\n // `left`/`top` stay screen pixels.\n el.style.transformOrigin = '0 0';\n el.style.transform = overlayTransform(pose, left, top, anchor);\n el.style.clipPath = pose.clip ? overlayClipPath(el, pose, left, top, anchor, pose.clip) : '';\n // `letter-spacing` is not part of the CSS `font` shorthand. Under a\n // transform the world value is the value. Without one, `pose.fontSize` is\n // `style.fontSize * zoom`, so their ratio is the world→screen factor; run\n // overrides, which `runsToDom` writes in world units, then stay unscaled,\n // so that path is only correct at zoom 1.\n const scale =\n pose.zoom !== undefined ? 1 : style.fontSize > 0 ? pose.fontSize / style.fontSize : 1;\n el.style.letterSpacing = `${style.letterSpacing * scale}px`;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/text-dom",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "description": "In-place text editing over a canvas: a contenteditable overlay that reads and writes styled runs, with range styling, caret mapping and font-load handling. A React hook; no scene graph.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,10 +19,11 @@
19
19
  "react": ">=18"
20
20
  },
21
21
  "dependencies": {
22
- "@weasel-js/font": "1.13.0",
23
- "@weasel-js/paint": "1.13.0",
24
- "@weasel-js/react": "1.13.0",
25
- "@weasel-js/text": "1.13.0"
22
+ "@weasel-js/font": "1.14.0",
23
+ "@weasel-js/headless": "1.14.0",
24
+ "@weasel-js/paint": "1.14.0",
25
+ "@weasel-js/react": "1.14.0",
26
+ "@weasel-js/text": "1.14.0"
26
27
  },
27
28
  "author": "orochi235",
28
29
  "homepage": "https://orochi235.github.io/weasel/",