@ascribed/astro 0.2.0 → 0.2.1-next.11

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.
@@ -15,6 +15,7 @@ import { APP_ID, CHANGED_EVENT, REQUEST_EVENT, RESULT_EVENT, } from "../review/p
15
15
  import { anchorOf, anchoredBlocks, anchorsArrived, contentRoot, pageFile, pageScheme, sourceLocation, } from "./page.js";
16
16
  import { PANEL_CSS } from "./style.js";
17
17
  import { againstText, buttonLabel, countsText, errorsNotice, nextChangedPage, nextPageText, pageDetail, position, THREAD_HASH, threadLocation, threadsNotice, unsentText, } from "./text.js";
18
+ import { CLASS_LABEL, CLASS_LABEL_BEFORE, CLASS_MARKS, DATA_REVIEW, DATA_SCHEME, DATA_SHOW, DATA_SOURCE, DATA_VIA, } from "../names.js";
18
19
  /** The width of the page's container from which threads show in a column beside it. */
19
20
  const COLUMN_AT = 720;
20
21
  /** The room between the panel and the window's edges, or the column of threads. */
@@ -122,7 +123,7 @@ class ReviewApp {
122
123
  this.live.setAttribute("role", "status");
123
124
  this.live.setAttribute("aria-live", "polite");
124
125
  canvas.append(style, this.panel, this.live);
125
- this.siteScheme = doc.documentElement.getAttribute("data-ascribe-scheme");
126
+ this.siteScheme = doc.documentElement.getAttribute(DATA_SCHEME);
126
127
  const win = doc.defaultView;
127
128
  win
128
129
  ?.matchMedia?.("(prefers-color-scheme: dark)")
@@ -136,7 +137,7 @@ class ReviewApp {
136
137
  this.restyleTimer = setTimeout(() => this.applyScheme(), 400);
137
138
  };
138
139
  const observer = new MutationObserver((records) => {
139
- if (records.some((r) => r.attributeName !== "data-ascribe-scheme"))
140
+ if (records.some((r) => r.attributeName !== DATA_SCHEME))
140
141
  restyle();
141
142
  });
142
143
  for (const target of [doc.documentElement, doc.body]) {
@@ -340,11 +341,11 @@ class ReviewApp {
340
341
  /** Each mark's label opens its block's source. */
341
342
  linkLabels() {
342
343
  for (const mark of this.marks) {
343
- const source = mark.element.getAttribute("data-ascribe-source");
344
+ const source = mark.element.getAttribute(DATA_SOURCE);
344
345
  const label = labelOf(mark.element);
345
346
  if (source === null || !label)
346
347
  continue;
347
- label.title = `Open ${describeSource(source, mark.element.getAttribute("data-ascribe-via"))}`;
348
+ label.title = `Open ${describeSource(source, mark.element.getAttribute(DATA_VIA))}`;
348
349
  label.tabIndex = 0;
349
350
  label.setAttribute("role", "link");
350
351
  const open = (event) => {
@@ -363,7 +364,7 @@ class ReviewApp {
363
364
  if (this.style?.isConnected)
364
365
  return;
365
366
  this.style = this.doc.createElement("style");
366
- this.style.setAttribute("data-ascribe-review", "");
367
+ this.style.setAttribute(DATA_REVIEW, "");
367
368
  this.style.textContent = marksCss;
368
369
  this.doc.head.append(this.style);
369
370
  }
@@ -373,8 +374,8 @@ class ReviewApp {
373
374
  this.stopSources = undefined;
374
375
  if (this.root) {
375
376
  clearMarks(this.root);
376
- this.root.classList.remove("ascribe-marks");
377
- this.root.removeAttribute("data-ascribe-show");
377
+ this.root.classList.remove(CLASS_MARKS);
378
+ this.root.removeAttribute(DATA_SHOW);
378
379
  }
379
380
  this.root = undefined;
380
381
  this.marked = undefined;
@@ -545,9 +546,9 @@ class ReviewApp {
545
546
  return;
546
547
  const html = this.doc.documentElement;
547
548
  if (!this.root)
548
- html.removeAttribute("data-ascribe-scheme");
549
- else if (html.getAttribute("data-ascribe-scheme") !== scheme)
550
- html.setAttribute("data-ascribe-scheme", scheme);
549
+ html.removeAttribute(DATA_SCHEME);
550
+ else if (html.getAttribute(DATA_SCHEME) !== scheme)
551
+ html.setAttribute(DATA_SCHEME, scheme);
551
552
  }
552
553
  /** Keeps the panel clear of the column of threads, over the page beside it. */
553
554
  placePanel() {
@@ -748,7 +749,7 @@ class ReviewApp {
748
749
  .join(" and ");
749
750
  body.append(this.el("b", "", anchoredBlocks(this.doc).length === 0
750
751
  ? `This page has ${what}, but its blocks carry no source anchors.`
751
- : `This page has ${what}, but most of its changed blocks carry no source anchors.`), this.el("span", "", "A layout or component is probably dropping the data-ascribe-source attributes, so nothing can be placed on the page. Everything is listed here instead."));
752
+ : `This page has ${what}, but most of its changed blocks carry no source anchors.`), this.el("span", "", `A layout or component is probably dropping the ${DATA_SOURCE} attributes, so nothing can be placed on the page. Everything is listed here instead.`));
752
753
  if (changes.length > 0) {
753
754
  body.append(this.el("span", "hint", "Changes"));
754
755
  const list = this.el("ul", "");
@@ -882,11 +883,11 @@ class ReviewApp {
882
883
  }
883
884
  /** The label the marks put on a block: inside it at its start, or just before it. */
884
885
  function labelOf(element) {
885
- const inside = element.querySelector(":scope > .ascribe-label");
886
+ const inside = element.querySelector(`:scope > .${CLASS_LABEL}`);
886
887
  if (inside)
887
888
  return inside;
888
889
  const before = element.previousElementSibling;
889
- return before instanceof HTMLElement && before.classList.contains("ascribe-label-before")
890
+ return before instanceof HTMLElement && before.classList.contains(CLASS_LABEL_BEFORE)
890
891
  ? before
891
892
  : undefined;
892
893
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/toolbar/app.ts"],"names":[],"mappings":"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","sourcesContent":["// The Ascribe review app in Astro's dev toolbar: the site preview's review.\n// It marks the page's changes with @ascribed/review's marks, hosts the\n// overlay for the pull request's threads, and holds the review controls in a\n// panel that opens from its toolbar button. Every request goes to the dev\n// server over the toolbar's channel; the page never sees a token and makes\n// no request to GitHub.\n//\n// Review stays on across pages and reloads (the dev server holds it), and\n// the panel stays as the reviewer left it in this tab.\nimport {\n clearMarks,\n describeSource,\n goTo,\n markChanges,\n setShow,\n showSources,\n type Mark,\n type Show,\n} from \"@ascribed/review/marks\";\nimport marksCss from \"@ascribed/review/marks.css?inline\";\nimport {\n createOverlay,\n renderMarkdown,\n type HostError,\n type LocatedThread,\n type Overlay,\n type OverlayData,\n type OverlayHost,\n} from \"@ascribed/review/overlay\";\nimport { defineToolbarApp } from \"astro/toolbar\";\nimport {\n APP_ID,\n CHANGED_EVENT,\n REQUEST_EVENT,\n RESULT_EVENT,\n type Change,\n type PageView,\n type Result,\n type Status,\n} from \"../review/protocol.js\";\nimport {\n anchorOf,\n anchoredBlocks,\n anchorsArrived,\n contentRoot,\n pageFile,\n pageScheme,\n sourceLocation,\n} from \"./page.js\";\nimport { PANEL_CSS } from \"./style.js\";\nimport {\n againstText,\n buttonLabel,\n countsText,\n errorsNotice,\n nextChangedPage,\n nextPageText,\n pageDetail,\n position,\n THREAD_HASH,\n threadLocation,\n threadsNotice,\n unsentText,\n} from \"./text.js\";\n\ntype ServerHelpers = Parameters<NonNullable<Parameters<typeof defineToolbarApp>[0][\"init\"]>>[2];\ntype AppEvents = Parameters<NonNullable<Parameters<typeof defineToolbarApp>[0][\"init\"]>>[1];\n\n/** The width of the page's container from which threads show in a column beside it. */\nconst COLUMN_AT = 720;\n/** The room between the panel and the window's edges, or the column of threads. */\nconst PANEL_MARGIN = 10;\nconst PANEL_WIDTH = 960;\n/** How long a request may take before the app gives up on the dev server. */\nconst TIMEOUT_MS = 120_000;\n/** This tab's memory: whether the panel is open, and a page to step into. */\nconst OPEN_KEY = \"ascribe-review-open\";\nconst FIRST_KEY = \"ascribe-review-first\";\n\nconst SHOWS: [Show, string][] = [\n [\"changes\", \"Changes\"],\n [\"will\", \"As it will be\"],\n [\"was\", \"As it was\"],\n];\n\nexport default defineToolbarApp({\n init(canvas, app, server) {\n void new ReviewApp(canvas, app, server, document).init();\n },\n});\n\n/** Requests to the dev server, each answered by its `id`. */\nclass Channel {\n private seq = 0;\n private readonly waiting = new Map<\n number,\n { resolve: (value: unknown) => void; reject: (error: HostError) => void }\n >();\n readonly tab = Math.random().toString(36).slice(2);\n\n constructor(private readonly server: ServerHelpers) {\n server.on<Result>(RESULT_EVENT, (result) => {\n if (result.tab !== this.tab) return;\n const waiter = this.waiting.get(result.id);\n if (!waiter) return;\n this.waiting.delete(result.id);\n if (result.error) waiter.reject(result.error);\n else waiter.resolve(result.result);\n });\n }\n\n request<T>(method: string, params: Record<string, unknown> = {}): Promise<T> {\n const id = ++this.seq;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.waiting.delete(id);\n reject({ message: \"The dev server didn't answer. Is `astro dev` still running?\" });\n }, TIMEOUT_MS);\n this.waiting.set(id, {\n resolve: (value) => {\n clearTimeout(timer);\n resolve(value as T);\n },\n reject: (error) => {\n clearTimeout(timer);\n reject(error);\n },\n });\n this.server.send(REQUEST_EVENT, { tab: this.tab, id, method, params });\n });\n }\n}\n\ntype Stage =\n | { kind: \"off\" }\n | { kind: \"starting\" }\n | { kind: \"failed\"; message: string }\n | { kind: \"on\"; view: PageView };\n\nclass ReviewApp {\n private readonly channel: Channel;\n private readonly panel: HTMLElement;\n private readonly live: HTMLElement;\n private stage: Stage = { kind: \"off\" };\n private open = false;\n private root: HTMLElement | undefined;\n /** Whether the page's anchors arrived: else everything is listed in the panel. */\n private arrived = true;\n private marked: string | undefined;\n private marks: Mark[] = [];\n private show: Show = \"changes\";\n private at = -1;\n private atEnd = false;\n private breakdown = false;\n private overlay: Overlay | undefined;\n private overlayFor: number | undefined;\n private listeners: (() => void)[] = [];\n /** The threads, read for a page whose anchors didn't arrive. */\n private listed: OverlayData | undefined;\n private stopSources: (() => void) | undefined;\n private style: HTMLStyleElement | undefined;\n private padding: { scroll: string; body: string } | undefined;\n private message: string | undefined;\n private messageTimer: ReturnType<typeof setTimeout> | undefined;\n /** The scheme the site set for review's colors itself, if it did. */\n private readonly siteScheme: string | null;\n private restyleTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(\n canvas: ShadowRoot,\n private readonly app: AppEvents,\n server: ServerHelpers,\n private readonly doc: Document,\n ) {\n this.channel = new Channel(server);\n const style = doc.createElement(\"style\");\n style.textContent = PANEL_CSS;\n this.panel = doc.createElement(\"div\");\n this.panel.className = \"panel\";\n this.panel.setAttribute(\"role\", \"region\");\n this.panel.setAttribute(\"aria-label\", \"Ascribe review\");\n this.live = doc.createElement(\"div\");\n this.live.className = \"sr-only\";\n this.live.setAttribute(\"role\", \"status\");\n this.live.setAttribute(\"aria-live\", \"polite\");\n canvas.append(style, this.panel, this.live);\n this.siteScheme = doc.documentElement.getAttribute(\"data-ascribe-scheme\");\n const win = doc.defaultView;\n win\n ?.matchMedia?.(\"(prefers-color-scheme: dark)\")\n .addEventListener(\"change\", () => this.render());\n win?.addEventListener(\"resize\", () => this.placePanel());\n // A theme switch on the page (a class or `data-theme` on the root, say) changes its colors.\n const restyle = () => {\n this.applyScheme();\n // Again once a transition between the themes is over.\n clearTimeout(this.restyleTimer);\n this.restyleTimer = setTimeout(() => this.applyScheme(), 400);\n };\n const observer = new MutationObserver((records) => {\n if (records.some((r) => r.attributeName !== \"data-ascribe-scheme\")) restyle();\n });\n for (const target of [doc.documentElement, doc.body]) {\n observer.observe(target, { attributes: true });\n }\n this.panel.addEventListener(\"keydown\", (event) => event.stopPropagation());\n server.on<{ from: string | null }>(CHANGED_EVENT, (event) => {\n if (event.from !== this.channel.tab) void this.changedElsewhere();\n });\n app.onToggled(({ state }) => {\n this.open = state;\n remember(OPEN_KEY, state ? \"1\" : \"0\");\n if (state && this.stage.kind === \"off\") void this.start();\n this.render();\n });\n }\n\n async init(): Promise<void> {\n let status: Status;\n try {\n status = await this.channel.request<Status>(\"status\");\n } catch {\n return;\n }\n if (!status.on) return;\n await this.load();\n if (recall(OPEN_KEY) === \"1\") this.app.toggleState({ state: true });\n }\n\n // --- Review on and off ---\n\n private async start(): Promise<void> {\n this.stage = { kind: \"starting\" };\n this.render();\n try {\n await this.channel.request<Status>(\"start\", {});\n } catch (error) {\n this.stage = { kind: \"failed\", message: messageOf(error) };\n this.render();\n return;\n }\n await this.load();\n }\n\n private async stop(): Promise<void> {\n try {\n await this.channel.request(\"stop\");\n } catch (error) {\n this.notify(messageOf(error));\n return;\n }\n this.clearPage();\n this.stage = { kind: \"off\" };\n this.render();\n this.announce(\"Review stopped.\");\n }\n\n /** Another page changed the threads, or stopped review. */\n private async changedElsewhere(): Promise<void> {\n let status: Status;\n try {\n status = await this.channel.request<Status>(\"status\");\n } catch {\n return;\n }\n if (!status.on) {\n this.clearPage();\n this.stage = { kind: \"off\" };\n this.render();\n } else if (this.stage.kind === \"on\") {\n this.didChange();\n }\n }\n\n /** Reads the page's changes and threads from the dev server, and draws them. */\n private async load(): Promise<void> {\n const blocks = anchoredBlocks(this.doc);\n let view: PageView;\n try {\n view = await this.channel.request<PageView>(\"page\", {\n route: this.doc.location.pathname,\n path: pageFile(blocks),\n });\n } catch (error) {\n this.stage = { kind: \"failed\", message: messageOf(error) };\n this.render();\n return;\n }\n this.stage = { kind: \"on\", view };\n this.draw(view, blocks);\n }\n\n private async refresh(): Promise<void> {\n this.notify(\"Refreshing…\");\n try {\n await this.channel.request(\"refresh\");\n } catch (error) {\n this.notify(messageOf(error));\n return;\n }\n await this.load();\n this.didChange();\n this.notify(\"Refreshed.\");\n }\n\n // --- The page ---\n\n private draw(view: PageView, blocks: HTMLElement[]): void {\n if (view.kind === \"not-page\") {\n this.clearPage();\n this.render();\n return;\n }\n const root = contentRoot(blocks);\n const changes = view.page?.changes ?? [];\n this.arrived = root !== undefined && anchorsArrived(root, blocks.length, changes);\n if (!root || !this.arrived) {\n this.clearPage();\n this.render();\n if (view.threads.state === \"on\") void this.listThreads(view);\n return;\n }\n this.listed = undefined;\n if (root !== this.root) this.clearPage();\n this.root = root;\n this.ensureStyle();\n const key = JSON.stringify(changes);\n if (key !== this.marked) {\n this.marked = key;\n this.at = -1;\n this.atEnd = false;\n this.marks = markChanges(root, changes);\n setShow(root, this.show);\n this.linkLabels();\n }\n this.stopSources ??= showSources(root);\n this.drawOverlay(view, root);\n this.render();\n this.goToAsked();\n }\n\n private drawOverlay(view: PageView, root: HTMLElement): void {\n const threads = view.threads;\n if (threads.state !== \"on\") {\n this.disposeOverlay();\n return;\n }\n if (this.overlay && this.overlayFor === threads.pullRequest.number) {\n this.didChange();\n return;\n }\n this.disposeOverlay();\n this.overlayFor = threads.pullRequest.number;\n this.overlay = createOverlay({\n root,\n host: this.host(),\n columnAt: COLUMN_AT,\n unsentBar: false,\n onUpdate: () => this.updated(),\n });\n }\n\n /**\n * The threads of a page whose anchors didn't arrive. The changes' anchors\n * stand in for the page's, so threads on the files it includes are read too.\n */\n private async listThreads(view: PageView): Promise<void> {\n const anchors = (view.page?.changes ?? []).flatMap((change) =>\n change.now\n ? [change.now, ...change.now.via.map((at) => ({ source: lineSource(at), via: [] }))]\n : [],\n );\n try {\n this.listed = await this.channel.request<OverlayData>(\"load\", {\n path: view.path,\n anchors,\n removed: this.removed(),\n });\n } catch (error) {\n this.notify(messageOf(error));\n return;\n }\n this.updated();\n }\n\n /** Goes where the page was opened for: a thread, or its first change. */\n private goToAsked(): void {\n const hash = this.doc.location.hash;\n if (hash.startsWith(THREAD_HASH) && this.overlay) {\n const id = decodeURIComponent(hash.slice(THREAD_HASH.length));\n const { pathname, search } = this.doc.location;\n this.doc.defaultView?.history.replaceState(null, \"\", `${pathname}${search}`);\n this.overlay.goToThread(id);\n } else if (recall(FIRST_KEY) === \"1\") {\n remember(FIRST_KEY, \"0\");\n if (this.marks.length > 0) this.step(1);\n }\n }\n\n /** Each mark's label opens its block's source. */\n private linkLabels(): void {\n for (const mark of this.marks) {\n const source = mark.element.getAttribute(\"data-ascribe-source\");\n const label = labelOf(mark.element);\n if (source === null || !label) continue;\n label.title = `Open ${describeSource(source, mark.element.getAttribute(\"data-ascribe-via\"))}`;\n label.tabIndex = 0;\n label.setAttribute(\"role\", \"link\");\n const open = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n this.openSource(source);\n };\n label.addEventListener(\"click\", open);\n label.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") open(event);\n });\n }\n }\n\n private ensureStyle(): void {\n if (this.style?.isConnected) return;\n this.style = this.doc.createElement(\"style\");\n this.style.setAttribute(\"data-ascribe-review\", \"\");\n this.style.textContent = marksCss;\n this.doc.head.append(this.style);\n }\n\n private clearPage(): void {\n this.disposeOverlay();\n this.stopSources?.();\n this.stopSources = undefined;\n if (this.root) {\n clearMarks(this.root);\n this.root.classList.remove(\"ascribe-marks\");\n this.root.removeAttribute(\"data-ascribe-show\");\n }\n this.root = undefined;\n this.marked = undefined;\n this.marks = [];\n this.listed = undefined;\n this.at = -1;\n this.atEnd = false;\n this.style?.remove();\n this.style = undefined;\n this.updated();\n }\n\n private disposeOverlay(): void {\n this.overlay?.dispose();\n this.overlay = undefined;\n this.overlayFor = undefined;\n this.listeners = [];\n }\n\n private didChange(): void {\n for (const listener of this.listeners) listener();\n }\n\n /** The overlay redrew, or the threads were read: the counts may have changed. */\n private updated(): void {\n const unsent = this.unsent();\n this.app.toggleNotification(unsent > 0 ? { state: true, level: \"info\" } : { state: false });\n labelButton(this.doc, buttonLabel(unsent));\n this.render();\n }\n\n private unsent(): number {\n return this.overlay?.unsentCount() ?? this.listed?.pending.count ?? 0;\n }\n\n // --- The overlay's host ---\n\n private host(): OverlayHost {\n const path = () => (this.stage.kind === \"on\" ? this.stage.view.path : null);\n const ask = <T>(method: string, params: Record<string, unknown> = {}) =>\n this.channel.request<T>(method, { ...params, path: path() });\n return {\n load: () => ask<OverlayData>(\"load\", { anchors: this.anchors(), removed: this.removed() }),\n commentTarget: (anchor) => ask(\"commentTarget\", { anchor }),\n comment: (anchor, body, quote) => ask(\"comment\", { anchor, body, quote }),\n reply: (threadId, body, when) => ask(\"reply\", { threadId, body, when }),\n allThreads: () => ask(\"allThreads\"),\n resolve: (threadId, resolved) => ask(\"resolve\", { threadId, resolved }),\n submit: (event, body) => ask(\"submit\", body === undefined ? { event } : { event, body }),\n discard: () => ask(\"discard\"),\n openSource: (anchor) => this.openSource(anchor.source),\n openThread: (threadId, pagePath) => this.openThread(threadId, pagePath),\n notify: (message) => this.notify(message),\n onDidChange: (listener) => {\n this.listeners.push(listener);\n },\n };\n }\n\n /** Every anchored block on the page, in its order. */\n private anchors(): { source: string; via: string[] }[] {\n return anchoredBlocks(this.doc)\n .filter((element) => this.root?.contains(element))\n .map(anchorOf);\n }\n\n /** Where the page's removed, moved, and changed blocks were, for threads on their old text. */\n private removed(): { source: string; via: string[] }[] {\n if (this.stage.kind !== \"on\") return [];\n return (this.stage.view.page?.changes ?? [])\n .filter((c: Change) => c.kind !== \"added\" && c.was)\n .map((c) => ({ source: c.was?.source ?? \"\", via: c.was?.via ?? [] }));\n }\n\n // --- Going places ---\n\n /** Opens a block's source file at its first line, in the editor Astro opens files in. */\n private openSource(source: string): void {\n if (this.stage.kind !== \"on\") return;\n const where = sourceLocation(source);\n if (!where) return;\n const { contentRoot: root, separator } = this.stage.view;\n const file = [root, ...where.path.split(\"/\")].join(separator);\n void fetch(`/__open-in-editor?file=${encodeURIComponent(`${file}:${where.line}`)}`).catch(() =>\n this.notify(\"Couldn't open the editor.\"),\n );\n }\n\n private openThread(threadId: string, pagePath: string): void {\n const page = this.routeOf(pagePath);\n if (page === undefined) {\n this.notify(\"That page isn't one this site shows.\");\n return;\n }\n this.doc.location.assign(`${page}${THREAD_HASH}${encodeURIComponent(threadId)}`);\n }\n\n private routeOf(pagePath: string): string | undefined {\n if (this.stage.kind !== \"on\") return undefined;\n return this.stage.view.changedPages.find((p) => p.path === pagePath && p.status !== \"removed\")\n ?.route;\n }\n\n private step(by: 1 | -1): void {\n const total = this.marks.length;\n if (by === 1 && this.at + 1 >= total) {\n this.at = total;\n this.atEnd = true;\n this.render();\n return;\n }\n this.atEnd = false;\n this.at = Math.max(0, Math.min(total - 1, this.at + by));\n if (this.show !== \"changes\") this.setShow(\"changes\");\n const mark = this.marks[this.at];\n if (mark) goTo(mark.element);\n this.render();\n }\n\n private setShow(show: Show): void {\n this.show = show;\n if (this.root) setShow(this.root, show);\n this.overlay?.layout();\n }\n\n // --- Telling the reviewer ---\n\n private notify(message: string): void {\n this.message = message;\n if (this.messageTimer) clearTimeout(this.messageTimer);\n this.messageTimer = setTimeout(() => {\n this.message = undefined;\n this.render();\n }, 6000);\n this.announce(message);\n this.render();\n }\n\n private announce(message: string): void {\n this.live.textContent = \"\";\n this.live.textContent = message;\n }\n\n // --- The panel ---\n\n private render(): void {\n this.applyScheme();\n this.panel.hidden = !this.open;\n this.pad();\n if (!this.open) return;\n const focus = this.focused();\n const title = this.el(\"div\", \"ttl\");\n title.append(this.el(\"span\", \"grow\", \"Ascribe review\"));\n if (this.stage.kind === \"on\") {\n title.append(this.button(\"Stop Review\", \"\", () => void this.stop()));\n }\n title.append(this.button(\"Close\", \"\", () => this.app.toggleState({ state: false })));\n const parts: HTMLElement[] = [title, ...this.content()];\n if (this.message !== undefined) parts.push(this.notice(this.message));\n this.panel.replaceChildren(...parts);\n this.refocus(focus);\n this.placePanel();\n this.pad();\n }\n\n /**\n * Review's colors follow the page's, not the reader's system: a light-only\n * site stays light. The marks and the overlay read `data-ascribe-scheme`\n * on the page's root; a site that sets it itself keeps its own.\n */\n private applyScheme(): void {\n const site = this.siteScheme;\n const prefersDark =\n this.doc.defaultView?.matchMedia?.(\"(prefers-color-scheme: dark)\").matches ?? false;\n const scheme =\n site === \"light\" || site === \"dark\"\n ? site\n : pageScheme(this.root ?? this.doc.body, prefersDark);\n if (this.panel.dataset[\"scheme\"] !== scheme) this.panel.dataset[\"scheme\"] = scheme;\n if (site !== null) return;\n const html = this.doc.documentElement;\n if (!this.root) html.removeAttribute(\"data-ascribe-scheme\");\n else if (html.getAttribute(\"data-ascribe-scheme\") !== scheme)\n html.setAttribute(\"data-ascribe-scheme\", scheme);\n }\n\n /** Keeps the panel clear of the column of threads, over the page beside it. */\n private placePanel(): void {\n const style = this.panel.style;\n const start = this.overlay?.columnStart();\n const viewport = this.doc.documentElement.clientWidth;\n const width = Math.min(PANEL_WIDTH, viewport - 2 * PANEL_MARGIN);\n if (start === undefined || (viewport + width) / 2 <= start - PANEL_MARGIN) {\n style.removeProperty(\"left\");\n style.removeProperty(\"width\");\n style.removeProperty(\"transform\");\n return;\n }\n const room = Math.max(0, start - 2 * PANEL_MARGIN);\n const fits = Math.min(PANEL_WIDTH, room);\n style.left = `${PANEL_MARGIN + (room - fits) / 2}px`;\n style.width = `${fits}px`;\n style.transform = \"none\";\n }\n\n private content(): HTMLElement[] {\n const stage = this.stage;\n switch (stage.kind) {\n case \"off\": {\n const row = this.el(\"div\", \"row\");\n row.append(\n this.el(\"span\", \"grow\", \"Review is off for this project.\"),\n this.button(\"Start Review\", \"primary\", () => void this.start()),\n );\n return [row];\n }\n case \"starting\":\n return [\n this.row(\n \"Starting review: comparing the pages with their base and looking for the pull request…\",\n ),\n ];\n case \"failed\": {\n const notice = this.notice(stage.message);\n notice.append(this.button(\"Try again\", \"primary\", () => void this.start()));\n return [notice];\n }\n case \"on\":\n return stage.view.kind === \"not-page\" ? this.notPage(stage.view) : this.onPage(stage.view);\n }\n }\n\n /** The site's own route: nothing to review, and the pages that changed. */\n private notPage(view: PageView): HTMLElement[] {\n const body = this.el(\"div\", \"body\");\n const { pullRequest } = againstText(view);\n const pages = view.changedPages.filter((p) => p.status !== \"removed\");\n body.append(\n this.el(\n \"span\",\n \"\",\n pages.length === 0\n ? \"Nothing to review here: this page doesn't come from the Ascribe project, and no page changed.\"\n : `Nothing to review here: this page doesn't come from the Ascribe project. Pages ${pullRequest ?? \"this branch\"} changes:`,\n ),\n );\n if (pages.length > 0) {\n const list = this.el(\"ul\", \"\");\n for (const page of pages) {\n const item = this.el(\"li\", \"\");\n const link = this.el(\"a\", \"\", page.route) as HTMLAnchorElement;\n link.href = page.route;\n item.append(link, ` ${pageDetail(page)}`);\n list.append(item);\n }\n body.append(list);\n }\n const parts = [body];\n if (view.problem !== null)\n parts.push(this.notice(`Couldn't compare the pages: ${view.problem}`));\n const errors = errorsNotice(view.errors);\n if (errors !== undefined) parts.push(this.notice(errors));\n return parts;\n }\n\n private onPage(view: PageView): HTMLElement[] {\n const parts: HTMLElement[] = [this.controls(view)];\n if (this.breakdown && view.page) {\n parts.push(this.el(\"div\", \"legend\", countsText(view.page.counts) || \"No changes\"));\n }\n if (view.problem !== null)\n parts.push(this.notice(`Couldn't compare the pages: ${view.problem}`));\n const errors = errorsNotice(view.errors);\n if (errors !== undefined) parts.push(this.notice(errors));\n const threads = threadsNotice(view.threads);\n if (threads !== undefined) parts.push(this.notice(threads));\n if (this.atEnd) parts.push(this.endNotice(view));\n if (!this.arrived) parts.push(this.notArrived(view));\n const unsent = this.unsent();\n if (unsent > 0) {\n const bar = this.el(\"div\", \"unsent\");\n bar.append(\n this.el(\"b\", \"\", unsentText(unsent)),\n this.el(\n \"span\",\n \"hint\",\n `Only you can see ${unsent === 1 ? \"it\" : \"them\"} until you submit.`,\n ),\n this.el(\"span\", \"spacer\"),\n );\n if (this.overlay) {\n bar.append(this.button(\"Submit review…\", \"primary\", () => this.overlay?.submitReview()));\n }\n parts.push(bar);\n }\n return parts;\n }\n\n /** The review controls, in one row. */\n private controls(view: PageView): HTMLElement {\n const row = this.el(\"div\", \"row\");\n const info = this.el(\"span\", \"grow\");\n const { pullRequest, base } = againstText(view);\n if (pullRequest !== null && view.threads.state === \"on\") {\n const link = this.el(\"a\", \"\", pullRequest) as HTMLAnchorElement;\n link.href = view.threads.pullRequest.url;\n link.target = \"_blank\";\n link.rel = \"noopener noreferrer\";\n link.title = `Open pull request ${pullRequest} on GitHub`;\n info.append(link, \" against \");\n } else {\n info.append(\"Against \");\n }\n const baseName = this.el(\"b\", \"\", base ?? \"the base\");\n if (view.base) {\n baseName.title = `Compared with ${(view.base.merge_base ?? view.base.commit).slice(0, 7)}, where this branch left ${view.base.requested}`;\n }\n info.append(baseName);\n const page = view.page;\n if (page?.status === \"added\") info.append(\" · a new page\");\n if (page && !page.own_file_changed && page.status === \"changed\" && page.because.length > 0) {\n info.append(\" · changed only through \");\n page.because.forEach((cause, i) => {\n if (i > 0) info.append(\", \");\n info.append(this.el(\"code\", \"\", cause));\n });\n }\n row.append(info);\n if (this.arrived) {\n const total = this.marks.length;\n const stepping = this.at >= 0 && this.at < total && this.show === \"changes\";\n const count = this.button(position(total, stepping ? this.at : -1), \"link position\", () => {\n this.breakdown = !this.breakdown;\n this.render();\n });\n count.setAttribute(\"aria-expanded\", String(this.breakdown));\n if (page) count.title = countsText(page.counts);\n const shows = this.el(\"div\", \"segmented\");\n shows.setAttribute(\"role\", \"group\");\n shows.setAttribute(\"aria-label\", \"Show\");\n for (const [show, label] of SHOWS) {\n const choice = this.button(label, \"\", () => {\n this.setShow(show);\n this.render();\n });\n choice.setAttribute(\"aria-pressed\", String(this.show === show));\n shows.append(choice);\n }\n const previous = this.button(\"↑\", \"ghost square\", () => this.step(-1));\n previous.setAttribute(\"aria-label\", \"Previous change\");\n previous.title = \"Previous change\";\n previous.disabled = total === 0;\n const next = this.button(\"↓\", \"ghost square\", () => this.step(1));\n next.setAttribute(\"aria-label\", \"Next change\");\n next.title = \"Next change\";\n row.append(count, shows, previous, next);\n }\n if (this.overlay) {\n const n = this.overlay.threadCount();\n const all = this.button(n === undefined ? \"Comments\" : `Comments (${n})`, \"ghost\", () =>\n this.overlay?.showAllComments(),\n );\n all.setAttribute(\"aria-label\", \"All comments on this pull request\");\n all.setAttribute(\"aria-haspopup\", \"dialog\");\n row.append(all);\n }\n const refresh = this.button(\"Refresh\", \"ghost\", () => void this.refresh());\n refresh.setAttribute(\"aria-label\", \"Refresh comments and changes\");\n row.append(refresh);\n return row;\n }\n\n /** Past the last change: the next changed page. */\n private endNotice(view: PageView): HTMLElement {\n const notice = this.notice(\n this.marks.length === 0\n ? \"This page has no changes.\"\n : \"That was the last change on this page.\",\n );\n const next = nextChangedPage(view.changedPages, view.path);\n if (next === null) notice.append(this.el(\"span\", \"\", \"No other page changed.\"));\n else {\n const target = next.page;\n notice.append(\n this.button(nextPageText(next), \"primary\", () => {\n remember(FIRST_KEY, \"1\");\n this.doc.location.assign(target.route);\n }),\n );\n }\n return notice;\n }\n\n /** The page's changes and threads, listed, since nothing could be placed on it. */\n private notArrived(view: PageView): HTMLElement {\n const body = this.el(\"div\", \"body\");\n const changes = view.page?.changes ?? [];\n const threads = listedThreads(this.listed);\n const what = [\n view.threads.state === \"on\" ? plural(threads.length, \"comment\") : undefined,\n plural(changes.length, \"change\"),\n ]\n .filter((x) => x !== undefined)\n .join(\" and \");\n body.append(\n this.el(\n \"b\",\n \"\",\n anchoredBlocks(this.doc).length === 0\n ? `This page has ${what}, but its blocks carry no source anchors.`\n : `This page has ${what}, but most of its changed blocks carry no source anchors.`,\n ),\n this.el(\n \"span\",\n \"\",\n \"A layout or component is probably dropping the data-ascribe-source attributes, so nothing can be placed on the page. Everything is listed here instead.\",\n ),\n );\n if (changes.length > 0) {\n body.append(this.el(\"span\", \"hint\", \"Changes\"));\n const list = this.el(\"ul\", \"\");\n for (const change of changes) {\n const item = this.el(\"li\", \"\", `${change.kind} `);\n const source = change.now?.source;\n if (source !== undefined) {\n item.append(this.button(describeSource(source), \"link\", () => this.openSource(source)));\n } else {\n item.append(this.el(\"span\", \"\", change.text ?? \"text\"));\n }\n list.append(item);\n }\n body.append(list);\n }\n if (threads.length > 0) {\n body.append(this.el(\"span\", \"hint\", \"Comments\"));\n for (const thread of threads) body.append(this.threadCard(thread));\n }\n return body;\n }\n\n /** A thread, read only: open it on GitHub to reply. */\n private threadCard(thread: LocatedThread): HTMLElement {\n const card = this.el(\"div\", \"thread\");\n const where = this.el(\"div\", \"where\");\n const lines = thread.lines;\n const { label, removed } = threadLocation(thread);\n // A thread on removed text is on the base's lines, which the working tree doesn't have.\n if (lines !== undefined && !removed) {\n const source = `${thread.path.split(\"/\").map(encodeURIComponent).join(\"/\")}:${lines.first}-${lines.last}`;\n const link = this.button(label, \"link\", () => this.openSource(source));\n link.title = `Open ${thread.path}, line ${lines.first}`;\n where.append(link);\n } else {\n const name = this.el(\"span\", \"\", label);\n name.title = thread.path;\n where.append(name);\n }\n if (removed) where.append(\" · On removed text\");\n if (thread.resolved) where.append(\" · Resolved\");\n if (thread.outdated) where.append(\" · Outdated\");\n card.append(where);\n for (const comment of thread.comments) {\n const body = this.el(\"div\", \"comment\");\n body.append(\n this.el(\"b\", \"\", comment.author?.login ?? \"ghost\"),\n renderMarkdown(this.doc, comment.body),\n );\n card.append(body);\n }\n const url = thread.comments[0]?.url;\n if (url !== undefined && url !== \"\") {\n const link = this.el(\"a\", \"\", \"Open on GitHub\") as HTMLAnchorElement;\n link.href = url;\n link.target = \"_blank\";\n link.rel = \"noopener noreferrer\";\n card.append(link);\n }\n return card;\n }\n\n /** Room below the page, so the panel never hides what's focused. */\n private pad(): void {\n const html = this.doc.documentElement;\n const body = this.doc.body;\n if (this.open && this.stage.kind === \"on\") {\n this.padding ??= { scroll: html.style.scrollPaddingBottom, body: body.style.paddingBottom };\n const room = `${this.panel.offsetHeight + 90}px`;\n html.style.scrollPaddingBottom = room;\n body.style.paddingBottom = room;\n } else if (this.padding) {\n html.style.scrollPaddingBottom = this.padding.scroll;\n body.style.paddingBottom = this.padding.body;\n this.padding = undefined;\n }\n }\n\n // --- DOM ---\n\n private row(text: string): HTMLElement {\n const row = this.el(\"div\", \"row\");\n row.append(this.el(\"span\", \"grow\", text));\n return row;\n }\n\n private notice(text: string): HTMLElement {\n const notice = this.el(\"div\", \"notice\");\n const words = this.el(\"span\", \"\");\n // A command or a setting is written in backticks: show it as code.\n text.split(\"`\").forEach((part, i) => {\n if (part !== \"\") words.append(i % 2 === 1 ? this.el(\"code\", \"\", part) : part);\n });\n notice.append(words, this.el(\"span\", \"spacer\"));\n return notice;\n }\n\n private el(tag: string, className: string, text?: string): HTMLElement {\n const el = this.doc.createElement(tag);\n if (className) el.className = className;\n if (text !== undefined) el.textContent = text;\n return el;\n }\n\n private button(text: string, className: string, onClick: () => void): HTMLButtonElement {\n const button = this.doc.createElement(\"button\");\n button.type = \"button\";\n if (className) button.className = className;\n button.textContent = text;\n button.addEventListener(\"click\", onClick);\n return button;\n }\n\n /** The focused control's label, to focus it again after a redraw. */\n private focused(): string | undefined {\n const active = (this.panel.getRootNode() as ShadowRoot).activeElement;\n return active instanceof HTMLElement && this.panel.contains(active)\n ? (active.getAttribute(\"aria-label\") ?? active.textContent ?? undefined)\n : undefined;\n }\n\n private refocus(label: string | undefined): void {\n if (label === undefined) return;\n for (const button of Array.from(this.panel.querySelectorAll<HTMLElement>(\"button, a\"))) {\n if ((button.getAttribute(\"aria-label\") ?? button.textContent) === label) {\n button.focus();\n return;\n }\n }\n }\n}\n\n/** The label the marks put on a block: inside it at its start, or just before it. */\nfunction labelOf(element: HTMLElement): HTMLElement | undefined {\n const inside = element.querySelector<HTMLElement>(\":scope > .ascribe-label\");\n if (inside) return inside;\n const before = element.previousElementSibling;\n return before instanceof HTMLElement && before.classList.contains(\"ascribe-label-before\")\n ? before\n : undefined;\n}\n\n/**\n * Puts the unsent count in the toolbar button's tooltip. The toolbar has no\n * API for a button's text, so this reads its markup and does nothing if\n * that changed.\n */\nfunction labelButton(doc: Document, text: string): void {\n const toolbar = doc.querySelector(\"astro-dev-toolbar\")?.shadowRoot;\n const button = toolbar?.querySelector(`button.item[data-app-id=\"${APP_ID}\"]`);\n const tip = button?.querySelector(\".item-tooltip\");\n if (tip) tip.textContent = text;\n button?.setAttribute(\"aria-label\", text);\n}\n\n/**\n * Every thread read for a page whose anchors didn't arrive, once each: on\n * the changes' blocks, on removed text, or on no block.\n */\nfunction listedThreads(data: OverlayData | undefined): LocatedThread[] {\n if (!data) return [];\n const { blocks, removed, detached } = data.threads;\n const seen = new Set<string>();\n return [...blocks, ...removed]\n .flatMap((entry) => entry.threads)\n .concat(detached)\n .filter((thread) => !seen.has(thread.id) && seen.add(thread.id));\n}\n\n/** An include's place (`<path>:<line>`) as a block's source (`<path>:<line>-<line>`). */\nfunction lineSource(at: string): string {\n const colon = at.lastIndexOf(\":\");\n const line = at.slice(colon + 1);\n return colon > 0 && /^\\d+$/.test(line) ? `${at}-${line}` : at;\n}\n\nfunction plural(count: number, noun: string): string {\n return count === 1 ? `1 ${noun}` : `${count} ${noun}s`;\n}\n\nfunction messageOf(error: unknown): string {\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\nfunction remember(key: string, value: string): void {\n try {\n sessionStorage.setItem(key, value);\n } catch {\n // Storage is off: the panel just starts closed on the next page.\n }\n}\n\nfunction recall(key: string): string | null {\n try {\n return sessionStorage.getItem(key);\n } catch {\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/toolbar/app.ts"],"names":[],"mappings":"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","sourcesContent":["// The Ascribe review app in Astro's dev toolbar: the site preview's review.\n// It marks the page's changes with @ascribed/review's marks, hosts the\n// overlay for the pull request's threads, and holds the review controls in a\n// panel that opens from its toolbar button. Every request goes to the dev\n// server over the toolbar's channel; the page never sees a token and makes\n// no request to GitHub.\n//\n// Review stays on across pages and reloads (the dev server holds it), and\n// the panel stays as the reviewer left it in this tab.\nimport {\n clearMarks,\n describeSource,\n goTo,\n markChanges,\n setShow,\n showSources,\n type Mark,\n type Show,\n} from \"@ascribed/review/marks\";\nimport marksCss from \"@ascribed/review/marks.css?inline\";\nimport {\n createOverlay,\n renderMarkdown,\n type HostError,\n type LocatedThread,\n type Overlay,\n type OverlayData,\n type OverlayHost,\n} from \"@ascribed/review/overlay\";\nimport { defineToolbarApp } from \"astro/toolbar\";\nimport {\n APP_ID,\n CHANGED_EVENT,\n REQUEST_EVENT,\n RESULT_EVENT,\n type Change,\n type PageView,\n type Result,\n type Status,\n} from \"../review/protocol.js\";\nimport {\n anchorOf,\n anchoredBlocks,\n anchorsArrived,\n contentRoot,\n pageFile,\n pageScheme,\n sourceLocation,\n} from \"./page.js\";\nimport { PANEL_CSS } from \"./style.js\";\nimport {\n againstText,\n buttonLabel,\n countsText,\n errorsNotice,\n nextChangedPage,\n nextPageText,\n pageDetail,\n position,\n THREAD_HASH,\n threadLocation,\n threadsNotice,\n unsentText,\n} from \"./text.js\";\nimport {\n CLASS_LABEL,\n CLASS_LABEL_BEFORE,\n CLASS_MARKS,\n DATA_REVIEW,\n DATA_SCHEME,\n DATA_SHOW,\n DATA_SOURCE,\n DATA_VIA,\n} from \"../names.js\";\n\ntype ServerHelpers = Parameters<NonNullable<Parameters<typeof defineToolbarApp>[0][\"init\"]>>[2];\ntype AppEvents = Parameters<NonNullable<Parameters<typeof defineToolbarApp>[0][\"init\"]>>[1];\n\n/** The width of the page's container from which threads show in a column beside it. */\nconst COLUMN_AT = 720;\n/** The room between the panel and the window's edges, or the column of threads. */\nconst PANEL_MARGIN = 10;\nconst PANEL_WIDTH = 960;\n/** How long a request may take before the app gives up on the dev server. */\nconst TIMEOUT_MS = 120_000;\n/** This tab's memory: whether the panel is open, and a page to step into. */\nconst OPEN_KEY = \"ascribe-review-open\";\nconst FIRST_KEY = \"ascribe-review-first\";\n\nconst SHOWS: [Show, string][] = [\n [\"changes\", \"Changes\"],\n [\"will\", \"As it will be\"],\n [\"was\", \"As it was\"],\n];\n\nexport default defineToolbarApp({\n init(canvas, app, server) {\n void new ReviewApp(canvas, app, server, document).init();\n },\n});\n\n/** Requests to the dev server, each answered by its `id`. */\nclass Channel {\n private seq = 0;\n private readonly waiting = new Map<\n number,\n { resolve: (value: unknown) => void; reject: (error: HostError) => void }\n >();\n readonly tab = Math.random().toString(36).slice(2);\n\n constructor(private readonly server: ServerHelpers) {\n server.on<Result>(RESULT_EVENT, (result) => {\n if (result.tab !== this.tab) return;\n const waiter = this.waiting.get(result.id);\n if (!waiter) return;\n this.waiting.delete(result.id);\n if (result.error) waiter.reject(result.error);\n else waiter.resolve(result.result);\n });\n }\n\n request<T>(method: string, params: Record<string, unknown> = {}): Promise<T> {\n const id = ++this.seq;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.waiting.delete(id);\n reject({ message: \"The dev server didn't answer. Is `astro dev` still running?\" });\n }, TIMEOUT_MS);\n this.waiting.set(id, {\n resolve: (value) => {\n clearTimeout(timer);\n resolve(value as T);\n },\n reject: (error) => {\n clearTimeout(timer);\n reject(error);\n },\n });\n this.server.send(REQUEST_EVENT, { tab: this.tab, id, method, params });\n });\n }\n}\n\ntype Stage =\n | { kind: \"off\" }\n | { kind: \"starting\" }\n | { kind: \"failed\"; message: string }\n | { kind: \"on\"; view: PageView };\n\nclass ReviewApp {\n private readonly channel: Channel;\n private readonly panel: HTMLElement;\n private readonly live: HTMLElement;\n private stage: Stage = { kind: \"off\" };\n private open = false;\n private root: HTMLElement | undefined;\n /** Whether the page's anchors arrived: else everything is listed in the panel. */\n private arrived = true;\n private marked: string | undefined;\n private marks: Mark[] = [];\n private show: Show = \"changes\";\n private at = -1;\n private atEnd = false;\n private breakdown = false;\n private overlay: Overlay | undefined;\n private overlayFor: number | undefined;\n private listeners: (() => void)[] = [];\n /** The threads, read for a page whose anchors didn't arrive. */\n private listed: OverlayData | undefined;\n private stopSources: (() => void) | undefined;\n private style: HTMLStyleElement | undefined;\n private padding: { scroll: string; body: string } | undefined;\n private message: string | undefined;\n private messageTimer: ReturnType<typeof setTimeout> | undefined;\n /** The scheme the site set for review's colors itself, if it did. */\n private readonly siteScheme: string | null;\n private restyleTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(\n canvas: ShadowRoot,\n private readonly app: AppEvents,\n server: ServerHelpers,\n private readonly doc: Document,\n ) {\n this.channel = new Channel(server);\n const style = doc.createElement(\"style\");\n style.textContent = PANEL_CSS;\n this.panel = doc.createElement(\"div\");\n this.panel.className = \"panel\";\n this.panel.setAttribute(\"role\", \"region\");\n this.panel.setAttribute(\"aria-label\", \"Ascribe review\");\n this.live = doc.createElement(\"div\");\n this.live.className = \"sr-only\";\n this.live.setAttribute(\"role\", \"status\");\n this.live.setAttribute(\"aria-live\", \"polite\");\n canvas.append(style, this.panel, this.live);\n this.siteScheme = doc.documentElement.getAttribute(DATA_SCHEME);\n const win = doc.defaultView;\n win\n ?.matchMedia?.(\"(prefers-color-scheme: dark)\")\n .addEventListener(\"change\", () => this.render());\n win?.addEventListener(\"resize\", () => this.placePanel());\n // A theme switch on the page (a class or `data-theme` on the root, say) changes its colors.\n const restyle = () => {\n this.applyScheme();\n // Again once a transition between the themes is over.\n clearTimeout(this.restyleTimer);\n this.restyleTimer = setTimeout(() => this.applyScheme(), 400);\n };\n const observer = new MutationObserver((records) => {\n if (records.some((r) => r.attributeName !== DATA_SCHEME)) restyle();\n });\n for (const target of [doc.documentElement, doc.body]) {\n observer.observe(target, { attributes: true });\n }\n this.panel.addEventListener(\"keydown\", (event) => event.stopPropagation());\n server.on<{ from: string | null }>(CHANGED_EVENT, (event) => {\n if (event.from !== this.channel.tab) void this.changedElsewhere();\n });\n app.onToggled(({ state }) => {\n this.open = state;\n remember(OPEN_KEY, state ? \"1\" : \"0\");\n if (state && this.stage.kind === \"off\") void this.start();\n this.render();\n });\n }\n\n async init(): Promise<void> {\n let status: Status;\n try {\n status = await this.channel.request<Status>(\"status\");\n } catch {\n return;\n }\n if (!status.on) return;\n await this.load();\n if (recall(OPEN_KEY) === \"1\") this.app.toggleState({ state: true });\n }\n\n // --- Review on and off ---\n\n private async start(): Promise<void> {\n this.stage = { kind: \"starting\" };\n this.render();\n try {\n await this.channel.request<Status>(\"start\", {});\n } catch (error) {\n this.stage = { kind: \"failed\", message: messageOf(error) };\n this.render();\n return;\n }\n await this.load();\n }\n\n private async stop(): Promise<void> {\n try {\n await this.channel.request(\"stop\");\n } catch (error) {\n this.notify(messageOf(error));\n return;\n }\n this.clearPage();\n this.stage = { kind: \"off\" };\n this.render();\n this.announce(\"Review stopped.\");\n }\n\n /** Another page changed the threads, or stopped review. */\n private async changedElsewhere(): Promise<void> {\n let status: Status;\n try {\n status = await this.channel.request<Status>(\"status\");\n } catch {\n return;\n }\n if (!status.on) {\n this.clearPage();\n this.stage = { kind: \"off\" };\n this.render();\n } else if (this.stage.kind === \"on\") {\n this.didChange();\n }\n }\n\n /** Reads the page's changes and threads from the dev server, and draws them. */\n private async load(): Promise<void> {\n const blocks = anchoredBlocks(this.doc);\n let view: PageView;\n try {\n view = await this.channel.request<PageView>(\"page\", {\n route: this.doc.location.pathname,\n path: pageFile(blocks),\n });\n } catch (error) {\n this.stage = { kind: \"failed\", message: messageOf(error) };\n this.render();\n return;\n }\n this.stage = { kind: \"on\", view };\n this.draw(view, blocks);\n }\n\n private async refresh(): Promise<void> {\n this.notify(\"Refreshing…\");\n try {\n await this.channel.request(\"refresh\");\n } catch (error) {\n this.notify(messageOf(error));\n return;\n }\n await this.load();\n this.didChange();\n this.notify(\"Refreshed.\");\n }\n\n // --- The page ---\n\n private draw(view: PageView, blocks: HTMLElement[]): void {\n if (view.kind === \"not-page\") {\n this.clearPage();\n this.render();\n return;\n }\n const root = contentRoot(blocks);\n const changes = view.page?.changes ?? [];\n this.arrived = root !== undefined && anchorsArrived(root, blocks.length, changes);\n if (!root || !this.arrived) {\n this.clearPage();\n this.render();\n if (view.threads.state === \"on\") void this.listThreads(view);\n return;\n }\n this.listed = undefined;\n if (root !== this.root) this.clearPage();\n this.root = root;\n this.ensureStyle();\n const key = JSON.stringify(changes);\n if (key !== this.marked) {\n this.marked = key;\n this.at = -1;\n this.atEnd = false;\n this.marks = markChanges(root, changes);\n setShow(root, this.show);\n this.linkLabels();\n }\n this.stopSources ??= showSources(root);\n this.drawOverlay(view, root);\n this.render();\n this.goToAsked();\n }\n\n private drawOverlay(view: PageView, root: HTMLElement): void {\n const threads = view.threads;\n if (threads.state !== \"on\") {\n this.disposeOverlay();\n return;\n }\n if (this.overlay && this.overlayFor === threads.pullRequest.number) {\n this.didChange();\n return;\n }\n this.disposeOverlay();\n this.overlayFor = threads.pullRequest.number;\n this.overlay = createOverlay({\n root,\n host: this.host(),\n columnAt: COLUMN_AT,\n unsentBar: false,\n onUpdate: () => this.updated(),\n });\n }\n\n /**\n * The threads of a page whose anchors didn't arrive. The changes' anchors\n * stand in for the page's, so threads on the files it includes are read too.\n */\n private async listThreads(view: PageView): Promise<void> {\n const anchors = (view.page?.changes ?? []).flatMap((change) =>\n change.now\n ? [change.now, ...change.now.via.map((at) => ({ source: lineSource(at), via: [] }))]\n : [],\n );\n try {\n this.listed = await this.channel.request<OverlayData>(\"load\", {\n path: view.path,\n anchors,\n removed: this.removed(),\n });\n } catch (error) {\n this.notify(messageOf(error));\n return;\n }\n this.updated();\n }\n\n /** Goes where the page was opened for: a thread, or its first change. */\n private goToAsked(): void {\n const hash = this.doc.location.hash;\n if (hash.startsWith(THREAD_HASH) && this.overlay) {\n const id = decodeURIComponent(hash.slice(THREAD_HASH.length));\n const { pathname, search } = this.doc.location;\n this.doc.defaultView?.history.replaceState(null, \"\", `${pathname}${search}`);\n this.overlay.goToThread(id);\n } else if (recall(FIRST_KEY) === \"1\") {\n remember(FIRST_KEY, \"0\");\n if (this.marks.length > 0) this.step(1);\n }\n }\n\n /** Each mark's label opens its block's source. */\n private linkLabels(): void {\n for (const mark of this.marks) {\n const source = mark.element.getAttribute(DATA_SOURCE);\n const label = labelOf(mark.element);\n if (source === null || !label) continue;\n label.title = `Open ${describeSource(source, mark.element.getAttribute(DATA_VIA))}`;\n label.tabIndex = 0;\n label.setAttribute(\"role\", \"link\");\n const open = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n this.openSource(source);\n };\n label.addEventListener(\"click\", open);\n label.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") open(event);\n });\n }\n }\n\n private ensureStyle(): void {\n if (this.style?.isConnected) return;\n this.style = this.doc.createElement(\"style\");\n this.style.setAttribute(DATA_REVIEW, \"\");\n this.style.textContent = marksCss;\n this.doc.head.append(this.style);\n }\n\n private clearPage(): void {\n this.disposeOverlay();\n this.stopSources?.();\n this.stopSources = undefined;\n if (this.root) {\n clearMarks(this.root);\n this.root.classList.remove(CLASS_MARKS);\n this.root.removeAttribute(DATA_SHOW);\n }\n this.root = undefined;\n this.marked = undefined;\n this.marks = [];\n this.listed = undefined;\n this.at = -1;\n this.atEnd = false;\n this.style?.remove();\n this.style = undefined;\n this.updated();\n }\n\n private disposeOverlay(): void {\n this.overlay?.dispose();\n this.overlay = undefined;\n this.overlayFor = undefined;\n this.listeners = [];\n }\n\n private didChange(): void {\n for (const listener of this.listeners) listener();\n }\n\n /** The overlay redrew, or the threads were read: the counts may have changed. */\n private updated(): void {\n const unsent = this.unsent();\n this.app.toggleNotification(unsent > 0 ? { state: true, level: \"info\" } : { state: false });\n labelButton(this.doc, buttonLabel(unsent));\n this.render();\n }\n\n private unsent(): number {\n return this.overlay?.unsentCount() ?? this.listed?.pending.count ?? 0;\n }\n\n // --- The overlay's host ---\n\n private host(): OverlayHost {\n const path = () => (this.stage.kind === \"on\" ? this.stage.view.path : null);\n const ask = <T>(method: string, params: Record<string, unknown> = {}) =>\n this.channel.request<T>(method, { ...params, path: path() });\n return {\n load: () => ask<OverlayData>(\"load\", { anchors: this.anchors(), removed: this.removed() }),\n commentTarget: (anchor) => ask(\"commentTarget\", { anchor }),\n comment: (anchor, body, quote) => ask(\"comment\", { anchor, body, quote }),\n reply: (threadId, body, when) => ask(\"reply\", { threadId, body, when }),\n allThreads: () => ask(\"allThreads\"),\n resolve: (threadId, resolved) => ask(\"resolve\", { threadId, resolved }),\n submit: (event, body) => ask(\"submit\", body === undefined ? { event } : { event, body }),\n discard: () => ask(\"discard\"),\n openSource: (anchor) => this.openSource(anchor.source),\n openThread: (threadId, pagePath) => this.openThread(threadId, pagePath),\n notify: (message) => this.notify(message),\n onDidChange: (listener) => {\n this.listeners.push(listener);\n },\n };\n }\n\n /** Every anchored block on the page, in its order. */\n private anchors(): { source: string; via: string[] }[] {\n return anchoredBlocks(this.doc)\n .filter((element) => this.root?.contains(element))\n .map(anchorOf);\n }\n\n /** Where the page's removed, moved, and changed blocks were, for threads on their old text. */\n private removed(): { source: string; via: string[] }[] {\n if (this.stage.kind !== \"on\") return [];\n return (this.stage.view.page?.changes ?? [])\n .filter((c: Change) => c.kind !== \"added\" && c.was)\n .map((c) => ({ source: c.was?.source ?? \"\", via: c.was?.via ?? [] }));\n }\n\n // --- Going places ---\n\n /** Opens a block's source file at its first line, in the editor Astro opens files in. */\n private openSource(source: string): void {\n if (this.stage.kind !== \"on\") return;\n const where = sourceLocation(source);\n if (!where) return;\n const { contentRoot: root, separator } = this.stage.view;\n const file = [root, ...where.path.split(\"/\")].join(separator);\n void fetch(`/__open-in-editor?file=${encodeURIComponent(`${file}:${where.line}`)}`).catch(() =>\n this.notify(\"Couldn't open the editor.\"),\n );\n }\n\n private openThread(threadId: string, pagePath: string): void {\n const page = this.routeOf(pagePath);\n if (page === undefined) {\n this.notify(\"That page isn't one this site shows.\");\n return;\n }\n this.doc.location.assign(`${page}${THREAD_HASH}${encodeURIComponent(threadId)}`);\n }\n\n private routeOf(pagePath: string): string | undefined {\n if (this.stage.kind !== \"on\") return undefined;\n return this.stage.view.changedPages.find((p) => p.path === pagePath && p.status !== \"removed\")\n ?.route;\n }\n\n private step(by: 1 | -1): void {\n const total = this.marks.length;\n if (by === 1 && this.at + 1 >= total) {\n this.at = total;\n this.atEnd = true;\n this.render();\n return;\n }\n this.atEnd = false;\n this.at = Math.max(0, Math.min(total - 1, this.at + by));\n if (this.show !== \"changes\") this.setShow(\"changes\");\n const mark = this.marks[this.at];\n if (mark) goTo(mark.element);\n this.render();\n }\n\n private setShow(show: Show): void {\n this.show = show;\n if (this.root) setShow(this.root, show);\n this.overlay?.layout();\n }\n\n // --- Telling the reviewer ---\n\n private notify(message: string): void {\n this.message = message;\n if (this.messageTimer) clearTimeout(this.messageTimer);\n this.messageTimer = setTimeout(() => {\n this.message = undefined;\n this.render();\n }, 6000);\n this.announce(message);\n this.render();\n }\n\n private announce(message: string): void {\n this.live.textContent = \"\";\n this.live.textContent = message;\n }\n\n // --- The panel ---\n\n private render(): void {\n this.applyScheme();\n this.panel.hidden = !this.open;\n this.pad();\n if (!this.open) return;\n const focus = this.focused();\n const title = this.el(\"div\", \"ttl\");\n title.append(this.el(\"span\", \"grow\", \"Ascribe review\"));\n if (this.stage.kind === \"on\") {\n title.append(this.button(\"Stop Review\", \"\", () => void this.stop()));\n }\n title.append(this.button(\"Close\", \"\", () => this.app.toggleState({ state: false })));\n const parts: HTMLElement[] = [title, ...this.content()];\n if (this.message !== undefined) parts.push(this.notice(this.message));\n this.panel.replaceChildren(...parts);\n this.refocus(focus);\n this.placePanel();\n this.pad();\n }\n\n /**\n * Review's colors follow the page's, not the reader's system: a light-only\n * site stays light. The marks and the overlay read `data-ascribe-scheme`\n * on the page's root; a site that sets it itself keeps its own.\n */\n private applyScheme(): void {\n const site = this.siteScheme;\n const prefersDark =\n this.doc.defaultView?.matchMedia?.(\"(prefers-color-scheme: dark)\").matches ?? false;\n const scheme =\n site === \"light\" || site === \"dark\"\n ? site\n : pageScheme(this.root ?? this.doc.body, prefersDark);\n if (this.panel.dataset[\"scheme\"] !== scheme) this.panel.dataset[\"scheme\"] = scheme;\n if (site !== null) return;\n const html = this.doc.documentElement;\n if (!this.root) html.removeAttribute(DATA_SCHEME);\n else if (html.getAttribute(DATA_SCHEME) !== scheme) html.setAttribute(DATA_SCHEME, scheme);\n }\n\n /** Keeps the panel clear of the column of threads, over the page beside it. */\n private placePanel(): void {\n const style = this.panel.style;\n const start = this.overlay?.columnStart();\n const viewport = this.doc.documentElement.clientWidth;\n const width = Math.min(PANEL_WIDTH, viewport - 2 * PANEL_MARGIN);\n if (start === undefined || (viewport + width) / 2 <= start - PANEL_MARGIN) {\n style.removeProperty(\"left\");\n style.removeProperty(\"width\");\n style.removeProperty(\"transform\");\n return;\n }\n const room = Math.max(0, start - 2 * PANEL_MARGIN);\n const fits = Math.min(PANEL_WIDTH, room);\n style.left = `${PANEL_MARGIN + (room - fits) / 2}px`;\n style.width = `${fits}px`;\n style.transform = \"none\";\n }\n\n private content(): HTMLElement[] {\n const stage = this.stage;\n switch (stage.kind) {\n case \"off\": {\n const row = this.el(\"div\", \"row\");\n row.append(\n this.el(\"span\", \"grow\", \"Review is off for this project.\"),\n this.button(\"Start Review\", \"primary\", () => void this.start()),\n );\n return [row];\n }\n case \"starting\":\n return [\n this.row(\n \"Starting review: comparing the pages with their base and looking for the pull request…\",\n ),\n ];\n case \"failed\": {\n const notice = this.notice(stage.message);\n notice.append(this.button(\"Try again\", \"primary\", () => void this.start()));\n return [notice];\n }\n case \"on\":\n return stage.view.kind === \"not-page\" ? this.notPage(stage.view) : this.onPage(stage.view);\n }\n }\n\n /** The site's own route: nothing to review, and the pages that changed. */\n private notPage(view: PageView): HTMLElement[] {\n const body = this.el(\"div\", \"body\");\n const { pullRequest } = againstText(view);\n const pages = view.changedPages.filter((p) => p.status !== \"removed\");\n body.append(\n this.el(\n \"span\",\n \"\",\n pages.length === 0\n ? \"Nothing to review here: this page doesn't come from the Ascribe project, and no page changed.\"\n : `Nothing to review here: this page doesn't come from the Ascribe project. Pages ${pullRequest ?? \"this branch\"} changes:`,\n ),\n );\n if (pages.length > 0) {\n const list = this.el(\"ul\", \"\");\n for (const page of pages) {\n const item = this.el(\"li\", \"\");\n const link = this.el(\"a\", \"\", page.route) as HTMLAnchorElement;\n link.href = page.route;\n item.append(link, ` ${pageDetail(page)}`);\n list.append(item);\n }\n body.append(list);\n }\n const parts = [body];\n if (view.problem !== null)\n parts.push(this.notice(`Couldn't compare the pages: ${view.problem}`));\n const errors = errorsNotice(view.errors);\n if (errors !== undefined) parts.push(this.notice(errors));\n return parts;\n }\n\n private onPage(view: PageView): HTMLElement[] {\n const parts: HTMLElement[] = [this.controls(view)];\n if (this.breakdown && view.page) {\n parts.push(this.el(\"div\", \"legend\", countsText(view.page.counts) || \"No changes\"));\n }\n if (view.problem !== null)\n parts.push(this.notice(`Couldn't compare the pages: ${view.problem}`));\n const errors = errorsNotice(view.errors);\n if (errors !== undefined) parts.push(this.notice(errors));\n const threads = threadsNotice(view.threads);\n if (threads !== undefined) parts.push(this.notice(threads));\n if (this.atEnd) parts.push(this.endNotice(view));\n if (!this.arrived) parts.push(this.notArrived(view));\n const unsent = this.unsent();\n if (unsent > 0) {\n const bar = this.el(\"div\", \"unsent\");\n bar.append(\n this.el(\"b\", \"\", unsentText(unsent)),\n this.el(\n \"span\",\n \"hint\",\n `Only you can see ${unsent === 1 ? \"it\" : \"them\"} until you submit.`,\n ),\n this.el(\"span\", \"spacer\"),\n );\n if (this.overlay) {\n bar.append(this.button(\"Submit review…\", \"primary\", () => this.overlay?.submitReview()));\n }\n parts.push(bar);\n }\n return parts;\n }\n\n /** The review controls, in one row. */\n private controls(view: PageView): HTMLElement {\n const row = this.el(\"div\", \"row\");\n const info = this.el(\"span\", \"grow\");\n const { pullRequest, base } = againstText(view);\n if (pullRequest !== null && view.threads.state === \"on\") {\n const link = this.el(\"a\", \"\", pullRequest) as HTMLAnchorElement;\n link.href = view.threads.pullRequest.url;\n link.target = \"_blank\";\n link.rel = \"noopener noreferrer\";\n link.title = `Open pull request ${pullRequest} on GitHub`;\n info.append(link, \" against \");\n } else {\n info.append(\"Against \");\n }\n const baseName = this.el(\"b\", \"\", base ?? \"the base\");\n if (view.base) {\n baseName.title = `Compared with ${(view.base.merge_base ?? view.base.commit).slice(0, 7)}, where this branch left ${view.base.requested}`;\n }\n info.append(baseName);\n const page = view.page;\n if (page?.status === \"added\") info.append(\" · a new page\");\n if (page && !page.own_file_changed && page.status === \"changed\" && page.because.length > 0) {\n info.append(\" · changed only through \");\n page.because.forEach((cause, i) => {\n if (i > 0) info.append(\", \");\n info.append(this.el(\"code\", \"\", cause));\n });\n }\n row.append(info);\n if (this.arrived) {\n const total = this.marks.length;\n const stepping = this.at >= 0 && this.at < total && this.show === \"changes\";\n const count = this.button(position(total, stepping ? this.at : -1), \"link position\", () => {\n this.breakdown = !this.breakdown;\n this.render();\n });\n count.setAttribute(\"aria-expanded\", String(this.breakdown));\n if (page) count.title = countsText(page.counts);\n const shows = this.el(\"div\", \"segmented\");\n shows.setAttribute(\"role\", \"group\");\n shows.setAttribute(\"aria-label\", \"Show\");\n for (const [show, label] of SHOWS) {\n const choice = this.button(label, \"\", () => {\n this.setShow(show);\n this.render();\n });\n choice.setAttribute(\"aria-pressed\", String(this.show === show));\n shows.append(choice);\n }\n const previous = this.button(\"↑\", \"ghost square\", () => this.step(-1));\n previous.setAttribute(\"aria-label\", \"Previous change\");\n previous.title = \"Previous change\";\n previous.disabled = total === 0;\n const next = this.button(\"↓\", \"ghost square\", () => this.step(1));\n next.setAttribute(\"aria-label\", \"Next change\");\n next.title = \"Next change\";\n row.append(count, shows, previous, next);\n }\n if (this.overlay) {\n const n = this.overlay.threadCount();\n const all = this.button(n === undefined ? \"Comments\" : `Comments (${n})`, \"ghost\", () =>\n this.overlay?.showAllComments(),\n );\n all.setAttribute(\"aria-label\", \"All comments on this pull request\");\n all.setAttribute(\"aria-haspopup\", \"dialog\");\n row.append(all);\n }\n const refresh = this.button(\"Refresh\", \"ghost\", () => void this.refresh());\n refresh.setAttribute(\"aria-label\", \"Refresh comments and changes\");\n row.append(refresh);\n return row;\n }\n\n /** Past the last change: the next changed page. */\n private endNotice(view: PageView): HTMLElement {\n const notice = this.notice(\n this.marks.length === 0\n ? \"This page has no changes.\"\n : \"That was the last change on this page.\",\n );\n const next = nextChangedPage(view.changedPages, view.path);\n if (next === null) notice.append(this.el(\"span\", \"\", \"No other page changed.\"));\n else {\n const target = next.page;\n notice.append(\n this.button(nextPageText(next), \"primary\", () => {\n remember(FIRST_KEY, \"1\");\n this.doc.location.assign(target.route);\n }),\n );\n }\n return notice;\n }\n\n /** The page's changes and threads, listed, since nothing could be placed on it. */\n private notArrived(view: PageView): HTMLElement {\n const body = this.el(\"div\", \"body\");\n const changes = view.page?.changes ?? [];\n const threads = listedThreads(this.listed);\n const what = [\n view.threads.state === \"on\" ? plural(threads.length, \"comment\") : undefined,\n plural(changes.length, \"change\"),\n ]\n .filter((x) => x !== undefined)\n .join(\" and \");\n body.append(\n this.el(\n \"b\",\n \"\",\n anchoredBlocks(this.doc).length === 0\n ? `This page has ${what}, but its blocks carry no source anchors.`\n : `This page has ${what}, but most of its changed blocks carry no source anchors.`,\n ),\n this.el(\n \"span\",\n \"\",\n `A layout or component is probably dropping the ${DATA_SOURCE} attributes, so nothing can be placed on the page. Everything is listed here instead.`,\n ),\n );\n if (changes.length > 0) {\n body.append(this.el(\"span\", \"hint\", \"Changes\"));\n const list = this.el(\"ul\", \"\");\n for (const change of changes) {\n const item = this.el(\"li\", \"\", `${change.kind} `);\n const source = change.now?.source;\n if (source !== undefined) {\n item.append(this.button(describeSource(source), \"link\", () => this.openSource(source)));\n } else {\n item.append(this.el(\"span\", \"\", change.text ?? \"text\"));\n }\n list.append(item);\n }\n body.append(list);\n }\n if (threads.length > 0) {\n body.append(this.el(\"span\", \"hint\", \"Comments\"));\n for (const thread of threads) body.append(this.threadCard(thread));\n }\n return body;\n }\n\n /** A thread, read only: open it on GitHub to reply. */\n private threadCard(thread: LocatedThread): HTMLElement {\n const card = this.el(\"div\", \"thread\");\n const where = this.el(\"div\", \"where\");\n const lines = thread.lines;\n const { label, removed } = threadLocation(thread);\n // A thread on removed text is on the base's lines, which the working tree doesn't have.\n if (lines !== undefined && !removed) {\n const source = `${thread.path.split(\"/\").map(encodeURIComponent).join(\"/\")}:${lines.first}-${lines.last}`;\n const link = this.button(label, \"link\", () => this.openSource(source));\n link.title = `Open ${thread.path}, line ${lines.first}`;\n where.append(link);\n } else {\n const name = this.el(\"span\", \"\", label);\n name.title = thread.path;\n where.append(name);\n }\n if (removed) where.append(\" · On removed text\");\n if (thread.resolved) where.append(\" · Resolved\");\n if (thread.outdated) where.append(\" · Outdated\");\n card.append(where);\n for (const comment of thread.comments) {\n const body = this.el(\"div\", \"comment\");\n body.append(\n this.el(\"b\", \"\", comment.author?.login ?? \"ghost\"),\n renderMarkdown(this.doc, comment.body),\n );\n card.append(body);\n }\n const url = thread.comments[0]?.url;\n if (url !== undefined && url !== \"\") {\n const link = this.el(\"a\", \"\", \"Open on GitHub\") as HTMLAnchorElement;\n link.href = url;\n link.target = \"_blank\";\n link.rel = \"noopener noreferrer\";\n card.append(link);\n }\n return card;\n }\n\n /** Room below the page, so the panel never hides what's focused. */\n private pad(): void {\n const html = this.doc.documentElement;\n const body = this.doc.body;\n if (this.open && this.stage.kind === \"on\") {\n this.padding ??= { scroll: html.style.scrollPaddingBottom, body: body.style.paddingBottom };\n const room = `${this.panel.offsetHeight + 90}px`;\n html.style.scrollPaddingBottom = room;\n body.style.paddingBottom = room;\n } else if (this.padding) {\n html.style.scrollPaddingBottom = this.padding.scroll;\n body.style.paddingBottom = this.padding.body;\n this.padding = undefined;\n }\n }\n\n // --- DOM ---\n\n private row(text: string): HTMLElement {\n const row = this.el(\"div\", \"row\");\n row.append(this.el(\"span\", \"grow\", text));\n return row;\n }\n\n private notice(text: string): HTMLElement {\n const notice = this.el(\"div\", \"notice\");\n const words = this.el(\"span\", \"\");\n // A command or a setting is written in backticks: show it as code.\n text.split(\"`\").forEach((part, i) => {\n if (part !== \"\") words.append(i % 2 === 1 ? this.el(\"code\", \"\", part) : part);\n });\n notice.append(words, this.el(\"span\", \"spacer\"));\n return notice;\n }\n\n private el(tag: string, className: string, text?: string): HTMLElement {\n const el = this.doc.createElement(tag);\n if (className) el.className = className;\n if (text !== undefined) el.textContent = text;\n return el;\n }\n\n private button(text: string, className: string, onClick: () => void): HTMLButtonElement {\n const button = this.doc.createElement(\"button\");\n button.type = \"button\";\n if (className) button.className = className;\n button.textContent = text;\n button.addEventListener(\"click\", onClick);\n return button;\n }\n\n /** The focused control's label, to focus it again after a redraw. */\n private focused(): string | undefined {\n const active = (this.panel.getRootNode() as ShadowRoot).activeElement;\n return active instanceof HTMLElement && this.panel.contains(active)\n ? (active.getAttribute(\"aria-label\") ?? active.textContent ?? undefined)\n : undefined;\n }\n\n private refocus(label: string | undefined): void {\n if (label === undefined) return;\n for (const button of Array.from(this.panel.querySelectorAll<HTMLElement>(\"button, a\"))) {\n if ((button.getAttribute(\"aria-label\") ?? button.textContent) === label) {\n button.focus();\n return;\n }\n }\n }\n}\n\n/** The label the marks put on a block: inside it at its start, or just before it. */\nfunction labelOf(element: HTMLElement): HTMLElement | undefined {\n const inside = element.querySelector<HTMLElement>(`:scope > .${CLASS_LABEL}`);\n if (inside) return inside;\n const before = element.previousElementSibling;\n return before instanceof HTMLElement && before.classList.contains(CLASS_LABEL_BEFORE)\n ? before\n : undefined;\n}\n\n/**\n * Puts the unsent count in the toolbar button's tooltip. The toolbar has no\n * API for a button's text, so this reads its markup and does nothing if\n * that changed.\n */\nfunction labelButton(doc: Document, text: string): void {\n const toolbar = doc.querySelector(\"astro-dev-toolbar\")?.shadowRoot;\n const button = toolbar?.querySelector(`button.item[data-app-id=\"${APP_ID}\"]`);\n const tip = button?.querySelector(\".item-tooltip\");\n if (tip) tip.textContent = text;\n button?.setAttribute(\"aria-label\", text);\n}\n\n/**\n * Every thread read for a page whose anchors didn't arrive, once each: on\n * the changes' blocks, on removed text, or on no block.\n */\nfunction listedThreads(data: OverlayData | undefined): LocatedThread[] {\n if (!data) return [];\n const { blocks, removed, detached } = data.threads;\n const seen = new Set<string>();\n return [...blocks, ...removed]\n .flatMap((entry) => entry.threads)\n .concat(detached)\n .filter((thread) => !seen.has(thread.id) && seen.add(thread.id));\n}\n\n/** An include's place (`<path>:<line>`) as a block's source (`<path>:<line>-<line>`). */\nfunction lineSource(at: string): string {\n const colon = at.lastIndexOf(\":\");\n const line = at.slice(colon + 1);\n return colon > 0 && /^\\d+$/.test(line) ? `${at}-${line}` : at;\n}\n\nfunction plural(count: number, noun: string): string {\n return count === 1 ? `1 ${noun}` : `${count} ${noun}s`;\n}\n\nfunction messageOf(error: unknown): string {\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return String(error);\n}\n\nfunction remember(key: string, value: string): void {\n try {\n sessionStorage.setItem(key, value);\n } catch {\n // Storage is off: the panel just starts closed on the next page.\n }\n}\n\nfunction recall(key: string): string | null {\n try {\n return sessionStorage.getItem(key);\n } catch {\n return null;\n }\n}\n"]}
@@ -1,9 +1,7 @@
1
1
  import type { Change } from "../review/protocol.js";
2
- /** An anchor, as the marks and the overlay take it. */
3
- export interface Anchor {
4
- source: string;
5
- via: string[];
6
- }
2
+ import type { Anchor } from "../shapes.js";
3
+ /** An anchor, as `ascribe diff` writes it and the marks and the overlay take it. */
4
+ export type { Anchor };
7
5
  /** The page's anchored blocks, in order, leaving out review's own elements. */
8
6
  export declare function anchoredBlocks(doc: Document): HTMLElement[];
9
7
  /**
@@ -3,9 +3,10 @@
3
3
  // whether the anchors arrived. Apart from the app so it can be tested in a
4
4
  // DOM by itself.
5
5
  import { findBlock, parseSource } from "@ascribed/review/marks";
6
+ import { DATA_SOURCE, DATA_UI, DATA_VIA } from "../names.js";
6
7
  /** The page's anchored blocks, in order, leaving out review's own elements. */
7
8
  export function anchoredBlocks(doc) {
8
- return Array.from(doc.querySelectorAll("[data-ascribe-source]")).filter((element) => element.closest("[data-ascribe-ui]") === null);
9
+ return Array.from(doc.querySelectorAll(`[${DATA_SOURCE}]`)).filter((element) => element.closest(`[${DATA_UI}]`) === null);
9
10
  }
10
11
  /**
11
12
  * The element holding the page's content: the innermost one holding every
@@ -18,7 +19,7 @@ export function contentRoot(blocks) {
18
19
  let root = first.parentElement;
19
20
  while (root && !blocks.every((block) => root?.contains(block)))
20
21
  root = root.parentElement;
21
- while (root?.hasAttribute("data-ascribe-source"))
22
+ while (root?.hasAttribute(DATA_SOURCE))
22
23
  root = root.parentElement;
23
24
  if (!root || root === first.ownerDocument.documentElement)
24
25
  return first.ownerDocument.body;
@@ -30,9 +31,9 @@ export function contentRoot(blocks) {
30
31
  */
31
32
  export function pageFile(blocks) {
32
33
  for (const block of blocks) {
33
- if ((block.getAttribute("data-ascribe-via") ?? "").trim() !== "")
34
+ if ((block.getAttribute(DATA_VIA) ?? "").trim() !== "")
34
35
  continue;
35
- const parsed = parseSource(block.getAttribute("data-ascribe-source") ?? "");
36
+ const parsed = parseSource(block.getAttribute(DATA_SOURCE) ?? "");
36
37
  if (parsed)
37
38
  return parsed.path;
38
39
  }
@@ -41,8 +42,8 @@ export function pageFile(blocks) {
41
42
  /** An element's anchor. */
42
43
  export function anchorOf(element) {
43
44
  return {
44
- source: element.getAttribute("data-ascribe-source") ?? "",
45
- via: (element.getAttribute("data-ascribe-via") ?? "").split(" ").filter(Boolean),
45
+ source: element.getAttribute(DATA_SOURCE) ?? "",
46
+ via: (element.getAttribute(DATA_VIA) ?? "").split(" ").filter(Boolean),
46
47
  };
47
48
  }
48
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/toolbar/page.ts"],"names":[],"mappings":"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","sourcesContent":["// What the toolbar app reads from the page the dev server rendered: its\n// anchored blocks, the element that holds them, the page's own file, and\n// whether the anchors arrived. Apart from the app so it can be tested in a\n// DOM by itself.\nimport { findBlock, parseSource } from \"@ascribed/review/marks\";\nimport type { Change } from \"../review/protocol.js\";\n\n/** An anchor, as the marks and the overlay take it. */\nexport interface Anchor {\n source: string;\n via: string[];\n}\n\n/** The page's anchored blocks, in order, leaving out review's own elements. */\nexport function anchoredBlocks(doc: Document): HTMLElement[] {\n return Array.from(doc.querySelectorAll<HTMLElement>(\"[data-ascribe-source]\")).filter(\n (element) => element.closest(\"[data-ascribe-ui]\") === null,\n );\n}\n\n/**\n * The element holding the page's content: the innermost one holding every\n * anchored block, and not a block itself. `undefined` with none.\n */\nexport function contentRoot(blocks: readonly HTMLElement[]): HTMLElement | undefined {\n const first = blocks[0];\n if (first === undefined) return undefined;\n let root: HTMLElement | null = first.parentElement;\n while (root && !blocks.every((block) => root?.contains(block))) root = root.parentElement;\n while (root?.hasAttribute(\"data-ascribe-source\")) root = root.parentElement;\n if (!root || root === first.ownerDocument.documentElement) return first.ownerDocument.body;\n return root;\n}\n\n/**\n * The page's own file, as a content path: the file of the first block\n * written in the page itself (with no includes). `null` when no block is.\n */\nexport function pageFile(blocks: readonly HTMLElement[]): string | null {\n for (const block of blocks) {\n if ((block.getAttribute(\"data-ascribe-via\") ?? \"\").trim() !== \"\") continue;\n const parsed = parseSource(block.getAttribute(\"data-ascribe-source\") ?? \"\");\n if (parsed) return parsed.path;\n }\n return null;\n}\n\n/** An element's anchor. */\nexport function anchorOf(element: Element): Anchor {\n return {\n source: element.getAttribute(\"data-ascribe-source\") ?? \"\",\n via: (element.getAttribute(\"data-ascribe-via\") ?? \"\").split(\" \").filter(Boolean),\n };\n}\n\n/**\n * Whether the page's anchors arrived: false when the page has changes but\n * no anchored blocks, or when fewer than half of its changed blocks can be\n * found. A layout or component that rebuilds the content's elements drops\n * their attributes, and then nothing can be placed.\n */\nexport function anchorsArrived(\n root: ParentNode,\n blocks: number,\n changes: readonly Change[],\n): boolean {\n // A removed block is found by the block it came after, or the one it was in.\n const anchors = changes\n .map((change) => change.now ?? change.after ?? change.parent)\n .filter((anchor) => anchor !== undefined);\n if (anchors.length === 0) return true;\n if (blocks === 0) return false;\n const found = anchors.filter((anchor) => findBlock(root, anchor) !== null).length;\n return found * 2 >= anchors.length;\n}\n\n/** Where a block's source is, for opening it: `guides/install.md`, line 12. */\nexport function sourceLocation(source: string): { path: string; line: number } | undefined {\n const parsed = parseSource(source);\n return parsed ? { path: parsed.path, line: parsed.first } : undefined;\n}\n\n/**\n * Whether the page looks light or dark, from its own colors: the first\n * background that isn't see-through, from `element` up, or else its text's\n * color, or else the canvas, which the root's `color-scheme` picks (`prefersDark` says which\n * one \"light dark\" picks). Review's colors follow it, not the reader's\n * system, since a site may be light only.\n */\nexport function pageScheme(element: Element, prefersDark: boolean): \"light\" | \"dark\" {\n const view = element.ownerDocument.defaultView;\n if (!view) return prefersDark ? \"dark\" : \"light\";\n for (let at: Element | null = element; at; at = at.parentElement) {\n const color = parseRgb(view.getComputedStyle(at).backgroundColor);\n if (color && color.alpha >= 0.5) return luminance(color) < 0.18 ? \"dark\" : \"light\";\n }\n // No background color: it may be an image or a gradient. Light text means a dark page.\n const text = parseRgb(view.getComputedStyle(element).color);\n if (text && text.alpha >= 0.5) return luminance(text) > 0.4 ? \"dark\" : \"light\";\n const scheme = view\n .getComputedStyle(element.ownerDocument.documentElement)\n .colorScheme.split(/\\s+/);\n const dark = scheme.includes(\"dark\");\n return dark && (!scheme.includes(\"light\") || prefersDark) ? \"dark\" : \"light\";\n}\n\n/** `rgb(…)` or `rgba(…)`, as computed styles give colors; `undefined` for anything else. */\nfunction parseRgb(color: string): { r: number; g: number; b: number; alpha: number } | undefined {\n const match = /^rgba?\\(([^)]*)\\)$/.exec(color.trim());\n if (!match?.[1]) return undefined;\n const parts = match[1].split(/[\\s,/]+/).filter(Boolean);\n const [r, g, b] = parts.slice(0, 3).map(Number);\n if (r === undefined || g === undefined || b === undefined) return undefined;\n const last = parts[3];\n const alpha = last === undefined ? 1 : last.endsWith(\"%\") ? parseFloat(last) / 100 : Number(last);\n if ([r, g, b, alpha].some((n) => Number.isNaN(n))) return undefined;\n return { r, g, b, alpha };\n}\n\n/** A color's relative luminance, from 0 (black) to 1 (white). */\nfunction luminance({ r, g, b }: { r: number; g: number; b: number }): number {\n const linear = (c: number) => {\n const s = c / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n };\n return 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b);\n}\n"]}
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/toolbar/page.ts"],"names":[],"mappings":"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","sourcesContent":["// What the toolbar app reads from the page the dev server rendered: its\n// anchored blocks, the element that holds them, the page's own file, and\n// whether the anchors arrived. Apart from the app so it can be tested in a\n// DOM by itself.\nimport { findBlock, parseSource } from \"@ascribed/review/marks\";\nimport type { Change } from \"../review/protocol.js\";\nimport { DATA_SOURCE, DATA_UI, DATA_VIA } from \"../names.js\";\nimport type { Anchor } from \"../shapes.js\";\n\n/** An anchor, as `ascribe diff` writes it and the marks and the overlay take it. */\nexport type { Anchor };\n\n/** The page's anchored blocks, in order, leaving out review's own elements. */\nexport function anchoredBlocks(doc: Document): HTMLElement[] {\n return Array.from(doc.querySelectorAll<HTMLElement>(`[${DATA_SOURCE}]`)).filter(\n (element) => element.closest(`[${DATA_UI}]`) === null,\n );\n}\n\n/**\n * The element holding the page's content: the innermost one holding every\n * anchored block, and not a block itself. `undefined` with none.\n */\nexport function contentRoot(blocks: readonly HTMLElement[]): HTMLElement | undefined {\n const first = blocks[0];\n if (first === undefined) return undefined;\n let root: HTMLElement | null = first.parentElement;\n while (root && !blocks.every((block) => root?.contains(block))) root = root.parentElement;\n while (root?.hasAttribute(DATA_SOURCE)) root = root.parentElement;\n if (!root || root === first.ownerDocument.documentElement) return first.ownerDocument.body;\n return root;\n}\n\n/**\n * The page's own file, as a content path: the file of the first block\n * written in the page itself (with no includes). `null` when no block is.\n */\nexport function pageFile(blocks: readonly HTMLElement[]): string | null {\n for (const block of blocks) {\n if ((block.getAttribute(DATA_VIA) ?? \"\").trim() !== \"\") continue;\n const parsed = parseSource(block.getAttribute(DATA_SOURCE) ?? \"\");\n if (parsed) return parsed.path;\n }\n return null;\n}\n\n/** An element's anchor. */\nexport function anchorOf(element: Element): Anchor {\n return {\n source: element.getAttribute(DATA_SOURCE) ?? \"\",\n via: (element.getAttribute(DATA_VIA) ?? \"\").split(\" \").filter(Boolean),\n };\n}\n\n/**\n * Whether the page's anchors arrived: false when the page has changes but\n * no anchored blocks, or when fewer than half of its changed blocks can be\n * found. A layout or component that rebuilds the content's elements drops\n * their attributes, and then nothing can be placed.\n */\nexport function anchorsArrived(\n root: ParentNode,\n blocks: number,\n changes: readonly Change[],\n): boolean {\n // A removed block is found by the block it came after, or the one it was in.\n const anchors = changes\n .map((change) => change.now ?? change.after ?? change.parent)\n .filter((anchor) => anchor !== undefined);\n if (anchors.length === 0) return true;\n if (blocks === 0) return false;\n const found = anchors.filter((anchor) => findBlock(root, anchor) !== null).length;\n return found * 2 >= anchors.length;\n}\n\n/** Where a block's source is, for opening it: `guides/install.md`, line 12. */\nexport function sourceLocation(source: string): { path: string; line: number } | undefined {\n const parsed = parseSource(source);\n return parsed ? { path: parsed.path, line: parsed.first } : undefined;\n}\n\n/**\n * Whether the page looks light or dark, from its own colors: the first\n * background that isn't see-through, from `element` up, or else its text's\n * color, or else the canvas, which the root's `color-scheme` picks (`prefersDark` says which\n * one \"light dark\" picks). Review's colors follow it, not the reader's\n * system, since a site may be light only.\n */\nexport function pageScheme(element: Element, prefersDark: boolean): \"light\" | \"dark\" {\n const view = element.ownerDocument.defaultView;\n if (!view) return prefersDark ? \"dark\" : \"light\";\n for (let at: Element | null = element; at; at = at.parentElement) {\n const color = parseRgb(view.getComputedStyle(at).backgroundColor);\n if (color && color.alpha >= 0.5) return luminance(color) < 0.18 ? \"dark\" : \"light\";\n }\n // No background color: it may be an image or a gradient. Light text means a dark page.\n const text = parseRgb(view.getComputedStyle(element).color);\n if (text && text.alpha >= 0.5) return luminance(text) > 0.4 ? \"dark\" : \"light\";\n const scheme = view\n .getComputedStyle(element.ownerDocument.documentElement)\n .colorScheme.split(/\\s+/);\n const dark = scheme.includes(\"dark\");\n return dark && (!scheme.includes(\"light\") || prefersDark) ? \"dark\" : \"light\";\n}\n\n/** `rgb(…)` or `rgba(…)`, as computed styles give colors; `undefined` for anything else. */\nfunction parseRgb(color: string): { r: number; g: number; b: number; alpha: number } | undefined {\n const match = /^rgba?\\(([^)]*)\\)$/.exec(color.trim());\n if (!match?.[1]) return undefined;\n const parts = match[1].split(/[\\s,/]+/).filter(Boolean);\n const [r, g, b] = parts.slice(0, 3).map(Number);\n if (r === undefined || g === undefined || b === undefined) return undefined;\n const last = parts[3];\n const alpha = last === undefined ? 1 : last.endsWith(\"%\") ? parseFloat(last) / 100 : Number(last);\n if ([r, g, b, alpha].some((n) => Number.isNaN(n))) return undefined;\n return { r, g, b, alpha };\n}\n\n/** A color's relative luminance, from 0 (black) to 1 (white). */\nfunction luminance({ r, g, b }: { r: number; g: number; b: number }): number {\n const linear = (c: number) => {\n const s = c / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n };\n return 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b);\n}\n"]}