@ascribed/review 0.4.4 → 0.4.5-next.34

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.
@@ -293,12 +293,28 @@ function charWidth(at) {
293
293
  const code = at.node.nodeValue?.codePointAt(at.offset) ?? 0;
294
294
  return code > 0xffff ? 2 : 1;
295
295
  }
296
+ /**
297
+ * The innermost element with `element`'s anchor, which holds its text: a
298
+ * one-line `@note`'s text is in a paragraph with the note's own anchor.
299
+ */
300
+ function textHolder(element) {
301
+ const source = element.getAttribute(DATA_SOURCE);
302
+ const via = viaOf(element);
303
+ let holder = element;
304
+ for (;;) {
305
+ const inner = Array.from(holder.querySelectorAll(`[${DATA_SOURCE}]`)).find((el) => el.getAttribute(DATA_SOURCE) === source && viaOf(el) === via);
306
+ if (!inner)
307
+ return holder;
308
+ holder = inner;
309
+ }
310
+ }
296
311
  /**
297
312
  * Marks the changed words of a block: the words added or replacing others
298
313
  * in `<ins>`, and the words removed in `<del>` where they were. Skipped when
299
314
  * the block's text isn't the text the change was computed from.
300
315
  */
301
- function markWords(element, words) {
316
+ function markWords(block, words) {
317
+ const element = textHolder(block);
302
318
  const map = textMap(element);
303
319
  const nowChars = Array.from(words.now_text);
304
320
  const text = map.text.join("");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/marks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CLASS_DEL,\n CLASS_FLASH,\n CLASS_HINT,\n CLASS_INS,\n CLASS_LABEL,\n CLASS_LABEL_BEFORE,\n CLASS_MARKS,\n CLASS_MOVED_FROM,\n CLASS_MOVE_AFTER,\n CLASS_MOVE_LINK,\n CLASS_MOVE_NOTE,\n CLASS_OPEN,\n CLASS_REMOVED,\n CLASS_REMOVED_BODY,\n CLASS_TOGGLE,\n CLASS_WAS_COPY,\n CLASS_WHERE,\n DATA_CHANGE,\n DATA_HAS_WAS,\n DATA_HINT,\n DATA_LABEL,\n DATA_MOVE,\n DATA_SHOW,\n DATA_SOURCE,\n DATA_UI,\n DATA_VIA,\n DATA_WAS_ONLY,\n DATA_WAS_SOURCE,\n ELEMENT_TAB,\n} from \"../names.js\";\nimport type { Anchor, Change, Words } from \"../shapes.js\";\n// @ascribed/review/marks: marks what changed on a rendered page, in the\n// browser.\n//\n// The page is Ascribe's site output rendered with source anchors (the\n// site-render contract, §7): every block's element carries\n// `data-ascribe-source`, and `data-ascribe-via` when it came through\n// includes. The changes are `ascribe diff --format json`'s, for that page.\n// `markChanges` applies them to the page's elements; `marks.css` (exported\n// as `@ascribed/review/marks.css`) draws them, and `setShow` switches between\n// the changes, the page as it will be, and the page as it was.\n//\n// Everything the marks add is an element with `data-ascribe-ui`, and every\n// element they change gets `data-ascribe-change`, so `clearMarks` can put the\n// page back as it was rendered.\n\n/** A block's change, where it's written, and its words, as `ascribe diff --format json` writes them. */\nexport type { Anchor, Change, Words } from \"../shapes.js\";\nexport { titleNodes, type FormattedPiece, type PieceKind } from \"./title.js\";\n\n/** What the page shows: its changes, the page as it will be, or as it was. */\nexport type Show = \"changes\" | \"will\" | \"was\";\n\nexport interface MarkOptions {\n /**\n * The page as it was, rendered with anchors. Removed blocks, and moved\n * blocks at their old place, are copied from it; without it they're shown\n * from the change's `text`, and \"as it was\" shows changed prose from its\n * words.\n */\n was?: ParentNode | null;\n}\n\n/** A change as marked on the page. */\nexport interface Mark {\n change: Change;\n /** The element to go to: the block now, or what stands for a removed one. */\n element: HTMLElement;\n}\n\nconst LABELS: Record<Change[\"kind\"], string> = {\n added: \"Added\",\n changed: \"Changed\",\n removed: \"Removed\",\n moved: \"Moved\",\n};\n\n/** Blocks a label can start, inline, as their first child. */\nconst LABEL_INSIDE = new Set([\n \"p\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"li\",\n \"dt\",\n \"dd\",\n \"summary\",\n \"td\",\n \"th\",\n // A tab's panel: before it would put the label among the tab list's panels.\n ELEMENT_TAB,\n]);\n\n/** A parsed anchor source: the path, decoded, and the lines. */\nexport interface Source {\n path: string;\n first: number;\n last: number;\n}\n\n/** Parses `<path>:<first>-<last>`, splitting at the last `:`. */\nexport function parseSource(source: string): Source | undefined {\n const colon = source.lastIndexOf(\":\");\n if (colon < 0) return undefined;\n const match = /^(\\d+)-(\\d+)$/.exec(source.slice(colon + 1));\n if (!match) return undefined;\n let path = source.slice(0, colon);\n try {\n path = decodeURIComponent(path);\n } catch {\n // Not percent-encoded as the grammar says; show it as it is.\n }\n return { path, first: Number(match[1]), last: Number(match[2]) };\n}\n\n/** `guides/install.md:12`, or `guides/install.md:12-14`, and its includes. */\nexport function describeSource(source: string, via?: string | null): string {\n const parsed = parseSource(source);\n let text = source;\n if (parsed) {\n const lines =\n parsed.first === parsed.last ? `${parsed.first}` : `${parsed.first}-${parsed.last}`;\n text = `${parsed.path}:${lines}`;\n }\n if (via) {\n const outer = via.split(\" \").map((v) => {\n const colon = v.lastIndexOf(\":\");\n if (colon < 0) return v;\n try {\n return `${decodeURIComponent(v.slice(0, colon))}${v.slice(colon)}`;\n } catch {\n return v;\n }\n });\n text += ` via ${outer.join(\", \")}`;\n }\n return text;\n}\n\nfunction viaOf(element: Element): string {\n return element.getAttribute(DATA_VIA) ?? \"\";\n}\n\n/**\n * The element of a block: the one with exactly its anchor, or, when there's\n * none (a paragraph in a tight list item has no element of its own), the\n * smallest anchored element with the same file and includes whose lines\n * contain it.\n */\nexport function findBlock(root: ParentNode, anchor: Anchor): HTMLElement | null {\n const via = anchor.via.join(\" \");\n const anchored = Array.from(root.querySelectorAll<HTMLElement>(`[${DATA_SOURCE}]`));\n const exact = anchored.find(\n (el) => el.getAttribute(DATA_SOURCE) === anchor.source && viaOf(el) === via,\n );\n if (exact) return exact;\n const want = parseSource(anchor.source);\n if (!want) return null;\n let best: HTMLElement | null = null;\n let bestSpan = Infinity;\n for (const el of anchored) {\n if (viaOf(el) !== via) continue;\n const has = parseSource(el.getAttribute(DATA_SOURCE) ?? \"\");\n if (!has || has.path !== want.path) continue;\n if (has.first > want.first || has.last < want.last) continue;\n const span = has.last - has.first;\n if (span < bestSpan) {\n best = el;\n bestSpan = span;\n }\n }\n return best;\n}\n\nfunction ui<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n className: string,\n text?: string,\n): HTMLElementTagNameMap[K] {\n const el = doc.createElement(tag);\n el.className = className;\n el.setAttribute(DATA_UI, \"\");\n if (text !== undefined) el.textContent = text;\n return el;\n}\n\n/** A label, inside the block at its start, or just before it. */\nfunction addLabel(element: HTMLElement, kind: Change[\"kind\"]): void {\n const doc = element.ownerDocument;\n const label = ui(doc, \"span\", CLASS_LABEL, LABELS[kind]);\n label.setAttribute(DATA_LABEL, kind);\n if (LABEL_INSIDE.has(element.localName)) {\n element.prepend(label);\n } else {\n label.classList.add(CLASS_LABEL_BEFORE);\n element.before(label);\n }\n}\n\n/**\n * What goes in `holder` to show `before`, a block of the page as it was: a\n * copy, or for an item going into an item, the copy's contents.\n */\nfunction contentOf(holder: Element, before: Element): Node[] {\n const copy = copyOf(before);\n if (holder.localName === \"li\" && copy.localName === \"li\") return Array.from(copy.childNodes);\n return [copy];\n}\n\n/** A copy of a block of the page as it was, without its anchors or ids. */\nfunction copyOf(element: Element): HTMLElement {\n const copy = element.cloneNode(true) as HTMLElement;\n for (const el of [copy, ...Array.from(copy.querySelectorAll(\"*\"))]) {\n el.removeAttribute(DATA_SOURCE);\n el.removeAttribute(DATA_VIA);\n el.removeAttribute(\"id\");\n }\n return copy;\n}\n\n/** The element to add beside `sibling`: an item in a list, else a `div`. */\nfunction holderFor(container: Element): \"li\" | \"div\" {\n return container.localName === \"ul\" || container.localName === \"ol\" ? \"li\" : \"div\";\n}\n\n/** The nearest heading before `node` in `root`, as text. */\nfunction headingBefore(root: Element, node: Node): string | undefined {\n const headings = Array.from(root.querySelectorAll(\"h1, h2, h3, h4, h5, h6\"));\n let found: Element | undefined;\n for (const heading of headings) {\n if (heading === node || heading.contains(node)) {\n found = heading;\n break;\n }\n if (heading.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING) found = heading;\n else break;\n }\n return found ? ownText(found).trim() : undefined;\n}\n\n/** An element's text without what the marks added. */\nfunction ownText(element: Element): string {\n let text = \"\";\n const walk = (node: Node): void => {\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) text += child.nodeValue ?? \"\";\n else if (child instanceof Element && !child.hasAttribute(DATA_UI)) walk(child);\n }\n };\n walk(element);\n return text.replace(/\\s+/g, \" \");\n}\n\n/** Where a removed block, or a moved block's old place, goes in the page now. */\nclass Placer {\n /** The last element placed after each block, so several stay in order. */\n #last = new Map<Element, Element>();\n #first = new Map<Element, Element>();\n\n constructor(readonly root: HTMLElement) {}\n\n /** Puts `make(container)`'s element where `change` was. */\n place(change: Change, make: (container: Element) => HTMLElement): HTMLElement {\n const after = change.after ? findBlock(this.root, change.after) : null;\n const parent = change.parent ? findBlock(this.root, change.parent) : null;\n if (after && after !== parent && after.parentElement) {\n let previous: Element = this.#last.get(after) ?? after;\n // Past what the marks put after the block itself: its copy as it\n // was, or its \"moved from\" link.\n for (\n let next = previous.nextElementSibling;\n next && (next.hasAttribute(DATA_WAS_ONLY) || next.classList.contains(CLASS_MOVE_AFTER));\n next = next.nextElementSibling\n ) {\n previous = next;\n }\n const el = make(after.parentElement);\n // A label before the next block belongs to that block, so this goes\n // before it.\n previous.after(el);\n this.#last.set(after, el);\n return el;\n }\n const container = parent ?? this.root;\n const el = make(container);\n const previous = this.#first.get(container);\n if (previous) {\n previous.after(el);\n } else {\n // First among the container's blocks: before its first anchored\n // child, or its first label, or at its end.\n const first = Array.from(container.children).find(\n (c) => c.hasAttribute(DATA_SOURCE) || c.hasAttribute(DATA_UI),\n );\n if (first) first.before(el);\n else container.append(el);\n }\n this.#first.set(container, el);\n return el;\n }\n}\n\n/** A text position: the text node, and the offset in it in UTF-16 units. */\ninterface At {\n node: Text;\n offset: number;\n}\n\n/**\n * The block's own text, whitespace collapsed as `ascribe diff` collapses it,\n * with where each character is: text inside the block's anchored children,\n * which are blocks of their own, and inside what the marks added, isn't its.\n */\nfunction textMap(element: Element): { text: string[]; at: At[] } {\n const chars: string[] = [];\n const at: At[] = [];\n let space = false;\n let spaceAt: At | undefined;\n const walk = (node: Node): void => {\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n const value = (child as Text).nodeValue ?? \"\";\n let offset = 0;\n for (const ch of value) {\n if (/\\s/.test(ch)) {\n if (!space) spaceAt = { node: child as Text, offset };\n space = true;\n } else {\n if (space && chars.length > 0 && spaceAt) {\n chars.push(\" \");\n at.push(spaceAt);\n }\n space = false;\n chars.push(ch);\n at.push({ node: child as Text, offset });\n }\n offset += ch.length;\n }\n } else if (\n child instanceof Element &&\n !child.hasAttribute(DATA_UI) &&\n !child.hasAttribute(DATA_SOURCE)\n ) {\n walk(child);\n }\n }\n };\n walk(element);\n return { text: chars, at };\n}\n\n/** Wraps characters `[start, end)` of the map in elements made by `make`. */\nfunction wrapRange(map: { at: At[] }, start: number, end: number, make: () => HTMLElement): void {\n // Each text node's part of the range, wrapped by itself, last first so\n // earlier offsets stay right.\n const parts: { node: Text; from: number; to: number }[] = [];\n for (let i = start; i < end; i++) {\n const at = map.at[i];\n if (!at) continue;\n const width = charWidth(at);\n const part = parts[parts.length - 1];\n if (part && part.node === at.node) part.to = at.offset + width;\n else parts.push({ node: at.node, from: at.offset, to: at.offset + width });\n }\n for (const part of parts.reverse()) {\n const range = part.node.ownerDocument.createRange();\n range.setStart(part.node, part.from);\n range.setEnd(part.node, part.to);\n const wrapper = make();\n range.surroundContents(wrapper);\n }\n}\n\nfunction charWidth(at: At): number {\n const code = at.node.nodeValue?.codePointAt(at.offset) ?? 0;\n return code > 0xffff ? 2 : 1;\n}\n\n/**\n * Marks the changed words of a block: the words added or replacing others\n * in `<ins>`, and the words removed in `<del>` where they were. Skipped when\n * the block's text isn't the text the change was computed from.\n */\nfunction markWords(element: HTMLElement, words: Words): boolean {\n const map = textMap(element);\n const nowChars = Array.from(words.now_text);\n const text = map.text.join(\"\");\n const offset = text === words.now_text ? 0 : findChars(map.text, nowChars);\n if (offset < 0) return false;\n const doc = element.ownerDocument;\n const wasChars = Array.from(words.was_text);\n // Each removed run goes where it was: after as many unchanged characters\n // of the new text as there were before it in the old.\n const insertions: { at: number; text: string }[] = [];\n let removedBefore = 0;\n for (const [start, end] of words.was) {\n const unchangedBefore = start - removedBefore;\n insertions.push({\n at: nowPosition(words.now, unchangedBefore),\n text: wasChars.slice(start, end).join(\"\"),\n });\n removedBefore += end - start;\n }\n // Wrap from the end so earlier positions stay valid.\n type Edit = { at: number; kind: \"ins\"; end: number } | { at: number; kind: \"del\"; text: string };\n const edits: Edit[] = [\n ...words.now.map(([start, end]): Edit => ({ at: start, kind: \"ins\", end })),\n ...insertions.map((i): Edit => ({ at: i.at, kind: \"del\", text: i.text })),\n ];\n // At one position, the removed words go first, before the words that\n // replace them.\n edits.sort((a, b) => b.at - a.at || (a.kind === \"del\" ? -1 : 1));\n for (const edit of edits) {\n if (edit.kind === \"ins\") {\n wrapRange(map, offset + edit.at, offset + edit.end, () => ui(doc, \"ins\", CLASS_INS));\n } else {\n const del = ui(doc, \"del\", CLASS_DEL, edit.text);\n insertAt(map, offset + edit.at, del, element);\n }\n }\n return true;\n}\n\n/** Where in the new text `unchanged` unchanged characters end. */\nfunction nowPosition(ranges: [number, number][], unchanged: number): number {\n let position = unchanged;\n for (const [start, end] of ranges) {\n if (start < position) position += end - start;\n else break;\n }\n return position;\n}\n\nfunction findChars(haystack: string[], needle: string[]): number {\n if (needle.length === 0) return -1;\n outer: for (let i = 0; i + needle.length <= haystack.length; i++) {\n for (let j = 0; j < needle.length; j++) if (haystack[i + j] !== needle[j]) continue outer;\n return i;\n }\n return -1;\n}\n\n/** Inserts `node` before character `index` of the map, or at its end. */\nfunction insertAt(map: { at: At[] }, index: number, node: Node, element: Element): void {\n const at = map.at[index];\n if (at) {\n const rest = at.node.splitText(at.offset);\n rest.before(node);\n // The map's later positions in this node now point into `rest`.\n for (let i = index; i < map.at.length; i++) {\n const later = map.at[i];\n if (later && later.node === at.node && later.offset >= at.offset) {\n map.at[i] = { node: rest, offset: later.offset - at.offset };\n }\n }\n return;\n }\n const last = map.at[map.at.length - 1];\n if (last) {\n const rest = last.node.splitText(last.offset + charWidth(last));\n rest.before(node);\n } else {\n element.append(node);\n }\n}\n\n/**\n * Marks `changes` on the page in `root`, and returns the marks in page\n * order. Marks already there are cleared first.\n */\nexport function markChanges(\n root: HTMLElement,\n changes: readonly Change[],\n options: MarkOptions = {},\n): Mark[] {\n clearMarks(root);\n const doc = root.ownerDocument;\n const was = options.was ?? null;\n const placer = new Placer(root);\n const marks: Mark[] = [];\n root.classList.add(CLASS_MARKS);\n if (!root.hasAttribute(DATA_SHOW)) root.setAttribute(DATA_SHOW, \"changes\");\n\n let moveCount = 0;\n for (const change of changes) {\n switch (change.kind) {\n case \"added\":\n case \"changed\": {\n const element = change.now ? findBlock(root, change.now) : null;\n if (!element || element.hasAttribute(DATA_CHANGE)) break;\n element.setAttribute(DATA_CHANGE, change.kind);\n addLabel(element, change.kind);\n if (change.kind === \"changed\") {\n // Where it was, for threads on its old text.\n if (change.was) element.setAttribute(DATA_WAS_SOURCE, change.was.source);\n const before = was && change.was ? findBlock(was, change.was) : null;\n if (change.words) markWords(element, change.words);\n if (before) {\n // As it was, the block as the old page rendered it.\n const copy = copyOf(before);\n copy.setAttribute(DATA_UI, \"\");\n copy.setAttribute(DATA_WAS_ONLY, \"\");\n element.after(copy);\n element.setAttribute(DATA_HAS_WAS, \"\");\n }\n }\n marks.push({ change, element });\n break;\n }\n case \"removed\": {\n const before = was && change.was ? findBlock(was, change.was) : null;\n const element = placer.place(change, (container) => {\n const holder = ui(doc, holderFor(container), CLASS_REMOVED);\n holder.setAttribute(DATA_CHANGE, \"removed\");\n if (change.was) holder.setAttribute(DATA_WAS_SOURCE, change.was.source);\n const label = ui(doc, \"span\", CLASS_LABEL, LABELS.removed);\n label.setAttribute(DATA_LABEL, \"removed\");\n const body = ui(doc, \"div\", CLASS_REMOVED_BODY);\n if (before) body.append(...contentOf(holder, before));\n else body.textContent = change.text ?? \"\";\n const toggle = ui(doc, \"button\", CLASS_TOGGLE, \"Show\");\n toggle.type = \"button\";\n toggle.setAttribute(\"aria-expanded\", \"false\");\n toggle.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n const open = holder.classList.toggle(CLASS_OPEN);\n toggle.textContent = open ? \"Collapse\" : \"Show\";\n toggle.setAttribute(\"aria-expanded\", String(open));\n });\n holder.append(label, body, toggle);\n return holder;\n });\n marks.push({ change, element });\n break;\n }\n case \"moved\": {\n const element = change.now ? findBlock(root, change.now) : null;\n if (!element || element.hasAttribute(DATA_CHANGE)) break;\n const id = `ascribe-move-${++moveCount}`;\n const before = was && change.was ? findBlock(was, change.was) : null;\n const stub = placer.place(change, (container) => {\n const holder = ui(doc, holderFor(container), CLASS_MOVED_FROM);\n holder.id = `${id}-from`;\n holder.setAttribute(DATA_CHANGE, \"moved-from\");\n if (change.was) holder.setAttribute(DATA_WAS_SOURCE, change.was.source);\n const note = ui(doc, \"span\", CLASS_MOVE_NOTE);\n note.append(doc.createTextNode(`A ${blockWord(element)} moved from here `));\n const link = ui(doc, \"a\", CLASS_MOVE_LINK);\n link.href = `#${id}`;\n note.append(link);\n holder.append(note);\n // As it was, the block itself.\n const copy = ui(doc, \"div\", CLASS_WAS_COPY);\n copy.setAttribute(DATA_WAS_ONLY, \"\");\n if (before) copy.append(...contentOf(holder, before));\n else copy.textContent = change.text ?? ownText(element);\n holder.append(copy);\n return holder;\n });\n element.setAttribute(DATA_CHANGE, \"moved\");\n element.setAttribute(DATA_MOVE, id);\n if (!element.id) element.id = id;\n addLabel(element, \"moved\");\n const back = ui(doc, \"a\", CLASS_MOVE_LINK);\n back.href = `#${stub.id}`;\n back.textContent = `from “${headingBefore(root, stub) ?? \"the top of the page\"}” ↑`;\n const forward = stub.querySelector<HTMLAnchorElement>(`.${CLASS_MOVE_LINK}`);\n if (forward) {\n forward.href = `#${element.id}`;\n forward.textContent = `to “${headingBefore(root, element) ?? \"the top of the page\"}” ↓`;\n }\n if (LABEL_INSIDE.has(element.localName)) {\n const note = ui(doc, \"span\", CLASS_MOVE_NOTE);\n note.append(\" \", back);\n element.append(note);\n } else {\n const holder = ui(doc, \"div\", `${CLASS_MOVE_NOTE} ${CLASS_MOVE_AFTER}`);\n holder.append(back);\n element.after(holder);\n }\n for (const link of [back, forward]) {\n link?.addEventListener(\"click\", (event) => {\n const target = doc.getElementById(link.hash.slice(1));\n if (!target || !root.contains(target)) return;\n event.preventDefault();\n goTo(target);\n });\n }\n marks.push({ change, element });\n break;\n }\n }\n }\n marks.sort((a, b) =>\n a.element === b.element\n ? 0\n : a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING\n ? -1\n : 1,\n );\n hintHidden(root, marks);\n return marks;\n}\n\n/**\n * Says on each tab's label, and on each `<details>`' summary, what's changed\n * in what they can hide: \"new\" for a tab that's added, else how many\n * changes. A tab that isn't selected, or a closed `<details>`, would\n * otherwise hide its changes until stepped to.\n */\nfunction hintHidden(root: HTMLElement, marks: readonly Mark[]): void {\n const tabs = new Map<HTMLElement, { added: boolean; count: number }>();\n const summaries = new Map<HTMLElement, number>();\n for (const { change, element } of marks) {\n for (let el: HTMLElement | null = element; el && el !== root; el = el.parentElement) {\n if (el.localName === ELEMENT_TAB) {\n const tab = tabs.get(el) ?? { added: false, count: 0 };\n if (el === element && change.kind === \"added\") tab.added = true;\n else tab.count++;\n tabs.set(el, tab);\n }\n const summary = el !== element ? summaryOf(el) : null;\n if (summary && !summary.contains(element)) {\n summaries.set(summary, (summaries.get(summary) ?? 0) + 1);\n }\n }\n }\n const doc = root.ownerDocument;\n const hint = (kind: \"added\" | \"changed\", text: string): HTMLElement => {\n // A space before it, not only a margin, so the label reads \"Linux 1\n // change\" to a screen reader, not \"Linux1 change\".\n const el = ui(doc, \"span\", CLASS_HINT, ` ${text}`);\n el.setAttribute(DATA_HINT, kind);\n return el;\n };\n const watching: MutationObserver[] = [];\n for (const [tab, { added, count }] of tabs) {\n const el = added ? hint(\"added\", \"new\") : hint(\"changed\", plural(count, \"change\"));\n const place = (): void => {\n const button = tabButton(tab);\n if (button && !button.contains(el)) button.append(el);\n };\n place();\n // `@ascribed/elements` makes the tab list once the page has loaded, and\n // again when the tabs are put back in the page.\n const group = tab.parentElement;\n const Observer = doc.defaultView?.MutationObserver;\n if (group && Observer) {\n const observer = new Observer(place);\n observer.observe(group, { childList: true });\n watching.push(observer);\n }\n }\n if (watching.length > 0) tabWatchers.set(root, watching);\n for (const [summary, count] of summaries)\n summary.append(hint(\"changed\", plural(count, \"change\")));\n}\n\n/** What waits for each marked page's tab lists, to stop when it's cleared. */\nconst tabWatchers = new WeakMap<HTMLElement, MutationObserver[]>();\n\nfunction plural(count: number, word: string): string {\n return `${count} ${word}${count === 1 ? \"\" : \"s\"}`;\n}\n\n/** A `<details>`' own `<summary>`, or null when `element` isn't one. */\nfunction summaryOf(element: Element): HTMLElement | null {\n if (element.localName !== \"details\") return null;\n return element.querySelector<HTMLElement>(\":scope > summary\");\n}\n\n/**\n * The button that selects an `<ascribe-tab>`, in its group's tab list, or\n * null before `@ascribed/elements` has made the list.\n */\nexport function tabButton(tab: Element): HTMLButtonElement | null {\n const group = tab.parentElement;\n if (tab.localName !== ELEMENT_TAB || !group) return null;\n const tabs = Array.from(group.children).filter((c) => c.localName === ELEMENT_TAB);\n const buttons = group.querySelectorAll<HTMLButtonElement>(\n ':scope > [role=\"tablist\"] > [role=\"tab\"]',\n );\n return buttons[tabs.indexOf(tab)] ?? null;\n}\n\n/** \"paragraph\", \"heading\", \"list\", or \"block\". */\nfunction blockWord(element: Element): string {\n const name = element.localName;\n if (name === \"p\") return \"paragraph\";\n if (/^h[1-6]$/.test(name)) return \"heading\";\n if (name === \"ul\" || name === \"ol\") return \"list\";\n if (name === \"li\") return \"list item\";\n if (name === \"pre\") return \"code block\";\n if (name === \"table\") return \"table\";\n return \"block\";\n}\n\n/** Removes every mark from the page in `root`. */\nexport function clearMarks(root: HTMLElement): void {\n for (const observer of tabWatchers.get(root) ?? []) observer.disconnect();\n tabWatchers.delete(root);\n for (const el of Array.from(root.querySelectorAll(`[${DATA_UI}]`))) {\n if (el.localName === \"ins\") el.replaceWith(...Array.from(el.childNodes));\n else el.remove();\n }\n for (const el of Array.from(root.querySelectorAll(`[${DATA_CHANGE}]`))) {\n el.removeAttribute(DATA_CHANGE);\n el.removeAttribute(DATA_HAS_WAS);\n el.removeAttribute(DATA_WAS_SOURCE);\n if (el.hasAttribute(DATA_MOVE)) {\n if (el.id === el.getAttribute(DATA_MOVE)) el.removeAttribute(\"id\");\n el.removeAttribute(DATA_MOVE);\n }\n }\n root.normalize();\n}\n\n/** Shows the changes, the page as it will be, or the page as it was. */\nexport function setShow(root: HTMLElement, show: Show): void {\n root.setAttribute(DATA_SHOW, show);\n}\n\n/**\n * Makes `element` visible: opens the `<details>` and selects the tabs it's\n * in.\n */\nexport function reveal(element: HTMLElement): void {\n for (let el: HTMLElement | null = element; el; el = el.parentElement) {\n if (el instanceof HTMLDetailsElement && !el.open) el.open = true;\n if (el.localName === ELEMENT_TAB && el.hidden) tabButton(el)?.click();\n }\n}\n\n/** Reveals `element`, scrolls to it, and flashes it. */\nexport function goTo(element: HTMLElement): void {\n reveal(element);\n // Not every DOM implements scrolling (jsdom doesn't).\n if (typeof element.scrollIntoView === \"function\") {\n element.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n }\n element.classList.remove(CLASS_FLASH);\n // Restart the animation.\n void element.offsetWidth;\n element.classList.add(CLASS_FLASH);\n if (!element.hasAttribute(\"tabindex\")) element.setAttribute(\"tabindex\", \"-1\");\n element.focus({ preventScroll: true });\n}\n\n/**\n * Shows each block's source on hover and focus: `guides/install.md:12`,\n * from its anchor. Returns a function that stops.\n */\nexport function showSources(root: HTMLElement): () => void {\n const doc = root.ownerDocument;\n const tip = ui(doc, \"span\", CLASS_WHERE);\n tip.setAttribute(\"role\", \"status\");\n let current: Element | null = null;\n const show = (target: EventTarget | null): void => {\n const el =\n target instanceof Element ? target.closest(`[${DATA_SOURCE}], [${DATA_WAS_SOURCE}]`) : null;\n if (el === current) return;\n current = el;\n if (!el || !root.contains(el)) {\n tip.remove();\n current = null;\n return;\n }\n const source = el.getAttribute(DATA_SOURCE);\n tip.textContent = source\n ? describeSource(source, el.getAttribute(DATA_VIA))\n : `was ${describeSource(el.getAttribute(DATA_WAS_SOURCE) ?? \"\")}`;\n const box = el.getBoundingClientRect();\n const host = root.getBoundingClientRect();\n tip.style.top = `${box.top - host.top}px`;\n root.append(tip);\n };\n const over = (event: Event): void => show(event.target);\n const out = (event: Event): void => {\n const to = (event as MouseEvent).relatedTarget;\n if (!(to instanceof Node) || !root.contains(to)) show(null);\n };\n root.addEventListener(\"mouseover\", over);\n root.addEventListener(\"focusin\", over);\n root.addEventListener(\"mouseout\", out);\n return () => {\n root.removeEventListener(\"mouseover\", over);\n root.removeEventListener(\"focusin\", over);\n root.removeEventListener(\"mouseout\", out);\n tip.remove();\n };\n}\n\n/**\n * Takes out of a page's HTML what could run script or take the reader\n * elsewhere: scripts, `<meta>` and `<base>`, event handler attributes, and\n * `javascript:` URLs. A page under review comes from the change being\n * reviewed, so a host disarms it before showing it, whatever its content\n * security policy also blocks.\n */\nexport function disarm(fragment: DocumentFragment): void {\n for (const el of Array.from(fragment.querySelectorAll(\"script, meta, base\"))) el.remove();\n for (const el of Array.from(fragment.querySelectorAll(\"*\"))) {\n for (const attr of Array.from(el.attributes)) {\n if (/^on/i.test(attr.name) || runsScript(attr.value)) el.removeAttribute(attr.name);\n }\n }\n}\n\n/** Whether a URL runs script: `javascript:`, however it's spaced or cased. */\nfunction runsScript(value: string): boolean {\n // URL parsing drops ASCII whitespace and control characters first.\n const kept = Array.from(value)\n .filter((ch) => ch.charCodeAt(0) > 0x20)\n .join(\"\");\n return /^javascript:/i.test(kept);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/marks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CLASS_DEL,\n CLASS_FLASH,\n CLASS_HINT,\n CLASS_INS,\n CLASS_LABEL,\n CLASS_LABEL_BEFORE,\n CLASS_MARKS,\n CLASS_MOVED_FROM,\n CLASS_MOVE_AFTER,\n CLASS_MOVE_LINK,\n CLASS_MOVE_NOTE,\n CLASS_OPEN,\n CLASS_REMOVED,\n CLASS_REMOVED_BODY,\n CLASS_TOGGLE,\n CLASS_WAS_COPY,\n CLASS_WHERE,\n DATA_CHANGE,\n DATA_HAS_WAS,\n DATA_HINT,\n DATA_LABEL,\n DATA_MOVE,\n DATA_SHOW,\n DATA_SOURCE,\n DATA_UI,\n DATA_VIA,\n DATA_WAS_ONLY,\n DATA_WAS_SOURCE,\n ELEMENT_TAB,\n} from \"../names.js\";\nimport type { Anchor, Change, Words } from \"../shapes.js\";\n// @ascribed/review/marks: marks what changed on a rendered page, in the\n// browser.\n//\n// The page is Ascribe's site output rendered with source anchors (the\n// site-render contract, §7): every block's element carries\n// `data-ascribe-source`, and `data-ascribe-via` when it came through\n// includes. The changes are `ascribe diff --format json`'s, for that page.\n// `markChanges` applies them to the page's elements; `marks.css` (exported\n// as `@ascribed/review/marks.css`) draws them, and `setShow` switches between\n// the changes, the page as it will be, and the page as it was.\n//\n// Everything the marks add is an element with `data-ascribe-ui`, and every\n// element they change gets `data-ascribe-change`, so `clearMarks` can put the\n// page back as it was rendered.\n\n/** A block's change, where it's written, and its words, as `ascribe diff --format json` writes them. */\nexport type { Anchor, Change, Words } from \"../shapes.js\";\nexport { titleNodes, type FormattedPiece, type PieceKind } from \"./title.js\";\n\n/** What the page shows: its changes, the page as it will be, or as it was. */\nexport type Show = \"changes\" | \"will\" | \"was\";\n\nexport interface MarkOptions {\n /**\n * The page as it was, rendered with anchors. Removed blocks, and moved\n * blocks at their old place, are copied from it; without it they're shown\n * from the change's `text`, and \"as it was\" shows changed prose from its\n * words.\n */\n was?: ParentNode | null;\n}\n\n/** A change as marked on the page. */\nexport interface Mark {\n change: Change;\n /** The element to go to: the block now, or what stands for a removed one. */\n element: HTMLElement;\n}\n\nconst LABELS: Record<Change[\"kind\"], string> = {\n added: \"Added\",\n changed: \"Changed\",\n removed: \"Removed\",\n moved: \"Moved\",\n};\n\n/** Blocks a label can start, inline, as their first child. */\nconst LABEL_INSIDE = new Set([\n \"p\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"li\",\n \"dt\",\n \"dd\",\n \"summary\",\n \"td\",\n \"th\",\n // A tab's panel: before it would put the label among the tab list's panels.\n ELEMENT_TAB,\n]);\n\n/** A parsed anchor source: the path, decoded, and the lines. */\nexport interface Source {\n path: string;\n first: number;\n last: number;\n}\n\n/** Parses `<path>:<first>-<last>`, splitting at the last `:`. */\nexport function parseSource(source: string): Source | undefined {\n const colon = source.lastIndexOf(\":\");\n if (colon < 0) return undefined;\n const match = /^(\\d+)-(\\d+)$/.exec(source.slice(colon + 1));\n if (!match) return undefined;\n let path = source.slice(0, colon);\n try {\n path = decodeURIComponent(path);\n } catch {\n // Not percent-encoded as the grammar says; show it as it is.\n }\n return { path, first: Number(match[1]), last: Number(match[2]) };\n}\n\n/** `guides/install.md:12`, or `guides/install.md:12-14`, and its includes. */\nexport function describeSource(source: string, via?: string | null): string {\n const parsed = parseSource(source);\n let text = source;\n if (parsed) {\n const lines =\n parsed.first === parsed.last ? `${parsed.first}` : `${parsed.first}-${parsed.last}`;\n text = `${parsed.path}:${lines}`;\n }\n if (via) {\n const outer = via.split(\" \").map((v) => {\n const colon = v.lastIndexOf(\":\");\n if (colon < 0) return v;\n try {\n return `${decodeURIComponent(v.slice(0, colon))}${v.slice(colon)}`;\n } catch {\n return v;\n }\n });\n text += ` via ${outer.join(\", \")}`;\n }\n return text;\n}\n\nfunction viaOf(element: Element): string {\n return element.getAttribute(DATA_VIA) ?? \"\";\n}\n\n/**\n * The element of a block: the one with exactly its anchor, or, when there's\n * none (a paragraph in a tight list item has no element of its own), the\n * smallest anchored element with the same file and includes whose lines\n * contain it.\n */\nexport function findBlock(root: ParentNode, anchor: Anchor): HTMLElement | null {\n const via = anchor.via.join(\" \");\n const anchored = Array.from(root.querySelectorAll<HTMLElement>(`[${DATA_SOURCE}]`));\n const exact = anchored.find(\n (el) => el.getAttribute(DATA_SOURCE) === anchor.source && viaOf(el) === via,\n );\n if (exact) return exact;\n const want = parseSource(anchor.source);\n if (!want) return null;\n let best: HTMLElement | null = null;\n let bestSpan = Infinity;\n for (const el of anchored) {\n if (viaOf(el) !== via) continue;\n const has = parseSource(el.getAttribute(DATA_SOURCE) ?? \"\");\n if (!has || has.path !== want.path) continue;\n if (has.first > want.first || has.last < want.last) continue;\n const span = has.last - has.first;\n if (span < bestSpan) {\n best = el;\n bestSpan = span;\n }\n }\n return best;\n}\n\nfunction ui<K extends keyof HTMLElementTagNameMap>(\n doc: Document,\n tag: K,\n className: string,\n text?: string,\n): HTMLElementTagNameMap[K] {\n const el = doc.createElement(tag);\n el.className = className;\n el.setAttribute(DATA_UI, \"\");\n if (text !== undefined) el.textContent = text;\n return el;\n}\n\n/** A label, inside the block at its start, or just before it. */\nfunction addLabel(element: HTMLElement, kind: Change[\"kind\"]): void {\n const doc = element.ownerDocument;\n const label = ui(doc, \"span\", CLASS_LABEL, LABELS[kind]);\n label.setAttribute(DATA_LABEL, kind);\n if (LABEL_INSIDE.has(element.localName)) {\n element.prepend(label);\n } else {\n label.classList.add(CLASS_LABEL_BEFORE);\n element.before(label);\n }\n}\n\n/**\n * What goes in `holder` to show `before`, a block of the page as it was: a\n * copy, or for an item going into an item, the copy's contents.\n */\nfunction contentOf(holder: Element, before: Element): Node[] {\n const copy = copyOf(before);\n if (holder.localName === \"li\" && copy.localName === \"li\") return Array.from(copy.childNodes);\n return [copy];\n}\n\n/** A copy of a block of the page as it was, without its anchors or ids. */\nfunction copyOf(element: Element): HTMLElement {\n const copy = element.cloneNode(true) as HTMLElement;\n for (const el of [copy, ...Array.from(copy.querySelectorAll(\"*\"))]) {\n el.removeAttribute(DATA_SOURCE);\n el.removeAttribute(DATA_VIA);\n el.removeAttribute(\"id\");\n }\n return copy;\n}\n\n/** The element to add beside `sibling`: an item in a list, else a `div`. */\nfunction holderFor(container: Element): \"li\" | \"div\" {\n return container.localName === \"ul\" || container.localName === \"ol\" ? \"li\" : \"div\";\n}\n\n/** The nearest heading before `node` in `root`, as text. */\nfunction headingBefore(root: Element, node: Node): string | undefined {\n const headings = Array.from(root.querySelectorAll(\"h1, h2, h3, h4, h5, h6\"));\n let found: Element | undefined;\n for (const heading of headings) {\n if (heading === node || heading.contains(node)) {\n found = heading;\n break;\n }\n if (heading.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING) found = heading;\n else break;\n }\n return found ? ownText(found).trim() : undefined;\n}\n\n/** An element's text without what the marks added. */\nfunction ownText(element: Element): string {\n let text = \"\";\n const walk = (node: Node): void => {\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) text += child.nodeValue ?? \"\";\n else if (child instanceof Element && !child.hasAttribute(DATA_UI)) walk(child);\n }\n };\n walk(element);\n return text.replace(/\\s+/g, \" \");\n}\n\n/** Where a removed block, or a moved block's old place, goes in the page now. */\nclass Placer {\n /** The last element placed after each block, so several stay in order. */\n #last = new Map<Element, Element>();\n #first = new Map<Element, Element>();\n\n constructor(readonly root: HTMLElement) {}\n\n /** Puts `make(container)`'s element where `change` was. */\n place(change: Change, make: (container: Element) => HTMLElement): HTMLElement {\n const after = change.after ? findBlock(this.root, change.after) : null;\n const parent = change.parent ? findBlock(this.root, change.parent) : null;\n if (after && after !== parent && after.parentElement) {\n let previous: Element = this.#last.get(after) ?? after;\n // Past what the marks put after the block itself: its copy as it\n // was, or its \"moved from\" link.\n for (\n let next = previous.nextElementSibling;\n next && (next.hasAttribute(DATA_WAS_ONLY) || next.classList.contains(CLASS_MOVE_AFTER));\n next = next.nextElementSibling\n ) {\n previous = next;\n }\n const el = make(after.parentElement);\n // A label before the next block belongs to that block, so this goes\n // before it.\n previous.after(el);\n this.#last.set(after, el);\n return el;\n }\n const container = parent ?? this.root;\n const el = make(container);\n const previous = this.#first.get(container);\n if (previous) {\n previous.after(el);\n } else {\n // First among the container's blocks: before its first anchored\n // child, or its first label, or at its end.\n const first = Array.from(container.children).find(\n (c) => c.hasAttribute(DATA_SOURCE) || c.hasAttribute(DATA_UI),\n );\n if (first) first.before(el);\n else container.append(el);\n }\n this.#first.set(container, el);\n return el;\n }\n}\n\n/** A text position: the text node, and the offset in it in UTF-16 units. */\ninterface At {\n node: Text;\n offset: number;\n}\n\n/**\n * The block's own text, whitespace collapsed as `ascribe diff` collapses it,\n * with where each character is: text inside the block's anchored children,\n * which are blocks of their own, and inside what the marks added, isn't its.\n */\nfunction textMap(element: Element): { text: string[]; at: At[] } {\n const chars: string[] = [];\n const at: At[] = [];\n let space = false;\n let spaceAt: At | undefined;\n const walk = (node: Node): void => {\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n const value = (child as Text).nodeValue ?? \"\";\n let offset = 0;\n for (const ch of value) {\n if (/\\s/.test(ch)) {\n if (!space) spaceAt = { node: child as Text, offset };\n space = true;\n } else {\n if (space && chars.length > 0 && spaceAt) {\n chars.push(\" \");\n at.push(spaceAt);\n }\n space = false;\n chars.push(ch);\n at.push({ node: child as Text, offset });\n }\n offset += ch.length;\n }\n } else if (\n child instanceof Element &&\n !child.hasAttribute(DATA_UI) &&\n !child.hasAttribute(DATA_SOURCE)\n ) {\n walk(child);\n }\n }\n };\n walk(element);\n return { text: chars, at };\n}\n\n/** Wraps characters `[start, end)` of the map in elements made by `make`. */\nfunction wrapRange(map: { at: At[] }, start: number, end: number, make: () => HTMLElement): void {\n // Each text node's part of the range, wrapped by itself, last first so\n // earlier offsets stay right.\n const parts: { node: Text; from: number; to: number }[] = [];\n for (let i = start; i < end; i++) {\n const at = map.at[i];\n if (!at) continue;\n const width = charWidth(at);\n const part = parts[parts.length - 1];\n if (part && part.node === at.node) part.to = at.offset + width;\n else parts.push({ node: at.node, from: at.offset, to: at.offset + width });\n }\n for (const part of parts.reverse()) {\n const range = part.node.ownerDocument.createRange();\n range.setStart(part.node, part.from);\n range.setEnd(part.node, part.to);\n const wrapper = make();\n range.surroundContents(wrapper);\n }\n}\n\nfunction charWidth(at: At): number {\n const code = at.node.nodeValue?.codePointAt(at.offset) ?? 0;\n return code > 0xffff ? 2 : 1;\n}\n\n/**\n * The innermost element with `element`'s anchor, which holds its text: a\n * one-line `@note`'s text is in a paragraph with the note's own anchor.\n */\nfunction textHolder(element: HTMLElement): HTMLElement {\n const source = element.getAttribute(DATA_SOURCE);\n const via = viaOf(element);\n let holder = element;\n for (;;) {\n const inner = Array.from(holder.querySelectorAll<HTMLElement>(`[${DATA_SOURCE}]`)).find(\n (el) => el.getAttribute(DATA_SOURCE) === source && viaOf(el) === via,\n );\n if (!inner) return holder;\n holder = inner;\n }\n}\n\n/**\n * Marks the changed words of a block: the words added or replacing others\n * in `<ins>`, and the words removed in `<del>` where they were. Skipped when\n * the block's text isn't the text the change was computed from.\n */\nfunction markWords(block: HTMLElement, words: Words): boolean {\n const element = textHolder(block);\n const map = textMap(element);\n const nowChars = Array.from(words.now_text);\n const text = map.text.join(\"\");\n const offset = text === words.now_text ? 0 : findChars(map.text, nowChars);\n if (offset < 0) return false;\n const doc = element.ownerDocument;\n const wasChars = Array.from(words.was_text);\n // Each removed run goes where it was: after as many unchanged characters\n // of the new text as there were before it in the old.\n const insertions: { at: number; text: string }[] = [];\n let removedBefore = 0;\n for (const [start, end] of words.was) {\n const unchangedBefore = start - removedBefore;\n insertions.push({\n at: nowPosition(words.now, unchangedBefore),\n text: wasChars.slice(start, end).join(\"\"),\n });\n removedBefore += end - start;\n }\n // Wrap from the end so earlier positions stay valid.\n type Edit = { at: number; kind: \"ins\"; end: number } | { at: number; kind: \"del\"; text: string };\n const edits: Edit[] = [\n ...words.now.map(([start, end]): Edit => ({ at: start, kind: \"ins\", end })),\n ...insertions.map((i): Edit => ({ at: i.at, kind: \"del\", text: i.text })),\n ];\n // At one position, the removed words go first, before the words that\n // replace them.\n edits.sort((a, b) => b.at - a.at || (a.kind === \"del\" ? -1 : 1));\n for (const edit of edits) {\n if (edit.kind === \"ins\") {\n wrapRange(map, offset + edit.at, offset + edit.end, () => ui(doc, \"ins\", CLASS_INS));\n } else {\n const del = ui(doc, \"del\", CLASS_DEL, edit.text);\n insertAt(map, offset + edit.at, del, element);\n }\n }\n return true;\n}\n\n/** Where in the new text `unchanged` unchanged characters end. */\nfunction nowPosition(ranges: [number, number][], unchanged: number): number {\n let position = unchanged;\n for (const [start, end] of ranges) {\n if (start < position) position += end - start;\n else break;\n }\n return position;\n}\n\nfunction findChars(haystack: string[], needle: string[]): number {\n if (needle.length === 0) return -1;\n outer: for (let i = 0; i + needle.length <= haystack.length; i++) {\n for (let j = 0; j < needle.length; j++) if (haystack[i + j] !== needle[j]) continue outer;\n return i;\n }\n return -1;\n}\n\n/** Inserts `node` before character `index` of the map, or at its end. */\nfunction insertAt(map: { at: At[] }, index: number, node: Node, element: Element): void {\n const at = map.at[index];\n if (at) {\n const rest = at.node.splitText(at.offset);\n rest.before(node);\n // The map's later positions in this node now point into `rest`.\n for (let i = index; i < map.at.length; i++) {\n const later = map.at[i];\n if (later && later.node === at.node && later.offset >= at.offset) {\n map.at[i] = { node: rest, offset: later.offset - at.offset };\n }\n }\n return;\n }\n const last = map.at[map.at.length - 1];\n if (last) {\n const rest = last.node.splitText(last.offset + charWidth(last));\n rest.before(node);\n } else {\n element.append(node);\n }\n}\n\n/**\n * Marks `changes` on the page in `root`, and returns the marks in page\n * order. Marks already there are cleared first.\n */\nexport function markChanges(\n root: HTMLElement,\n changes: readonly Change[],\n options: MarkOptions = {},\n): Mark[] {\n clearMarks(root);\n const doc = root.ownerDocument;\n const was = options.was ?? null;\n const placer = new Placer(root);\n const marks: Mark[] = [];\n root.classList.add(CLASS_MARKS);\n if (!root.hasAttribute(DATA_SHOW)) root.setAttribute(DATA_SHOW, \"changes\");\n\n let moveCount = 0;\n for (const change of changes) {\n switch (change.kind) {\n case \"added\":\n case \"changed\": {\n const element = change.now ? findBlock(root, change.now) : null;\n if (!element || element.hasAttribute(DATA_CHANGE)) break;\n element.setAttribute(DATA_CHANGE, change.kind);\n addLabel(element, change.kind);\n if (change.kind === \"changed\") {\n // Where it was, for threads on its old text.\n if (change.was) element.setAttribute(DATA_WAS_SOURCE, change.was.source);\n const before = was && change.was ? findBlock(was, change.was) : null;\n if (change.words) markWords(element, change.words);\n if (before) {\n // As it was, the block as the old page rendered it.\n const copy = copyOf(before);\n copy.setAttribute(DATA_UI, \"\");\n copy.setAttribute(DATA_WAS_ONLY, \"\");\n element.after(copy);\n element.setAttribute(DATA_HAS_WAS, \"\");\n }\n }\n marks.push({ change, element });\n break;\n }\n case \"removed\": {\n const before = was && change.was ? findBlock(was, change.was) : null;\n const element = placer.place(change, (container) => {\n const holder = ui(doc, holderFor(container), CLASS_REMOVED);\n holder.setAttribute(DATA_CHANGE, \"removed\");\n if (change.was) holder.setAttribute(DATA_WAS_SOURCE, change.was.source);\n const label = ui(doc, \"span\", CLASS_LABEL, LABELS.removed);\n label.setAttribute(DATA_LABEL, \"removed\");\n const body = ui(doc, \"div\", CLASS_REMOVED_BODY);\n if (before) body.append(...contentOf(holder, before));\n else body.textContent = change.text ?? \"\";\n const toggle = ui(doc, \"button\", CLASS_TOGGLE, \"Show\");\n toggle.type = \"button\";\n toggle.setAttribute(\"aria-expanded\", \"false\");\n toggle.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n const open = holder.classList.toggle(CLASS_OPEN);\n toggle.textContent = open ? \"Collapse\" : \"Show\";\n toggle.setAttribute(\"aria-expanded\", String(open));\n });\n holder.append(label, body, toggle);\n return holder;\n });\n marks.push({ change, element });\n break;\n }\n case \"moved\": {\n const element = change.now ? findBlock(root, change.now) : null;\n if (!element || element.hasAttribute(DATA_CHANGE)) break;\n const id = `ascribe-move-${++moveCount}`;\n const before = was && change.was ? findBlock(was, change.was) : null;\n const stub = placer.place(change, (container) => {\n const holder = ui(doc, holderFor(container), CLASS_MOVED_FROM);\n holder.id = `${id}-from`;\n holder.setAttribute(DATA_CHANGE, \"moved-from\");\n if (change.was) holder.setAttribute(DATA_WAS_SOURCE, change.was.source);\n const note = ui(doc, \"span\", CLASS_MOVE_NOTE);\n note.append(doc.createTextNode(`A ${blockWord(element)} moved from here `));\n const link = ui(doc, \"a\", CLASS_MOVE_LINK);\n link.href = `#${id}`;\n note.append(link);\n holder.append(note);\n // As it was, the block itself.\n const copy = ui(doc, \"div\", CLASS_WAS_COPY);\n copy.setAttribute(DATA_WAS_ONLY, \"\");\n if (before) copy.append(...contentOf(holder, before));\n else copy.textContent = change.text ?? ownText(element);\n holder.append(copy);\n return holder;\n });\n element.setAttribute(DATA_CHANGE, \"moved\");\n element.setAttribute(DATA_MOVE, id);\n if (!element.id) element.id = id;\n addLabel(element, \"moved\");\n const back = ui(doc, \"a\", CLASS_MOVE_LINK);\n back.href = `#${stub.id}`;\n back.textContent = `from “${headingBefore(root, stub) ?? \"the top of the page\"}” ↑`;\n const forward = stub.querySelector<HTMLAnchorElement>(`.${CLASS_MOVE_LINK}`);\n if (forward) {\n forward.href = `#${element.id}`;\n forward.textContent = `to “${headingBefore(root, element) ?? \"the top of the page\"}” ↓`;\n }\n if (LABEL_INSIDE.has(element.localName)) {\n const note = ui(doc, \"span\", CLASS_MOVE_NOTE);\n note.append(\" \", back);\n element.append(note);\n } else {\n const holder = ui(doc, \"div\", `${CLASS_MOVE_NOTE} ${CLASS_MOVE_AFTER}`);\n holder.append(back);\n element.after(holder);\n }\n for (const link of [back, forward]) {\n link?.addEventListener(\"click\", (event) => {\n const target = doc.getElementById(link.hash.slice(1));\n if (!target || !root.contains(target)) return;\n event.preventDefault();\n goTo(target);\n });\n }\n marks.push({ change, element });\n break;\n }\n }\n }\n marks.sort((a, b) =>\n a.element === b.element\n ? 0\n : a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING\n ? -1\n : 1,\n );\n hintHidden(root, marks);\n return marks;\n}\n\n/**\n * Says on each tab's label, and on each `<details>`' summary, what's changed\n * in what they can hide: \"new\" for a tab that's added, else how many\n * changes. A tab that isn't selected, or a closed `<details>`, would\n * otherwise hide its changes until stepped to.\n */\nfunction hintHidden(root: HTMLElement, marks: readonly Mark[]): void {\n const tabs = new Map<HTMLElement, { added: boolean; count: number }>();\n const summaries = new Map<HTMLElement, number>();\n for (const { change, element } of marks) {\n for (let el: HTMLElement | null = element; el && el !== root; el = el.parentElement) {\n if (el.localName === ELEMENT_TAB) {\n const tab = tabs.get(el) ?? { added: false, count: 0 };\n if (el === element && change.kind === \"added\") tab.added = true;\n else tab.count++;\n tabs.set(el, tab);\n }\n const summary = el !== element ? summaryOf(el) : null;\n if (summary && !summary.contains(element)) {\n summaries.set(summary, (summaries.get(summary) ?? 0) + 1);\n }\n }\n }\n const doc = root.ownerDocument;\n const hint = (kind: \"added\" | \"changed\", text: string): HTMLElement => {\n // A space before it, not only a margin, so the label reads \"Linux 1\n // change\" to a screen reader, not \"Linux1 change\".\n const el = ui(doc, \"span\", CLASS_HINT, ` ${text}`);\n el.setAttribute(DATA_HINT, kind);\n return el;\n };\n const watching: MutationObserver[] = [];\n for (const [tab, { added, count }] of tabs) {\n const el = added ? hint(\"added\", \"new\") : hint(\"changed\", plural(count, \"change\"));\n const place = (): void => {\n const button = tabButton(tab);\n if (button && !button.contains(el)) button.append(el);\n };\n place();\n // `@ascribed/elements` makes the tab list once the page has loaded, and\n // again when the tabs are put back in the page.\n const group = tab.parentElement;\n const Observer = doc.defaultView?.MutationObserver;\n if (group && Observer) {\n const observer = new Observer(place);\n observer.observe(group, { childList: true });\n watching.push(observer);\n }\n }\n if (watching.length > 0) tabWatchers.set(root, watching);\n for (const [summary, count] of summaries)\n summary.append(hint(\"changed\", plural(count, \"change\")));\n}\n\n/** What waits for each marked page's tab lists, to stop when it's cleared. */\nconst tabWatchers = new WeakMap<HTMLElement, MutationObserver[]>();\n\nfunction plural(count: number, word: string): string {\n return `${count} ${word}${count === 1 ? \"\" : \"s\"}`;\n}\n\n/** A `<details>`' own `<summary>`, or null when `element` isn't one. */\nfunction summaryOf(element: Element): HTMLElement | null {\n if (element.localName !== \"details\") return null;\n return element.querySelector<HTMLElement>(\":scope > summary\");\n}\n\n/**\n * The button that selects an `<ascribe-tab>`, in its group's tab list, or\n * null before `@ascribed/elements` has made the list.\n */\nexport function tabButton(tab: Element): HTMLButtonElement | null {\n const group = tab.parentElement;\n if (tab.localName !== ELEMENT_TAB || !group) return null;\n const tabs = Array.from(group.children).filter((c) => c.localName === ELEMENT_TAB);\n const buttons = group.querySelectorAll<HTMLButtonElement>(\n ':scope > [role=\"tablist\"] > [role=\"tab\"]',\n );\n return buttons[tabs.indexOf(tab)] ?? null;\n}\n\n/** \"paragraph\", \"heading\", \"list\", or \"block\". */\nfunction blockWord(element: Element): string {\n const name = element.localName;\n if (name === \"p\") return \"paragraph\";\n if (/^h[1-6]$/.test(name)) return \"heading\";\n if (name === \"ul\" || name === \"ol\") return \"list\";\n if (name === \"li\") return \"list item\";\n if (name === \"pre\") return \"code block\";\n if (name === \"table\") return \"table\";\n return \"block\";\n}\n\n/** Removes every mark from the page in `root`. */\nexport function clearMarks(root: HTMLElement): void {\n for (const observer of tabWatchers.get(root) ?? []) observer.disconnect();\n tabWatchers.delete(root);\n for (const el of Array.from(root.querySelectorAll(`[${DATA_UI}]`))) {\n if (el.localName === \"ins\") el.replaceWith(...Array.from(el.childNodes));\n else el.remove();\n }\n for (const el of Array.from(root.querySelectorAll(`[${DATA_CHANGE}]`))) {\n el.removeAttribute(DATA_CHANGE);\n el.removeAttribute(DATA_HAS_WAS);\n el.removeAttribute(DATA_WAS_SOURCE);\n if (el.hasAttribute(DATA_MOVE)) {\n if (el.id === el.getAttribute(DATA_MOVE)) el.removeAttribute(\"id\");\n el.removeAttribute(DATA_MOVE);\n }\n }\n root.normalize();\n}\n\n/** Shows the changes, the page as it will be, or the page as it was. */\nexport function setShow(root: HTMLElement, show: Show): void {\n root.setAttribute(DATA_SHOW, show);\n}\n\n/**\n * Makes `element` visible: opens the `<details>` and selects the tabs it's\n * in.\n */\nexport function reveal(element: HTMLElement): void {\n for (let el: HTMLElement | null = element; el; el = el.parentElement) {\n if (el instanceof HTMLDetailsElement && !el.open) el.open = true;\n if (el.localName === ELEMENT_TAB && el.hidden) tabButton(el)?.click();\n }\n}\n\n/** Reveals `element`, scrolls to it, and flashes it. */\nexport function goTo(element: HTMLElement): void {\n reveal(element);\n // Not every DOM implements scrolling (jsdom doesn't).\n if (typeof element.scrollIntoView === \"function\") {\n element.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n }\n element.classList.remove(CLASS_FLASH);\n // Restart the animation.\n void element.offsetWidth;\n element.classList.add(CLASS_FLASH);\n if (!element.hasAttribute(\"tabindex\")) element.setAttribute(\"tabindex\", \"-1\");\n element.focus({ preventScroll: true });\n}\n\n/**\n * Shows each block's source on hover and focus: `guides/install.md:12`,\n * from its anchor. Returns a function that stops.\n */\nexport function showSources(root: HTMLElement): () => void {\n const doc = root.ownerDocument;\n const tip = ui(doc, \"span\", CLASS_WHERE);\n tip.setAttribute(\"role\", \"status\");\n let current: Element | null = null;\n const show = (target: EventTarget | null): void => {\n const el =\n target instanceof Element ? target.closest(`[${DATA_SOURCE}], [${DATA_WAS_SOURCE}]`) : null;\n if (el === current) return;\n current = el;\n if (!el || !root.contains(el)) {\n tip.remove();\n current = null;\n return;\n }\n const source = el.getAttribute(DATA_SOURCE);\n tip.textContent = source\n ? describeSource(source, el.getAttribute(DATA_VIA))\n : `was ${describeSource(el.getAttribute(DATA_WAS_SOURCE) ?? \"\")}`;\n const box = el.getBoundingClientRect();\n const host = root.getBoundingClientRect();\n tip.style.top = `${box.top - host.top}px`;\n root.append(tip);\n };\n const over = (event: Event): void => show(event.target);\n const out = (event: Event): void => {\n const to = (event as MouseEvent).relatedTarget;\n if (!(to instanceof Node) || !root.contains(to)) show(null);\n };\n root.addEventListener(\"mouseover\", over);\n root.addEventListener(\"focusin\", over);\n root.addEventListener(\"mouseout\", out);\n return () => {\n root.removeEventListener(\"mouseover\", over);\n root.removeEventListener(\"focusin\", over);\n root.removeEventListener(\"mouseout\", out);\n tip.remove();\n };\n}\n\n/**\n * Takes out of a page's HTML what could run script or take the reader\n * elsewhere: scripts, `<meta>` and `<base>`, event handler attributes, and\n * `javascript:` URLs. A page under review comes from the change being\n * reviewed, so a host disarms it before showing it, whatever its content\n * security policy also blocks.\n */\nexport function disarm(fragment: DocumentFragment): void {\n for (const el of Array.from(fragment.querySelectorAll(\"script, meta, base\"))) el.remove();\n for (const el of Array.from(fragment.querySelectorAll(\"*\"))) {\n for (const attr of Array.from(el.attributes)) {\n if (/^on/i.test(attr.name) || runsScript(attr.value)) el.removeAttribute(attr.name);\n }\n }\n}\n\n/** Whether a URL runs script: `javascript:`, however it's spaced or cased. */\nfunction runsScript(value: string): boolean {\n // URL parsing drops ASCII whitespace and control characters first.\n const kept = Array.from(value)\n .filter((ch) => ch.charCodeAt(0) > 0x20)\n .join(\"\");\n return /^javascript:/i.test(kept);\n}\n"]}
package/dist/names.d.ts CHANGED
@@ -6,6 +6,11 @@ export declare const ELEMENT_STEPS = "ascribe-steps";
6
6
  export declare const ELEMENT_TABS = "ascribe-tabs";
7
7
  /** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */
8
8
  export declare const ELEMENT_TAB = "ascribe-tab";
9
+ /**
10
+ * On the paragraph that starts an `<ascribe-tab>` and holds its label as
11
+ * text, for a reader of the HTML with no script (packages/elements/CONTRACT.md §3).
12
+ */
13
+ export declare const CLASS_TAB_LABEL = "ascribe-tab-label";
9
14
  /** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */
10
15
  export declare const ELEMENT_AVAILABILITY = "ascribe-availability";
11
16
  /**
@@ -24,6 +29,22 @@ export declare const CLASS_AVAILABILITY_LEAD_IN = "ascribe-availability-lead-in"
24
29
  * (packages/elements/CONTRACT.md §9).
25
30
  */
26
31
  export declare const CLASS_CODE_TESTED = "ascribe-code-tested";
32
+ /**
33
+ * On the button the element library's script adds after a code block's
34
+ * `<pre>`, which copies its code; its words are the stylesheet's
35
+ * (packages/elements/CONTRACT.md §12).
36
+ */
37
+ export declare const CLASS_COPY = "ascribe-copy";
38
+ /**
39
+ * On a copy button for a moment after a click: `copied`, or `failed`
40
+ * when the clipboard refused (packages/elements/CONTRACT.md §12).
41
+ */
42
+ export declare const DATA_COPY = "data-ascribe-copy";
43
+ /**
44
+ * The visually hidden live region that says a copy button copied
45
+ * (packages/elements/CONTRACT.md §12).
46
+ */
47
+ export declare const CLASS_COPY_STATUS = "ascribe-copy-status";
27
48
  /**
28
49
  * `<ascribe-operation>`: an operation of a declared API, from `@operation`
29
50
  * (packages/elements/CONTRACT.md §11).
package/dist/names.js CHANGED
@@ -9,6 +9,11 @@ export const ELEMENT_STEPS = "ascribe-steps";
9
9
  export const ELEMENT_TABS = "ascribe-tabs";
10
10
  /** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */
11
11
  export const ELEMENT_TAB = "ascribe-tab";
12
+ /**
13
+ * On the paragraph that starts an `<ascribe-tab>` and holds its label as
14
+ * text, for a reader of the HTML with no script (packages/elements/CONTRACT.md §3).
15
+ */
16
+ export const CLASS_TAB_LABEL = "ascribe-tab-label";
12
17
  /** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */
13
18
  export const ELEMENT_AVAILABILITY = "ascribe-availability";
14
19
  /**
@@ -27,6 +32,22 @@ export const CLASS_AVAILABILITY_LEAD_IN = "ascribe-availability-lead-in";
27
32
  * (packages/elements/CONTRACT.md §9).
28
33
  */
29
34
  export const CLASS_CODE_TESTED = "ascribe-code-tested";
35
+ /**
36
+ * On the button the element library's script adds after a code block's
37
+ * `<pre>`, which copies its code; its words are the stylesheet's
38
+ * (packages/elements/CONTRACT.md §12).
39
+ */
40
+ export const CLASS_COPY = "ascribe-copy";
41
+ /**
42
+ * On a copy button for a moment after a click: `copied`, or `failed`
43
+ * when the clipboard refused (packages/elements/CONTRACT.md §12).
44
+ */
45
+ export const DATA_COPY = "data-ascribe-copy";
46
+ /**
47
+ * The visually hidden live region that says a copy button copied
48
+ * (packages/elements/CONTRACT.md §12).
49
+ */
50
+ export const CLASS_COPY_STATUS = "ascribe-copy-status";
30
51
  /**
31
52
  * `<ascribe-operation>`: an operation of a declared API, from `@operation`
32
53
  * (packages/elements/CONTRACT.md §11).
package/dist/names.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"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","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/**\n * On the visually hidden `(Available: ` and `)` around a table row's\n * `<ascribe-availability>` targets (packages/elements/CONTRACT.md §4).\n */\nexport const CLASS_AVAILABILITY_LEAD_IN = \"ascribe-availability-lead-in\";\n\n/**\n * On the line of a code block's caption that says what a tested example\n * was tested with; its lead-in, \"Tested with\", is the stylesheet's\n * (packages/elements/CONTRACT.md §9).\n */\nexport const CLASS_CODE_TESTED = \"ascribe-code-tested\";\n\n/**\n * `<ascribe-operation>`: an operation of a declared API, from `@operation`\n * (packages/elements/CONTRACT.md §11).\n */\nexport const ELEMENT_OPERATION = \"ascribe-operation\";\n\n/**\n * On the `(deprecated)` after a deprecated operation's link in\n * `<ascribe-operation>` (packages/elements/CONTRACT.md §11).\n */\nexport const CLASS_OPERATION_DEPRECATED = \"ascribe-operation-deprecated\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/**\n * `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top\n * of a page, for agents (packages/elements/CONTRACT.md §8).\n */\nexport const ELEMENT_FOR_AGENTS = \"ascribe-for-agents\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The line a link out of a line leads to, on its link (packages/elements/CONTRACT.md §10). */\nexport const DATA_RELEASE_LINE = \"data-ascribe-release-line\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/astro/reference.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,qDAAqD;AACrD,4EAA4E;AAE5E,mEAAmE;AACnE,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,yEAAyE;AACzE,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,sFAAsF;AACtF,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,6BAA6B,CAAC;AAEzE;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAEzE;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAEzE,sFAAsF;AACtF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,gGAAgG;AAChG,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AAE3C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,+FAA+F;AAC/F,MAAM,CAAC,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AAE7D,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAE1C,wEAAwE;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAEzC,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAE/C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,gEAAgE;AAChE,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAErD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,yBAAyB,CAAC;AAEzD,sDAAsD;AACtD,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,sDAAsD;AACtD,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,wBAAwB;AACxB,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,qBAAqB;AACrB,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;AAEvC,oBAAoB;AACpB,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;AAEvC,uBAAuB;AACvB,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE/C,iCAAiC;AACjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC,2CAA2C;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAErD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,kDAAkD;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAErD,uDAAuD;AACvD,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,oDAAoD;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEjD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC,yCAAyC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/**\n * On the paragraph that starts an `<ascribe-tab>` and holds its label as\n * text, for a reader of the HTML with no script (packages/elements/CONTRACT.md §3).\n */\nexport const CLASS_TAB_LABEL = \"ascribe-tab-label\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/**\n * On the visually hidden `(Available: ` and `)` around a table row's\n * `<ascribe-availability>` targets (packages/elements/CONTRACT.md §4).\n */\nexport const CLASS_AVAILABILITY_LEAD_IN = \"ascribe-availability-lead-in\";\n\n/**\n * On the line of a code block's caption that says what a tested example\n * was tested with; its lead-in, \"Tested with\", is the stylesheet's\n * (packages/elements/CONTRACT.md §9).\n */\nexport const CLASS_CODE_TESTED = \"ascribe-code-tested\";\n\n/**\n * On the button the element library's script adds after a code block's\n * `<pre>`, which copies its code; its words are the stylesheet's\n * (packages/elements/CONTRACT.md §12).\n */\nexport const CLASS_COPY = \"ascribe-copy\";\n\n/**\n * On a copy button for a moment after a click: `copied`, or `failed`\n * when the clipboard refused (packages/elements/CONTRACT.md §12).\n */\nexport const DATA_COPY = \"data-ascribe-copy\";\n\n/**\n * The visually hidden live region that says a copy button copied\n * (packages/elements/CONTRACT.md §12).\n */\nexport const CLASS_COPY_STATUS = \"ascribe-copy-status\";\n\n/**\n * `<ascribe-operation>`: an operation of a declared API, from `@operation`\n * (packages/elements/CONTRACT.md §11).\n */\nexport const ELEMENT_OPERATION = \"ascribe-operation\";\n\n/**\n * On the `(deprecated)` after a deprecated operation's link in\n * `<ascribe-operation>` (packages/elements/CONTRACT.md §11).\n */\nexport const CLASS_OPERATION_DEPRECATED = \"ascribe-operation-deprecated\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/**\n * `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top\n * of a page, for agents (packages/elements/CONTRACT.md §8).\n */\nexport const ELEMENT_FOR_AGENTS = \"ascribe-for-agents\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The line a link out of a line leads to, on its link (packages/elements/CONTRACT.md §10). */\nexport const DATA_RELEASE_LINE = \"data-ascribe-release-line\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/astro/reference.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
@@ -585,6 +585,31 @@ class ReviewOverlay {
585
585
  host.remove();
586
586
  this.markers = [];
587
587
  }
588
+ /**
589
+ * The text a thread was on, quoted, or in words when it's empty or can't
590
+ * be read: an empty quote reads as a mistake.
591
+ */
592
+ originalText(thread) {
593
+ const orig = this.el("div", "orig");
594
+ const quote = thread.quote?.trim() ? thread.quote : undefined;
595
+ if (thread.detached !== undefined) {
596
+ if (quote !== undefined) {
597
+ orig.append(this.el("span", "", "The comment was on this text, which is no longer on the page: "), this.el("q", "", quote));
598
+ }
599
+ else {
600
+ orig.append(onRemovedText(thread)
601
+ ? "The comment was on a line that's since been removed."
602
+ : "The comment was on text that's no longer on the page.");
603
+ }
604
+ }
605
+ else if (quote !== undefined) {
606
+ orig.append(this.el("span", "", "The text when the comment was made: "), this.el("q", "", quote));
607
+ }
608
+ else {
609
+ orig.append("The text when the comment was made can't be shown.");
610
+ }
611
+ return orig;
612
+ }
588
613
  drawDetached() {
589
614
  const detached = this.data?.threads.detached ?? [];
590
615
  if (detached.length === 0)
@@ -679,15 +704,17 @@ class ReviewOverlay {
679
704
  if (!(view === "panel" && entry && !entry.removed && where === sourceLabel(entry.anchor))) {
680
705
  head.append(this.el("span", "", where));
681
706
  }
707
+ // One label for where the thread stands against the page, the most
708
+ // specific: on removed text says why a thread is detached, and a
709
+ // detached thread is past being outdated.
682
710
  if (onRemovedText(thread))
683
711
  head.append(this.badge("removed", "On removed text"));
684
- if (thread.resolved)
685
- head.append(this.badge("resolved", "Resolved"));
686
- if (thread.detached !== undefined)
712
+ else if (thread.detached !== undefined)
687
713
  head.append(this.badge("detached", "Detached"));
688
- if (thread.outdated && thread.detached === undefined) {
714
+ else if (thread.outdated)
689
715
  head.append(this.badge("outdated", "Outdated"));
690
- }
716
+ if (thread.resolved)
717
+ head.append(this.badge("resolved", "Resolved"));
691
718
  if (thread.kind === "conversation")
692
719
  head.append(this.badge("summary", "In the review summary"));
693
720
  if (hasUnsent(thread))
@@ -757,14 +784,8 @@ class ReviewOverlay {
757
784
  }
758
785
  if (collapsed)
759
786
  return card;
760
- if (thread.quote !== undefined &&
761
- thread.quote.trim() !== "" &&
762
- (thread.detached !== undefined || this.original.has(thread.id))) {
763
- const orig = this.el("div", "orig");
764
- orig.append(this.el("span", "", thread.detached !== undefined
765
- ? "The comment was on this text, which is no longer on the page: "
766
- : "The text when the comment was made: "), this.el("q", "", thread.quote));
767
- card.append(orig);
787
+ if (thread.detached !== undefined || this.original.has(thread.id)) {
788
+ card.append(this.originalText(thread));
768
789
  }
769
790
  const now = Date.now();
770
791
  for (const comment of thread.comments) {