@8ux-co/eelzap 0.10.0 → 0.10.2

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/preview/site/api.ts","../src/preview/site/suggestion.ts","../src/preview/site/suggest.ts"],"sourcesContent":["import type { SiteContext } from './config'\n\n/**\n * The site tools' calls to Zap's public API with the site client's\n * bearer (ADR 041 §3 to §5). The browser sends `Origin`; Zap checks it\n * against the site's preview origins and answers CORS to that origin only.\n *\n * Every answer becomes one of a few outcomes the UI words:\n *\n * - `expired` (401): the hour is up or the token was revoked; sign in again.\n * - `refused`: a network error. A request Zap refuses for a wrong origin,\n * another site or Live mode off carries NO CORS headers, so the page sees a\n * network error, not a 403; the UI says «No puedes editar ni comentar en\n * este sitio».\n * - `forbidden` (a readable 403: no Zap seat, or «Editar» turned off for this\n * site on the save-to-draft route).\n * - `rate` (429) with `Retry-After` seconds.\n * - `invalid` for anything else.\n *\n * Creates are idempotent: the caller passes the `Idempotency-Key`, kept for\n * one payload so a retry after a 429 or a dropped answer cannot open two\n * threads.\n */\n\nexport type ApiFailure =\n | { ok: false; kind: 'expired' | 'refused' | 'forbidden' | 'invalid' }\n | { ok: false; kind: 'rate'; retryAfter: number }\n\nexport type ApiResult<T> = { ok: true; data: T } | ApiFailure\n\nexport interface FieldInfo {\n type: string\n label: string\n}\n\nexport interface OnPageAnchor {\n fieldKey: string | null\n tag: string | null\n selector: string | null\n rect: { x: number; y: number; w: number; h: number } | null\n /** A pin placed on a point of the page (fractions of the whole document). */\n spot: { x: number; y: number } | null\n}\n\nexport interface OnPageComment {\n id: string\n status: 'OPEN'\n isChangeRequest: boolean\n createdAt: string\n author: { name: string | null } | null\n excerpt: string | null\n anchors: OnPageAnchor[]\n}\n\nexport interface OnPage {\n viewer: { name: string | null }\n /** Whether «Editar» is on for this site (the ADMIN's `liveEditing` switch). */\n liveEditing: boolean\n fields: Record<string, Record<string, FieldInfo>>\n comments: OnPageComment[]\n truncated: boolean\n}\n\n/** An element anchor (with its field when tagged), or a point of the page. */\nexport type ApiAnchor =\n | {\n field?: { key: string; locale?: string | null }\n dom: {\n tag?: string\n selector?: string\n textQuote?: { exact: string; prefix: string; suffix: string }\n rect: { x: number; y: number; w: number; h: number }\n viewport: { w: number; h: number }\n }\n }\n | { spot: { x: number; y: number }; viewport: { w: number; h: number } }\n\nexport interface CreateBody {\n collection?: string\n slug?: string\n document?: string\n /** «Solicitar cambio»: a change request, assigned by Zap to the record's Responsable. */\n isChangeRequest: boolean\n locale?: string\n /** The page the anchors were made on; element anchors need it. */\n pageUrl: string\n anchors: ApiAnchor[]\n body: string\n proposedValues?: Array<{ fieldKey: string; locale?: string; value: string | number | null }>\n}\n\n/** «Editar» saves to the draft: always a resolved change request, so no flag. */\nexport type DraftBody = Omit<CreateBody, 'isChangeRequest'>\n\nconst BASE = '/api/public/v1/comments'\n\nasync function call<T>(\n ctx: Pick<SiteContext, 'win' | 'zapOrigin'>,\n token: string,\n path: string,\n init: { method: 'GET' | 'POST'; body?: unknown; idempotencyKey?: string },\n): Promise<ApiResult<T>> {\n const headers: Record<string, string> = { Authorization: `Bearer ${token}` }\n if (init.body !== undefined) headers['Content-Type'] = 'application/json'\n if (init.idempotencyKey) headers['Idempotency-Key'] = init.idempotencyKey\n let response: Response\n try {\n response = await ctx.win.fetch(`${ctx.zapOrigin}${path}`, {\n method: init.method,\n headers,\n credentials: 'omit',\n body: init.body === undefined ? undefined : JSON.stringify(init.body),\n })\n } catch {\n return { ok: false, kind: 'refused' }\n }\n if (response.status === 401) return { ok: false, kind: 'expired' }\n if (response.status === 403) return { ok: false, kind: 'forbidden' }\n if (response.status === 429) {\n const seconds = Number.parseInt(response.headers.get('Retry-After') ?? '', 10)\n return { ok: false, kind: 'rate', retryAfter: seconds > 0 ? Math.min(seconds, 3600) : 30 }\n }\n if (!response.ok) return { ok: false, kind: 'invalid' }\n try {\n return { ok: true, data: (await response.json()) as T }\n } catch {\n return { ok: false, kind: 'invalid' }\n }\n}\n\nexport function fetchOnPage(\n ctx: Pick<SiteContext, 'win' | 'zapOrigin'>,\n token: string,\n pageUrl: string,\n refs: readonly string[],\n): Promise<ApiResult<OnPage>> {\n const query = new URLSearchParams({ url: pageUrl })\n if (refs.length > 0) query.set('refs', refs.slice(0, 20).join(','))\n return call<OnPage>(ctx, token, `${BASE}/on-page?${query.toString()}`, { method: 'GET' })\n}\n\n/** The part of the create answer the toast reads: who the request went to. */\nexport interface CreateAnswer {\n thread: { id: string; assignee?: { name: string | null } | null }\n}\n\nexport function createComment(\n ctx: Pick<SiteContext, 'win' | 'zapOrigin'>,\n token: string,\n body: CreateBody,\n idempotencyKey: string,\n): Promise<ApiResult<CreateAnswer>> {\n return call(ctx, token, BASE, { method: 'POST', body, idempotencyKey })\n}\n\nexport function saveToDraft(\n ctx: Pick<SiteContext, 'win' | 'zapOrigin'>,\n token: string,\n body: DraftBody,\n idempotencyKey: string,\n): Promise<ApiResult<{ thread: { id: string }; draftVersionId: string }>> {\n return call(ctx, token, `${BASE}/save-to-draft`, { method: 'POST', body, idempotencyKey })\n}\n\n/** A random Idempotency-Key (a v4-shaped UUID). */\nexport function newIdempotencyKey(win: Window): string {\n const native = (win.crypto as Crypto & { randomUUID?: () => string }).randomUUID\n if (typeof native === 'function') return native.call(win.crypto)\n const bytes = win.crypto.getRandomValues(new Uint8Array(16))\n bytes[6] = (bytes[6]! & 0x0f) | 0x40\n bytes[8] = (bytes[8]! & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n}\n","import { findAnchorElement, normalizeText } from '../anchor'\nimport type { OverlayPin } from '../overlay'\nimport { isRecordRef, parseRecordRef, type DomAnchor, type PageAnchor } from '../protocol'\nimport type { TagIndex, TaggedElement } from '../tags'\nimport type { ApiAnchor, CreateBody, DraftBody, FieldInfo, OnPage, OnPageAnchor } from './api'\n\n/**\n * What «Editar» and «Comentar» send, decided in the page (zap-cms-v2 §3.3,\n * §3.4). Pure functions over the DOM and the `on-page` answer, so each rule is\n * a spec:\n *\n * - **What can be edited or proposed.** Only ONE tagged element whose field\n * is TEXT or LONG_TEXT (edited in place, `contenteditable`) or NUMBER or URL\n * (a small input), and never on `data-zap-html` (rich text). The field types\n * come from Zap's `on-page` read (the site's schema for the records tagged\n * on the page), never from the page's markup.\n * - **Which record** a thread lands on: the element's own tag, else the\n * nearest `data-zap-entry`, else the record the page tags most.\n * - **Anchors** are the package's own (`buildAnchor`), clamped to the request\n * schema's limits, with the `field` layer only for the target record; or a\n * point of the page (`spotAnchor`).\n * - **The payloads.** «Comentar»: a plain comment, or with «Solicitar cambio»\n * a change request, which alone may carry a proposed value. «Editar»: the\n * new value, saved to the draft. The page's address goes once, as `pageUrl`.\n * - **The pins**: the open threads made on this page with an element or a\n * point, oldest first, numbered from 1, as the editor's Comentarios list\n * numbers them (`numberPins` in Zap).\n */\n\nexport const SUGGESTIBLE_TYPES = ['TEXT', 'LONG_TEXT', 'NUMBER', 'URL'] as const\n\nexport type EditKind = 'text' | 'input'\n\n/** How a field can be edited in place, or null for comment only. */\nexport function editKindFor(\n tagged: TaggedElement | null,\n field: FieldInfo | null | undefined,\n): EditKind | null {\n if (!tagged || !field || tagged.html) return null\n if (field.type === 'TEXT' || field.type === 'LONG_TEXT') return 'text'\n if (field.type === 'NUMBER' || field.type === 'URL') return 'input'\n return null\n}\n\n/** The field of a tagged element, from the `on-page` schema. */\nexport function fieldOf(\n data: Pick<OnPage, 'fields'> | null,\n tagged: TaggedElement | null,\n): FieldInfo | null {\n if (!data || !tagged) return null\n const field = data.fields?.[tagged.recordRef]?.[tagged.fieldKey]\n return field && typeof field.type === 'string' ? field : null\n}\n\n/** The record a thread about `element` belongs to, or null when the page names none. */\nexport function recordFor(element: Element, index: TagIndex): string | null {\n const tagged = index.closest(element)\n if (tagged) return tagged.recordRef\n const entry = element.closest('[data-zap-entry]')?.getAttribute('data-zap-entry')?.trim()\n if (entry && isRecordRef(entry)) return entry\n const counts = new Map<string, number>()\n for (const row of index.summary()) {\n counts.set(row.recordRef, (counts.get(row.recordRef) ?? 0) + row.count)\n }\n let best: string | null = null\n let most = 0\n for (const [ref, count] of counts) {\n if (count > most) {\n best = ref\n most = count\n }\n }\n return best\n}\n\n/** The page's address for anchors and the `on-page` read: no hash, at most 2048 chars. */\nexport function currentPageUrl(win: Window): string {\n const { origin, pathname, search } = win.location\n return `${origin}${pathname}${search}`.slice(0, 2048)\n}\n\nconst unit = (value: number) => (Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 0)\nconst whole = (value: number, max: number) =>\n Number.isFinite(value) ? Math.min(max, Math.max(1, Math.round(value))) : 1\n\ntype ElementAnchor = Extract<ApiAnchor, { dom: unknown }>\n\n/** A page anchor as the public API takes it: keys, not ids; null layers left out. */\nexport function toApiAnchor(anchor: PageAnchor, recordRef: string): ElementAnchor {\n const dom = anchor.dom\n const out: ElementAnchor = {\n dom: {\n ...(dom.tag && dom.tag.length <= 500 ? { tag: dom.tag } : {}),\n ...(dom.selector ? { selector: dom.selector } : {}),\n ...(dom.textQuote\n ? {\n textQuote: {\n exact: dom.textQuote.exact.slice(0, 500),\n prefix: dom.textQuote.prefix.slice(-32),\n suffix: dom.textQuote.suffix.slice(0, 32),\n },\n }\n : {}),\n rect: { x: unit(dom.rect.x), y: unit(dom.rect.y), w: unit(dom.rect.w), h: unit(dom.rect.h) },\n viewport: { w: whole(dom.viewport.w, 100_000), h: whole(dom.viewport.h, 1_000_000) },\n },\n }\n if (anchor.field && anchor.field.recordRef === recordRef) {\n out.field = {\n key: anchor.field.key,\n ...(anchor.field.locale ? { locale: anchor.field.locale } : {}),\n }\n }\n return out\n}\n\nexport function recordKeys(\n recordRef: string,\n): Pick<CreateBody, 'collection' | 'slug' | 'document'> {\n const parsed = parseRecordRef(recordRef)\n if (!parsed) return {}\n return parsed.kind === 'document'\n ? { document: parsed.key }\n : { collection: parsed.collection, slug: parsed.slug }\n}\n\nexport interface Proposal {\n fieldKey: string\n locale: string | null\n value: string | number\n}\n\n/**\n * The «Comentar» body. A proposal goes only with a change request; the\n * comment (trimmed) is the body, or the proposed value's text when there is\n * no comment.\n */\nexport function buildCreateBody(input: {\n recordRef: string\n pageUrl: string\n anchors: ApiAnchor[]\n comment: string\n isChangeRequest: boolean\n proposal: Proposal | null\n}): CreateBody {\n const proposal = input.isChangeRequest ? input.proposal : null\n const comment = input.comment.trim()\n const body: CreateBody = {\n ...recordKeys(input.recordRef),\n isChangeRequest: input.isChangeRequest,\n pageUrl: input.pageUrl,\n anchors: input.anchors.slice(0, 20),\n body: (comment || (proposal ? String(proposal.value) : '')).slice(0, 10_000),\n }\n if (proposal) Object.assign(body, proposedPart(proposal))\n return body\n}\n\n/** The «Editar» body: the new value, saved to the record's draft. */\nexport function buildDraftBody(input: {\n recordRef: string\n pageUrl: string\n anchors: ApiAnchor[]\n proposal: Proposal\n}): DraftBody {\n return {\n ...recordKeys(input.recordRef),\n pageUrl: input.pageUrl,\n anchors: input.anchors.slice(0, 20),\n body: String(input.proposal.value).slice(0, 10_000) || ' ',\n ...proposedPart(input.proposal),\n }\n}\n\nfunction proposedPart(proposal: Proposal): Pick<CreateBody, 'locale' | 'proposedValues'> {\n const locale = proposal.locale\n return {\n ...(locale ? { locale } : {}),\n proposedValues: [\n { fieldKey: proposal.fieldKey, ...(locale ? { locale } : {}), value: proposal.value },\n ],\n }\n}\n\n/** The value typed for `kind`, parsed for its field type; `invalid` when a number is not one. */\nexport function parseProposed(\n type: string,\n raw: string,\n): { ok: true; value: string | number } | { ok: false } {\n if (type === 'NUMBER') {\n const text = raw.trim().replace(',', '.')\n const value = Number(text)\n return text !== '' && Number.isFinite(value) ? { ok: true, value } : { ok: false }\n }\n if (type === 'TEXT' || type === 'URL') return { ok: true, value: normalizeText(raw) }\n return { ok: true, value: raw.replace(/\\r\\n?/g, '\\n').trim() }\n}\n\n/** A point of the page, from a click at viewport `(x, y)`, as fractions of the whole document. */\nexport function spotAnchor(x: number, y: number, doc: Document, win: Window): ApiAnchor {\n const root = doc.documentElement\n const w = Math.max(root.scrollWidth, 1)\n const h = Math.max(root.scrollHeight, 1)\n return {\n spot: { x: unit((x + win.scrollX) / w), y: unit((y + win.scrollY) / h) },\n viewport: { w: whole(w, 100_000), h: whole(h, 1_000_000) },\n }\n}\n\n/** An anchor the page can show: a point, or an element (the editor's `onPageAnchor`). */\nfunction onPage(anchor: OnPageAnchor): boolean {\n return !!(anchor?.spot || anchor?.rect || anchor?.tag || anchor?.selector)\n}\n\n/**\n * The numbered pins of the page's open threads. Numbers go to every thread\n * with an on-page anchor, oldest first, so «2» here is «2» in Zap; a pin is\n * drawn at the thread's point, else at the first of its elements still on the\n * page (a thread whose element is gone keeps its number and draws nothing).\n * Never throws: stored selectors only reach `safeQueryAll`.\n */\nexport function pinsFor<R extends { id: string; createdAt: string; anchors: OnPageAnchor[] }>(\n threads: readonly R[],\n index: TagIndex,\n doc: Document,\n win: Window,\n): { pins: OverlayPin[]; numbers: Map<string, number> } {\n const numbers = new Map<string, number>()\n const pins: OverlayPin[] = []\n const numbered = threads\n .filter((thread) => Array.isArray(thread.anchors) && thread.anchors.some(onPage))\n .sort(\n (a, b) => String(a.createdAt).localeCompare(String(b.createdAt)) || a.id.localeCompare(b.id),\n )\n numbered.forEach((thread, i) => {\n const n = i + 1\n numbers.set(thread.id, n)\n const spot = thread.anchors.find((anchor) => anchor?.spot)?.spot\n if (spot && Number.isFinite(spot.x) && Number.isFinite(spot.y)) {\n pins.push({ id: thread.id, n, spot: { x: unit(spot.x), y: unit(spot.y) } })\n return\n }\n for (const anchor of thread.anchors) {\n if (!onPage(anchor) || anchor.spot) continue\n const element = findAnchorElement(asDomAnchor(anchor), index, doc, win)\n if (element && element !== doc.body && element !== doc.documentElement) {\n pins.push({ id: thread.id, n, element })\n return\n }\n }\n })\n return { pins: pins.slice(0, 50), numbers }\n}\n\n/** No rectangle fallback: a pin on a guessed element is worse than none. */\nconst NOWHERE = { x: -1, y: -1, w: 0, h: 0 }\n\nfunction asDomAnchor(anchor: OnPageAnchor): DomAnchor {\n const tag = typeof anchor?.tag === 'string' && anchor.tag.length <= 500 ? anchor.tag : null\n const selector =\n typeof anchor?.selector === 'string' && anchor.selector.length <= 1024 ? anchor.selector : null\n return { tag, selector, textQuote: null, rect: NOWHERE, viewport: { w: 1, h: 1 } }\n}\n","import { buildAnchor } from '../anchor'\nimport { Overlay, OVERLAY_HOST_TAG, type OverlayPin } from '../overlay'\nimport type { OverlayMode } from '../protocol'\nimport { observeTags, TagIndex, type TaggedElement } from '../tags'\nimport {\n createComment,\n fetchOnPage,\n newIdempotencyKey,\n saveToDraft,\n type ApiAnchor,\n type ApiFailure,\n type FieldInfo,\n type OnPage,\n type OnPageComment,\n} from './api'\nimport type { ChunkHandle, SiteContext, StartOptions } from './config'\nimport { SUGGEST_MESSAGES } from './messages'\nimport {\n buildCreateBody,\n buildDraftBody,\n currentPageUrl,\n editKindFor,\n fieldOf,\n parseProposed,\n pinsFor,\n recordFor,\n spotAnchor,\n toApiAnchor,\n type EditKind,\n type Proposal,\n} from './suggestion'\nimport { clearToken, readToken } from './token'\nimport { el, icon, initials, mountHost, TOKENS as T, type IconName } from './ui'\n\n/**\n * The `suggest` chunk: «Editar» and «Comentar» on the live site (zap-cms-v2\n * §3.4, owner 2026-10-05; boards SitioBarra, SitioEditar, SitioSugerencia,\n * SitioEnviado, SitioRenovacion), loaded only once this tab holds a site\n * client token. The file keeps its old name so the CDN chunk keeps its own.\n *\n * - **Toolbar**: Navegar, Editar and Comentar, the page's open comments, the\n * person's initials, Salir (which forgets the token). Navegar intercepts\n * nothing and still shows the pins.\n * - **Editar** (only while the site's ADMIN leaves `liveEditing` on; off, the\n * tool shows disabled with «Desactivado por un administrador»): the overlay\n * outlines tagged fields; a click on a TEXT or LONG_TEXT field makes it\n * editable in place, a NUMBER or URL field opens a small input. Leaving the\n * field (or Enter) saves the new value straight to the record's draft\n * through Zap's save path and says «Guardado en el borrador»; Escape puts it\n * back. Nothing reaches the site's visitors until an ADMIN publishes in Zap.\n * - **Comentar**: the overlay outlines any element and consumes the click; a\n * click opens the composer anchored to that element, or to the point\n * clicked when the element is most of the page. Shift, Cmd or Ctrl click\n * gathers several elements for one comment. «Solicitar cambio» makes it a\n * change request, which Zap assigns to the record's Responsable; on a single\n * tagged text field it may carry «Proponer texto».\n * - **Pins**: the page's open comments (Zap's `on-page` read) as the\n * overlay's numbered gold pins, the same numbers as the editor's list; a\n * pin, or the count, opens the list.\n *\n * Everything renders in closed shadow roots as text (`ui.ts`, the overlay's\n * pins are `textContent` numbers). Excerpts, names and labels from Zap are\n * set with `textContent`; stored selectors only ever reach `safeQueryAll`.\n */\n\ntype Mode = 'navigate' | 'edit' | 'comment'\n\nconst OVERLAY_MODE: Record<Mode, OverlayMode> = {\n navigate: 'off',\n edit: 'inspect',\n comment: 'select',\n}\n\n/** The pin of the comment being written, never a thread id. */\nconst PENDING_PIN = 'eelzap:pending'\n\n/** An element taking at least this share of the viewport is commented as a point. */\nconst LARGE_SHARE = 0.5\n\nconst TOAST_MS = 8000\nconst SAVED_MS = 4000\n\ninterface Composer {\n elements: Element[]\n /** The point clicked, in viewport pixels, when the comment is on a point. */\n point: { x: number; y: number } | null\n pin: OverlayPin | null\n recordRef: string\n pageUrl: string\n anchors: ApiAnchor[]\n /** The one tagged text field a proposal may change, else null. */\n tagged: TaggedElement | null\n field: FieldInfo | null\n before: string\n card: HTMLElement\n textarea: HTMLTextAreaElement\n request: boolean\n proposing: boolean\n proposal: HTMLInputElement | HTMLTextAreaElement | null\n error: HTMLElement\n sendButton: HTMLButtonElement\n busy: boolean\n idempotency: { payload: string; key: string } | null\n}\n\ninterface Editing {\n element: HTMLElement\n tagged: TaggedElement\n field: FieldInfo\n kind: EditKind\n recordRef: string\n pageUrl: string\n anchors: ApiAnchor[]\n before: string\n /** Put the element back exactly as it was. */\n revert: () => void\n /** Stop editing, keeping what was typed. */\n keep: () => void\n card: HTMLElement | null\n input: HTMLInputElement | null\n done: boolean\n}\n\nexport function start(ctx: SiteContext, options: StartOptions = {}): ChunkHandle {\n const { win, doc } = ctx\n const stored = readToken(win, ctx.siteId)\n if (!stored) {\n void ctx.open('signin', { reason: 'expired' })\n return { destroy() {} }\n }\n const token = stored.token\n const m = SUGGEST_MESSAGES[ctx.locale]\n\n const host = mountHost(doc, CSS)\n const layer = el(doc, 'div', { class: 'layer' })\n const marks = el(doc, 'div', { class: 'marks' })\n const bottom = el(doc, 'div', { class: 'bottom' })\n layer.append(marks, bottom)\n host.root.append(layer)\n\n let mode: Mode = 'navigate'\n let selection: Element[] = []\n let data: OnPage | null = null\n let refused = false\n let composer: Composer | null = null\n let editing: Editing | null = null\n let list: OnPageComment[] | null = null\n let toast: { title: string; body: string; error?: boolean } | null = null\n let toastTimer: number | null = null\n let status: 'saving' | 'saved' | null = null\n let statusTimer: number | null = null\n let frame: number | null = null\n let destroyed = false\n let pins: OverlayPin[] = []\n let numbers = new Map<string, number>()\n let lastClick = { x: 0, y: 0, additive: false }\n\n // Before the overlay installs its own capture listeners, so this one runs\n // first and still sees clicks the overlay consumes: where, and whether the\n // person was gathering elements.\n const onClickFirst = (event: MouseEvent) => {\n lastClick = {\n x: event.clientX,\n y: event.clientY,\n additive: event.shiftKey || event.metaKey || event.ctrlKey,\n }\n }\n win.addEventListener('click', onClickFirst, true)\n\n const index = new TagIndex(doc)\n index.scan()\n const overlay = new Overlay({\n doc,\n win,\n index,\n pinsWhenOff: true,\n ignore: (target) => target === host.host,\n onInspect: (tagged) => beginEdit(tagged),\n onSelect: (elements) => onSelect(elements),\n onPin: ({ id }) => {\n if (id === PENDING_PIN) return\n const found = data?.comments.find((comment) => comment.id === id)\n if (!found) return\n list = [found]\n renderBottom()\n },\n })\n overlay.mount()\n\n const stopObserving = observeTags(\n doc.documentElement,\n () => {\n index.scan()\n placePins()\n },\n {\n ignore: (node) => {\n const own = overlay.hostElement\n return node === host.host || (!!own && (node === own || own.contains(node)))\n },\n },\n )\n\n // ── Loading the page's context ──────────────────────────────────────────\n\n async function load(): Promise<void> {\n const refs = Array.from(new Set(index.elements.map((tagged) => tagged.recordRef)))\n const result = await fetchOnPage(ctx, token, currentPageUrl(win), refs)\n if (destroyed) return\n if (!result.ok) {\n onFailure(result)\n return\n }\n const first = data === null\n data = result.data\n const labels: Record<string, string> = {}\n for (const fields of Object.values(data.fields ?? {})) {\n for (const [key, field] of Object.entries(fields)) {\n if (typeof field?.label === 'string') labels[key] = field.label\n }\n }\n overlay.setLabels(labels)\n if (!data.liveEditing && mode === 'edit') setMode('navigate')\n if (first && options.reason === 'renewed') {\n const name = data.viewer?.name\n setToast({ title: m.renewed, body: name ? m.renewedAs(name) : m.renewedBody })\n }\n renderBottom()\n placePins()\n }\n\n function onFailure(failure: ApiFailure, during: 'read' | 'comment' | 'edit' = 'read'): void {\n if (failure.kind === 'expired') {\n expire()\n return\n }\n if (failure.kind === 'forbidden' && during === 'edit') {\n // «Editar» was turned off since the page read: the tool goes disabled.\n if (data) data.liveEditing = false\n setMode('navigate')\n setToast({ title: m.editOff, body: m.editOffBody, error: true })\n return\n }\n if (failure.kind === 'refused' || failure.kind === 'forbidden') {\n refused = true\n closeComposer()\n overlay.setMode('off')\n overlay.setPins([])\n renderBottom()\n return\n }\n const message = failure.kind === 'rate' ? m.rateLimited(failure.retryAfter) : m.failed\n if (during === 'comment' && composer) showError(message)\n else\n setToast({ title: during === 'edit' ? m.saveFailed : m.failed, body: message, error: true })\n }\n\n function expire(): void {\n clearToken(win)\n void ctx.open('signin', { reason: 'expired' })\n }\n\n // ── Toolbar, tray, list, status, toast ──────────────────────────────────\n\n function canEdit(): boolean {\n return !!data?.liveEditing\n }\n\n function setMode(next: Mode): void {\n if (next === 'edit' && !canEdit()) return\n endEdit()\n closeComposer()\n mode = next\n selection = []\n overlay.clearSelection()\n overlay.setMode(OVERLAY_MODE[next])\n renderBottom()\n }\n\n function renderBottom(): void {\n if (destroyed) return\n const children: HTMLElement[] = []\n if (toast) children.push(toastCard(toast))\n if (refused) {\n children.push(refusedCard())\n bottom.replaceChildren(...children)\n marks.replaceChildren()\n return\n }\n if (list) children.push(listCard(list))\n if (selection.length > 0 && !composer) children.push(trayCard())\n if (status) {\n children.push(\n el(doc, 'div', { class: 'card status', attrs: { role: 'status' } }, [\n status === 'saved' ? icon(doc, 'check', 14) : null,\n status === 'saved' ? m.saved : m.saving,\n ]),\n )\n }\n children.push(toolbar())\n bottom.replaceChildren(...children)\n drawMarks()\n }\n\n function toolbar(): HTMLElement {\n const open = data?.comments.length ?? 0\n const name = data?.viewer?.name ?? null\n const tool = (value: Mode, label: string, glyph: IconName) => {\n const off = value === 'edit' && !canEdit()\n // Disabled by the ADMIN: says so; still loading: just not yet.\n const why = off && data ? m.editOff : null\n return el(\n doc,\n 'button',\n {\n class: 'seg',\n attrs: {\n type: 'button',\n 'aria-pressed': String(mode === value),\n 'aria-disabled': off ? 'true' : null,\n title: why,\n 'data-tip': why,\n 'data-mode': value,\n },\n on: { click: () => setMode(value) },\n },\n [icon(doc, glyph, 14), label],\n )\n }\n return el(\n doc,\n 'div',\n { class: 'card toolbar', attrs: { role: 'toolbar', 'aria-label': m.toolbar } },\n [\n icon(doc, 'zap', 20),\n el(doc, 'div', { class: 'segments', attrs: { role: 'group', 'aria-label': m.tools } }, [\n tool('navigate', m.navigate, 'pointer'),\n tool('edit', m.edit, 'pencil'),\n tool('comment', m.comment, 'commentPlus'),\n ]),\n el(doc, 'span', { class: 'divider', attrs: { 'aria-hidden': 'true' } }),\n el(\n doc,\n 'button',\n {\n class: 'tool strong',\n attrs: { type: 'button', 'aria-expanded': String(!!list), 'data-action': 'open-list' },\n on: {\n click: () => {\n list = list ? null : (data?.comments ?? [])\n renderBottom()\n },\n },\n },\n [\n icon(doc, 'thread'),\n data?.truncated ? m.open(open).replace(String(open), `${open}+`) : m.open(open),\n ],\n ),\n el(doc, 'span', { class: 'divider', attrs: { 'aria-hidden': 'true' } }),\n name\n ? el(doc, 'span', { class: 'avatar', attrs: { title: name }, text: initials(name) })\n : null,\n el(\n doc,\n 'button',\n { class: 'tool', attrs: { type: 'button', 'data-action': 'exit' }, on: { click: exit } },\n [icon(doc, 'exit'), m.exit],\n ),\n ],\n )\n }\n\n function trayCard(): HTMLElement {\n return el(doc, 'div', { class: 'card tray', attrs: { role: 'status' } }, [\n el(doc, 'span', { text: m.selected(selection.length) }),\n el(doc, 'button', {\n class: 'btn btn-outline',\n text: m.clearSelection,\n attrs: { type: 'button' },\n on: {\n click: () => {\n selection = []\n overlay.clearSelection()\n renderBottom()\n },\n },\n }),\n el(doc, 'button', {\n class: 'btn btn-primary',\n text: m.comment,\n attrs: { type: 'button', 'data-action': 'comment-selection' },\n on: {\n click: () => {\n const elements = selection\n selection = []\n overlay.clearSelection()\n openComposer(elements, null)\n },\n },\n }),\n ])\n }\n\n function listCard(comments: OnPageComment[]): HTMLElement {\n return el(\n doc,\n 'div',\n { class: 'card list sheet', attrs: { role: 'dialog', 'aria-label': m.openTitle } },\n [\n el(doc, 'div', { class: 'head' }, [\n el(doc, 'h2', { text: m.openTitle }),\n closeButton(m.dismiss, () => {\n list = null\n renderBottom()\n }),\n ]),\n comments.length === 0\n ? el(doc, 'p', { class: 'muted', text: m.noneOpen })\n : el(\n doc,\n 'ul',\n {},\n comments.map((comment) => {\n const n = numbers.get(comment.id)\n return el(doc, 'li', {}, [\n el(\n doc,\n 'button',\n {\n class: 'item',\n attrs: { type: 'button', 'data-comment': comment.id },\n on: { click: () => reveal(comment.id) },\n },\n [\n n ? el(doc, 'span', { class: 'num', text: String(n) }) : null,\n el(doc, 'span', { class: 'item-text' }, [\n el(doc, 'span', { class: 'who', text: comment.author?.name || m.someone }),\n comment.isChangeRequest\n ? el(doc, 'span', { class: 'flag', text: m.changeRequest })\n : null,\n el(doc, 'span', { class: 'what', text: comment.excerpt ?? '' }),\n ]),\n ],\n ),\n ])\n }),\n ),\n ],\n )\n }\n\n /** Scroll to a thread's pin. */\n function reveal(id: string): void {\n const pin = pins.find((entry) => entry.id === id)\n if (pin?.element) pin.element.scrollIntoView?.({ block: 'center', behavior: 'smooth' })\n else if (pin?.spot) {\n const root = doc.documentElement\n win.scrollTo?.({\n top: Math.max(0, pin.spot.y * root.scrollHeight - win.innerHeight / 2),\n behavior: 'smooth',\n })\n }\n }\n\n function toastCard(value: { title: string; body: string; error?: boolean }): HTMLElement {\n return el(\n doc,\n 'div',\n {\n class: value.error ? 'card toast toast-error' : 'card toast',\n attrs: { role: 'status', 'aria-live': 'polite' },\n },\n [\n icon(doc, value.error ? 'alert' : 'check', 18),\n el(doc, 'div', { class: 'toast-text' }, [\n el(doc, 'span', { class: 'title', text: value.title }),\n el(doc, 'span', { class: 'muted', text: value.body }),\n ]),\n closeButton(m.dismiss, () => setToast(null)),\n ],\n )\n }\n\n function refusedCard(): HTMLElement {\n return el(doc, 'div', { class: 'card refused', attrs: { role: 'alert' } }, [\n icon(doc, 'alert', 18),\n el(doc, 'div', { class: 'toast-text' }, [\n el(doc, 'span', { class: 'title', text: m.refusedTitle }),\n el(doc, 'span', { class: 'muted', text: m.refusedBody }),\n ]),\n el(\n doc,\n 'button',\n { class: 'tool', attrs: { type: 'button', 'data-action': 'exit' }, on: { click: exit } },\n [icon(doc, 'exit'), m.exit],\n ),\n ])\n }\n\n function closeButton(label: string, onClick: () => void): HTMLElement {\n return el(\n doc,\n 'button',\n {\n class: 'iconbtn',\n attrs: { type: 'button', 'aria-label': label, title: label },\n on: { click: onClick },\n },\n [icon(doc, 'x')],\n )\n }\n\n function setToast(value: typeof toast): void {\n toast = value\n if (toastTimer !== null) win.clearTimeout(toastTimer)\n toastTimer = value ? win.setTimeout(() => setToast(null), TOAST_MS) : null\n renderBottom()\n }\n\n function setStatus(value: typeof status): void {\n status = value\n if (statusTimer !== null) win.clearTimeout(statusTimer)\n statusTimer = value === 'saved' ? win.setTimeout(() => setStatus(null), SAVED_MS) : null\n renderBottom()\n }\n\n function exit(): void {\n clearToken(win)\n ctx.close()\n }\n\n // ── Pins and marks ──────────────────────────────────────────────────────\n\n function placePins(): void {\n if (destroyed || refused || !data) return\n const placed = pinsFor(data.comments ?? [], index, doc, win)\n pins = placed.pins\n numbers = placed.numbers\n overlay.setPins(composer?.pin ? [...pins, composer.pin] : pins)\n }\n\n /** The soft gold outline around what is being edited or commented (SitioEditar). */\n function drawMarks(): void {\n const targets = editing ? [editing.element] : (composer?.elements ?? [])\n marks.replaceChildren(\n ...targets\n .filter((element) => element.isConnected)\n .map((element) => {\n const rect = element.getBoundingClientRect()\n const box = el(doc, 'div', { class: 'mark' })\n box.style.left = `${rect.left - 3}px`\n box.style.top = `${rect.top - 3}px`\n box.style.width = `${rect.width + 6}px`\n box.style.height = `${rect.height + 6}px`\n return box\n }),\n )\n }\n\n function schedule(): void {\n if (frame !== null) return\n const raf = win.requestAnimationFrame?.bind(win) ?? ((fn: () => void) => win.setTimeout(fn, 16))\n frame = raf(() => {\n frame = null\n drawMarks()\n if (composer) position(composer.card, anchorRect(composer))\n if (editing?.card) position(editing.card, editing.element.getBoundingClientRect())\n }) as number\n }\n\n function position(card: HTMLElement, rect: Pick<DOMRect, 'left' | 'top' | 'bottom'>): void {\n const width = Math.min(420, win.innerWidth - 16)\n const height = card.offsetHeight || 260\n const below = rect.bottom + 10\n const top = below + height < win.innerHeight - 90 ? below : Math.max(8, rect.top - height - 10)\n const left = Math.min(Math.max(8, rect.left), Math.max(8, win.innerWidth - width - 8))\n card.style.width = `${width}px`\n card.style.top = `${top}px`\n card.style.left = `${left}px`\n }\n\n // ── Comentar ────────────────────────────────────────────────────────────\n\n function onSelect(elements: Element[]): void {\n if (mode !== 'comment' || composer) return\n if (elements.length === 0) {\n if (selection.length > 0) {\n selection = []\n renderBottom()\n }\n return\n }\n if (lastClick.additive || elements.length > 1) {\n selection = elements\n renderBottom()\n return\n }\n const element = elements[0]!\n overlay.clearSelection()\n if (isLarge(element)) openComposer([], { x: lastClick.x, y: lastClick.y }, element)\n else openComposer([element], null)\n }\n\n /** Most of the viewport: a wrapper, not the thing the person pointed at. */\n function isLarge(element: Element): boolean {\n const rect = element.getBoundingClientRect()\n const area = Math.max(1, win.innerWidth * win.innerHeight)\n return (rect.width * rect.height) / area >= LARGE_SHARE\n }\n\n function anchorRect(session: Composer): Pick<DOMRect, 'left' | 'top' | 'bottom'> {\n const first = session.elements[0]\n if (first) return first.getBoundingClientRect()\n const point = session.point ?? { x: 0, y: 0 }\n return { left: point.x, top: point.y, bottom: point.y }\n }\n\n function openComposer(\n elements: Element[],\n point: { x: number; y: number } | null,\n owner?: Element,\n ): void {\n if (refused || (elements.length === 0 && !point)) return\n const recordRef = recordFor(elements[0] ?? owner ?? doc.body, index)\n if (!recordRef) {\n setToast({ title: m.failed, body: m.noRecord, error: true })\n return\n }\n list = null\n const pageUrl = currentPageUrl(win)\n const anchors: ApiAnchor[] = point\n ? [spotAnchor(point.x, point.y, doc, win)]\n : elements\n .slice(0, 20)\n .map((element) => toApiAnchor(buildAnchor(element, index, pageUrl, doc, win), recordRef))\n const single = elements.length === 1 ? elements[0]! : null\n const own = single ? index.get(single) : null\n const tagged = own && own.recordRef === recordRef ? own : null\n const field = fieldOf(data, tagged)\n const proposable = editKindFor(tagged, field) !== null\n const target = single as HTMLElement | null\n const before =\n field?.type === 'URL' && target?.localName === 'a'\n ? (target.getAttribute('href') ?? '')\n : (target?.textContent ?? '').replace(/\\s+/g, ' ').trim()\n const spotPin = point ? anchors[0] : null\n\n const textarea = el(doc, 'textarea', {\n class: 'composer',\n attrs: {\n 'aria-label': m.commentLabel,\n rows: '3',\n maxlength: '10000',\n placeholder: m.commentPlaceholder,\n },\n })\n const error = el(doc, 'p', { class: 'error', attrs: { role: 'alert' } })\n const sendButton = el(\n doc,\n 'button',\n {\n class: 'btn btn-primary',\n attrs: { type: 'button', 'data-action': 'send' },\n on: { click: () => void submit() },\n },\n [icon(doc, 'commentPlus', 16), m.comment],\n )\n const title = tagged\n ? el(doc, 'span', { class: 'chip' }, [\n icon(doc, 'field', 12),\n field?.label || tagged.fieldKey,\n ])\n : el(doc, 'h2', {\n text: elements.length > 1 ? m.selected(elements.length) : m.commentTitle,\n })\n const extra = el(doc, 'div', { class: 'extra' })\n const card = el(\n doc,\n 'div',\n { class: 'card popover sheet', attrs: { role: 'dialog', 'aria-label': m.newComment } },\n [\n el(doc, 'div', { class: 'head' }, [title, closeButton(m.close, closeComposer)]),\n el(doc, 'div', { class: 'content' }, [\n textarea,\n extra,\n error,\n // A dialog footer: a full-bleed rule, Cancelar and the primary (OWNER-PASS 19).\n el(doc, 'div', { class: 'foot' }, [\n el(doc, 'button', {\n class: 'btn btn-outline',\n text: m.cancel,\n attrs: { type: 'button' },\n on: { click: closeComposer },\n }),\n sendButton,\n ]),\n ]),\n ],\n )\n layer.append(card)\n\n composer = {\n elements,\n point,\n pin:\n spotPin && 'spot' in spotPin\n ? { id: PENDING_PIN, n: (numbers.size || 0) + 1, spot: spotPin.spot }\n : null,\n recordRef,\n pageUrl,\n anchors,\n tagged: proposable ? tagged : null,\n field: proposable ? field : null,\n before,\n card,\n textarea,\n request: false,\n proposing: false,\n proposal: null,\n error,\n sendButton,\n busy: false,\n idempotency: null,\n }\n renderExtra(extra)\n textarea.addEventListener('input', refreshSend)\n // Enter sends, Shift+Enter breaks the line, as the editor's comment box and\n // Swarm's; the Enter that commits an IME candidate never sends.\n textarea.addEventListener('keydown', (event) => {\n if (event.key !== 'Enter' || event.shiftKey || event.isComposing || event.keyCode === 229) {\n return\n }\n event.preventDefault()\n if (!sendButton.disabled) void submit()\n })\n overlay.setMode('off')\n placePins()\n refreshSend()\n renderBottom()\n position(card, anchorRect(composer))\n textarea.focus()\n }\n\n /** «Solicitar cambio», who receives it, and «Proponer texto» (SitioSugerencia). */\n function renderExtra(extra: HTMLElement): void {\n const session = composer\n if (!session) return\n const toggle = el(\n doc,\n 'button',\n {\n class: 'check',\n attrs: {\n type: 'button',\n role: 'checkbox',\n 'aria-checked': String(session.request),\n 'data-action': 'request-change',\n },\n on: {\n click: () => {\n session.request = !session.request\n if (!session.request) {\n session.proposing = false\n session.proposal = null\n }\n renderExtra(extra)\n refreshSend()\n },\n },\n },\n [el(doc, 'span', { class: 'box', attrs: { 'aria-hidden': 'true' } }), m.requestChange],\n )\n const parts: Array<HTMLElement | null> = [toggle]\n if (session.request) {\n parts.push(el(doc, 'p', { class: 'muted small', text: m.recipient }))\n parts.push(el(doc, 'p', { class: 'muted small', text: m.requestHelp }))\n if (session.tagged && session.field && !session.proposing) {\n parts.push(\n el(\n doc,\n 'button',\n {\n class: 'btn btn-outline propose',\n attrs: { type: 'button', 'data-action': 'propose' },\n on: {\n click: () => {\n session.proposing = true\n renderExtra(extra)\n refreshSend()\n session.proposal?.focus()\n },\n },\n },\n [icon(doc, 'pencil', 14), m.propose],\n ),\n )\n }\n if (session.tagged && session.field && session.proposing) {\n const label = session.field.label || session.tagged.fieldKey\n const input =\n session.field.type === 'LONG_TEXT'\n ? el(doc, 'textarea', {\n class: 'value',\n attrs: { 'aria-label': m.proposal, rows: '3', maxlength: '10000' },\n })\n : el(doc, 'input', {\n class: 'value',\n attrs: {\n 'aria-label': m.proposal,\n type: 'text',\n inputmode: session.field.type === 'NUMBER' ? 'decimal' : null,\n },\n })\n input.value = session.proposal?.value ?? session.before\n input.addEventListener('input', refreshSend)\n session.proposal = input\n parts.push(\n el(doc, 'div', { class: 'proposal' }, [\n el(doc, 'div', { class: 'head' }, [\n el(doc, 'span', { class: 'small strong-text', text: `${m.proposalFor} ${label}` }),\n closeButton(m.removeProposal, () => {\n session.proposing = false\n session.proposal = null\n renderExtra(extra)\n refreshSend()\n }),\n ]),\n session.before\n ? el(doc, 'p', { class: 'muted small before' }, [\n `${m.now} `,\n el(doc, 'span', { class: 'strong-text', text: session.before }),\n ])\n : null,\n input,\n ]),\n )\n }\n }\n extra.replaceChildren(...parts.filter((part): part is HTMLElement => part !== null))\n }\n\n /** The proposal typed, null when none or unchanged, `invalid` for a number that is not one. */\n function proposalOf(session: Composer): Proposal | null | 'invalid' {\n if (!session.request || !session.proposing || !session.proposal) return null\n if (!session.tagged || !session.field) return null\n const parsed = parseProposed(session.field.type, session.proposal.value)\n if (!parsed.ok) return 'invalid'\n const before = parseProposed(session.field.type, session.before)\n if (before.ok && before.value === parsed.value) return null\n return { fieldKey: session.tagged.fieldKey, locale: session.tagged.locale, value: parsed.value }\n }\n\n function refreshSend(): void {\n const session = composer\n if (!session) return\n const proposal = proposalOf(session)\n const comment = session.textarea.value.trim()\n // The primary names what it does: «Comentar», or «Solicitar cambio» once flagged.\n session.sendButton.replaceChildren(\n icon(doc, session.request ? 'pencil' : 'commentPlus', 16),\n session.busy ? m.sending : session.request ? m.requestChange : m.comment,\n )\n // Text, or a parsed proposal that is not empty: either makes a body.\n const proposed = proposal && proposal !== 'invalid' && String(proposal.value) !== ''\n session.sendButton.disabled = session.busy || proposal === 'invalid' || (!comment && !proposed)\n session.error.textContent =\n proposal === 'invalid' ? m.invalidNumber : (session.error.dataset.sticky ?? '')\n }\n\n function showError(message: string): void {\n if (!composer) return\n composer.error.dataset.sticky = message\n composer.error.textContent = message\n }\n\n async function submit(): Promise<void> {\n const session = composer\n if (!session || session.busy) return\n const proposal = proposalOf(session)\n if (proposal === 'invalid') return\n const body = buildCreateBody({\n recordRef: session.recordRef,\n pageUrl: session.pageUrl,\n anchors: session.anchors,\n comment: session.textarea.value,\n isChangeRequest: session.request,\n proposal,\n })\n if (!body.body) return\n // One key per payload: a retry of the same request is the same request.\n const payload = JSON.stringify(body)\n if (session.idempotency?.payload !== payload) {\n session.idempotency = { payload, key: newIdempotencyKey(win) }\n }\n session.busy = true\n delete session.error.dataset.sticky\n refreshSend()\n const result = await createComment(ctx, token, body, session.idempotency.key)\n if (destroyed || composer !== session) return\n session.busy = false\n if (!result.ok) {\n refreshSend()\n onFailure(result, 'comment')\n return\n }\n closeComposer()\n const assignee = result.data?.thread?.assignee?.name\n setToast(\n body.isChangeRequest\n ? {\n title: m.sentRequest,\n body: m.sentRequestBody(\n typeof assignee === 'string' && assignee ? assignee : null,\n !!body.proposedValues,\n ),\n }\n : { title: m.sentComment, body: m.sentCommentBody },\n )\n void load()\n }\n\n function closeComposer(): void {\n const session = composer\n if (!session) return\n composer = null\n session.card.remove()\n if (!refused) {\n overlay.setMode(OVERLAY_MODE[mode])\n placePins()\n }\n renderBottom()\n }\n\n // ── Editar ──────────────────────────────────────────────────────────────\n\n function beginEdit(tagged: TaggedElement): void {\n if (mode !== 'edit' || refused || !canEdit()) return\n if (editing && !editing.done) {\n if (editing.element === tagged.element) return\n commitEdit(editing)\n }\n const field = fieldOf(data, tagged)\n const kind = editKindFor(tagged, field)\n if (!kind || !field) {\n setToast({ title: m.notEditable, body: m.notEditableBody, error: true })\n return\n }\n const element = tagged.element as HTMLElement\n const pageUrl = currentPageUrl(win)\n // The anchor BEFORE any edit: its text quote is what was published.\n const anchors = [toApiAnchor(buildAnchor(element, index, pageUrl, doc, win), tagged.recordRef)]\n const before =\n field.type === 'URL' && element.localName === 'a'\n ? (element.getAttribute('href') ?? '')\n : (element.textContent ?? '').replace(/\\s+/g, ' ').trim()\n const inline = kind === 'text' ? beginInlineEdit(element) : null\n const session: Editing = {\n element,\n tagged,\n field,\n kind,\n recordRef: tagged.recordRef,\n pageUrl,\n anchors,\n before,\n revert: inline?.revert ?? (() => {}),\n keep: inline?.keep ?? (() => {}),\n card: null,\n input: null,\n done: false,\n }\n editing = session\n if (inline) {\n element.addEventListener('blur', () => commitEdit(session), { once: true })\n element.focus?.()\n } else {\n openInputCard(session)\n }\n renderBottom()\n }\n\n /** NUMBER and URL: a small input beside the element; the page itself is not touched. */\n function openInputCard(session: Editing): void {\n const input = el(doc, 'input', {\n class: 'value',\n attrs: {\n 'aria-label': session.field.label || session.tagged.fieldKey,\n type: 'text',\n inputmode: session.field.type === 'NUMBER' ? 'decimal' : 'url',\n },\n })\n input.value = session.before\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n commitEdit(session)\n }\n })\n const card = el(doc, 'div', { class: 'card popover sheet', attrs: { role: 'dialog' } }, [\n el(doc, 'div', { class: 'head' }, [\n el(doc, 'span', { class: 'chip' }, [\n icon(doc, 'field', 12),\n session.field.label || session.tagged.fieldKey,\n ]),\n closeButton(m.close, () => cancelEdit(session)),\n ]),\n el(doc, 'div', { class: 'content' }, [\n input,\n el(doc, 'div', { class: 'actions' }, [\n el(doc, 'button', {\n class: 'btn btn-outline',\n text: m.cancel,\n attrs: { type: 'button' },\n on: { click: () => cancelEdit(session) },\n }),\n el(doc, 'button', {\n class: 'btn btn-primary',\n text: m.save,\n attrs: { type: 'button', 'data-action': 'save' },\n on: { click: () => commitEdit(session) },\n }),\n ]),\n ]),\n ])\n session.card = card\n session.input = input\n layer.append(card)\n position(card, session.element.getBoundingClientRect())\n input.focus()\n }\n\n /** Make the element editable in place; how to put it back, or keep what was typed. */\n function beginInlineEdit(target: HTMLElement): { revert: () => void; keep: () => void } {\n const children = Array.from(target.childNodes)\n const texts: Array<[Text, string]> = []\n const walker = doc.createTreeWalker(target, 4 /* NodeFilter.SHOW_TEXT */)\n for (let node = walker.nextNode(); node; node = walker.nextNode()) {\n texts.push([node as Text, (node as Text).data])\n }\n const hadAttribute = target.getAttribute('contenteditable')\n target.setAttribute('contenteditable', 'plaintext-only')\n if (target.contentEditable !== 'plaintext-only') target.setAttribute('contenteditable', 'true')\n target.setAttribute('spellcheck', 'true')\n const keep = () => {\n if (hadAttribute === null) target.removeAttribute('contenteditable')\n else target.setAttribute('contenteditable', hadAttribute)\n target.removeAttribute('spellcheck')\n }\n return {\n keep,\n revert: () => {\n keep()\n // The SAME nodes back, with their text: a framework holding them keeps working.\n target.replaceChildren(...children)\n for (const [node, text] of texts) node.data = text\n },\n }\n }\n\n function typedValue(session: Editing): string {\n if (session.input) return session.input.value\n const element = session.element\n return element.innerText ?? element.textContent ?? ''\n }\n\n function finishEdit(session: Editing, keepTyped: boolean): void {\n session.done = true\n if (keepTyped) session.keep()\n else session.revert()\n session.card?.remove()\n if (editing === session) editing = null\n renderBottom()\n }\n\n function cancelEdit(session: Editing): void {\n if (session.done) return\n finishEdit(session, false)\n }\n\n /** Save what was typed to the draft, or put the element back when nothing changed. */\n function commitEdit(session: Editing): void {\n if (session.done) return\n const parsed = parseProposed(session.field.type, typedValue(session))\n if (!parsed.ok) {\n finishEdit(session, false)\n setToast({ title: m.saveFailed, body: m.invalidNumber, error: true })\n return\n }\n const before = parseProposed(session.field.type, session.before)\n if (before.ok && before.value === parsed.value) {\n finishEdit(session, false)\n return\n }\n finishEdit(session, true)\n void save(session, {\n fieldKey: session.tagged.fieldKey,\n locale: session.tagged.locale,\n value: parsed.value,\n })\n }\n\n async function save(session: Editing, proposal: Proposal): Promise<void> {\n setStatus('saving')\n const body = buildDraftBody({\n recordRef: session.recordRef,\n pageUrl: session.pageUrl,\n anchors: session.anchors,\n proposal,\n })\n const result = await saveToDraft(ctx, token, body, newIdempotencyKey(win))\n if (destroyed) return\n if (!result.ok) {\n // The page goes back to what is published; nothing was saved.\n session.revert()\n setStatus(null)\n onFailure(result, 'edit')\n return\n }\n setStatus('saved')\n }\n\n function endEdit(): void {\n if (editing && !editing.done) commitEdit(editing)\n }\n\n // ── Page events ─────────────────────────────────────────────────────────\n\n const onKey = (event: KeyboardEvent) => {\n if (composer && event.key === 'Escape') {\n event.preventDefault()\n closeComposer()\n return\n }\n const session = editing\n if (!session || session.done) return\n if (event.key === 'Escape') {\n event.preventDefault()\n cancelEdit(session)\n } else if (\n event.key === 'Enter' &&\n session.kind === 'text' &&\n event.target === session.element &&\n (session.field.type === 'TEXT' || event.metaKey || event.ctrlKey)\n ) {\n // A one-line field stays one line; Enter (Cmd or Ctrl Enter for long text) saves.\n event.preventDefault()\n commitEdit(session)\n }\n }\n const onClick = (event: MouseEvent) => {\n // The element being edited may be (or sit in) a link: place the caret, never navigate.\n if (\n editing?.kind === 'text' &&\n !editing.done &&\n editing.element.contains(event.target as Node)\n ) {\n event.preventDefault()\n }\n }\n win.addEventListener('keydown', onKey, true)\n win.addEventListener('click', onClick, true)\n win.addEventListener('scroll', schedule, true)\n win.addEventListener('resize', schedule)\n const expiry = win.setTimeout(expire, Math.max(0, stored.exp - Date.now() - 30_000))\n\n overlay.setMode(OVERLAY_MODE[mode])\n renderBottom()\n void load()\n\n return {\n destroy() {\n endEdit()\n destroyed = true\n closeComposer()\n win.clearTimeout(expiry)\n if (toastTimer !== null) win.clearTimeout(toastTimer)\n if (statusTimer !== null) win.clearTimeout(statusTimer)\n win.removeEventListener('click', onClickFirst, true)\n win.removeEventListener('keydown', onKey, true)\n win.removeEventListener('click', onClick, true)\n win.removeEventListener('scroll', schedule, true)\n win.removeEventListener('resize', schedule)\n stopObserving()\n overlay.destroy()\n host.destroy()\n },\n }\n}\n\n/** Exported for specs: the overlay's own host tag, which the site tools never draw over. */\nexport { OVERLAY_HOST_TAG }\n\nconst CSS = `\n.marks { position: fixed; inset: 0; pointer-events: none; }\n.mark { position: fixed; border-radius: 4px; outline: 2px solid rgba(207,135,0,.55); }\n.bottom { position: fixed; left: 0; right: 0; bottom: 22px; display: flex; flex-direction: column;\n align-items: center; gap: 10px; pointer-events: none; padding: 0 8px; }\n.bottom > .card { position: relative; }\n.toolbar { display: flex; align-items: center; gap: 8px; padding: 6px 6px 6px 12px; white-space: nowrap;\n max-width: 100%; overflow-x: auto; }\n.segments { display: inline-flex; gap: 2px; padding: 2px; border-radius: 7px; background: ${T.subtle}; }\n.seg { position: relative; height: 26px; padding: 0 9px; border-radius: 5px; font-size: 12px; color: ${T.muted}; }\n.seg[aria-pressed=\"true\"] { background: ${T.bg}; color: ${T.fg}; box-shadow: 0 1px 2px rgba(15,23,42,.05); }\n.seg[aria-disabled=\"true\"] { opacity: .5; cursor: default; }\n.seg[data-tip]:hover::after { content: attr(data-tip); position: absolute; bottom: 34px; left: 50%;\n transform: translateX(-50%); padding: 6px 10px; border-radius: 9px; background: ${T.dark}; color: #FFFFFF;\n font-size: 12px; white-space: nowrap; }\n.tool { height: 30px; padding: 0 9px; border-radius: 9px; color: ${T.muted}; }\n.tool:hover, .seg:not([aria-disabled=\"true\"]):hover { background: ${T.subtle}; }\n.tool.strong { color: ${T.fg}; }\n.divider { width: 1px; height: 22px; background: ${T.border}; }\n.avatar { width: 26px; height: 26px; border-radius: 7px; background: #DBEAFE; color: #1D4ED8;\n display: inline-flex; align-items: center; justify-content: center; font-weight: 600; font-size: 12px; }\n.status { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px;\n font-size: 12px; font-weight: 500; }\n.status > .icon { color: #16A34A; }\n.tray { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 14px; }\n.list { width: min(420px, calc(100vw - 16px)); padding: 13px 10px 10px 15px; max-height: 50vh; overflow: auto; }\n.list ul { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }\n.item { width: 100%; text-align: left; align-items: flex-start; gap: 10px; padding: 8px; border-radius: 9px; }\n.item:hover { background: ${T.subtle}; }\n.num { flex-shrink: 0; width: 22px; height: 22px; border-radius: 999px 999px 999px 0; background: #CF8700;\n color: #FFFFFF; font-weight: 700; font-size: 11px; display: inline-flex; align-items: center; justify-content: center; }\n.item-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n.who { font-weight: 600; font-size: 12px; }\n.flag { font-size: 11px; color: ${T.goldText}; }\n.what { font-weight: 400; color: ${T.muted}; overflow-wrap: anywhere; }\n.toast, .refused { width: min(340px, calc(100vw - 16px)); display: flex; gap: 11px; padding: 14px 12px 14px 16px;\n align-self: flex-end; margin-right: 16px; }\n.refused { align-self: center; margin-right: 0; width: min(420px, calc(100vw - 16px)); align-items: flex-start; }\n.toast > .icon { color: #16A34A; }\n.refused > .icon, .toast-error > .icon { color: ${T.danger}; }\n.toast-text { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }\n.title { font-weight: 600; }\n.head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.popover { border-radius: 13px; }\n.popover > .head { padding: 13px 10px 0 15px; }\n.content { display: flex; flex-direction: column; gap: 11px; padding: 10px 15px 15px; }\n.extra { display: flex; flex-direction: column; gap: 8px; }\n.check { gap: 8px; font-size: 13px; align-self: flex-start; }\n.check .box { width: 16px; height: 16px; border-radius: 4px; border: 1px solid #90A1B9; background: ${T.bg}; }\n.check[aria-checked=\"true\"] .box { background: ${T.primary}; border-color: ${T.primaryBorder};\n box-shadow: inset 0 0 0 3px ${T.bg}; }\n.propose { align-self: flex-start; height: 30px; }\n.proposal { display: flex; flex-direction: column; gap: 6px; padding: 10px; border-radius: 12px; background: ${T.goldTint}; }\n.chip { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px 0 6px; border-radius: 7px;\n background: ${T.goldTint}; color: ${T.goldText}; font: 400 12px Poppins, ui-sans-serif, system-ui, sans-serif;\n white-space: nowrap; max-width: 220px; overflow: hidden; text-overflow: ellipsis; }\n.before { overflow-wrap: anywhere; }\n.strong-text { color: ${T.fg}; }\n.small { font-size: 12px; }\n.composer, .value { width: 100%; font: 400 13px/22px Poppins, ui-sans-serif, system-ui, sans-serif; color: ${T.fg};\n border: 1px solid ${T.border}; border-radius: 12px; padding: 8px 12px; background: ${T.bg}; resize: vertical; }\ninput.value { height: 36px; border-radius: 9px; }\n.composer:focus, .value:focus { border-color: #90A1B9; box-shadow: 0 0 0 3px ${T.focus}; outline: none; }\n.error:empty { display: none; }\n.actions { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }\n.foot { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; margin: 2px -15px -15px;\n padding: 11px 15px; border-top: 1px solid ${T.border}; }\n.foot .btn { height: 30px; gap: 7px; }\n.foot .btn-outline { padding: 0 14px; }\n`\n"],"mappings":"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","names":["onClick"]}