@orkestrel/browser 0.0.21 → 0.0.23

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 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/browser/constants.ts","../../../src/browser/helpers.ts","../../../src/browser/elements/BrowserDOMElement.ts","../../../src/browser/BrowserDOMWait.ts","../../../src/browser/elements/BrowserDOMElementManager.ts","../../../src/browser/BrowserDOMView.ts","../../../src/browser/transports/SocketCDPTransport.ts","../../../src/browser/factories.ts"],"sourcesContent":["// === Browser document\n\n/**\n * Sets the default `wait` deadline for DOM waits in a browser document toolset, `5_000`\n * milliseconds.\n */\nexport const BROWSER_DOCUMENT_TIMEOUT_MS = 5_000\n\n/**\n * Maps an HTML element to the ARIA role the HTML Accessibility API Mappings specification gives\n * it when it carries no `role` attribute.\n *\n * @remarks\n * A key is a lowercase element name, or `input:` followed by the input's `type` state. An element\n * whose mapping depends on more than its name — `a` and `area` without `href`, `select` with\n * `multiple` or a `size` above 1, an `img` with an empty `alt`, a scoped `header` or `footer`, a\n * `section` or `form` without an accessible name, and a text input with a `list` — is resolved\n * by `computeBrowserRole` before this table is read. An element or input state the mapping gives\n * no role has no entry.\n */\nexport const BROWSER_IMPLICIT_ROLES: ReadonlyMap<string, string> = Object.freeze(\n\tnew Map([\n\t\t['a', 'link'],\n\t\t['area', 'link'],\n\t\t['article', 'article'],\n\t\t['aside', 'complementary'],\n\t\t['blockquote', 'blockquote'],\n\t\t['button', 'button'],\n\t\t['caption', 'caption'],\n\t\t['code', 'code'],\n\t\t['datalist', 'listbox'],\n\t\t['dd', 'definition'],\n\t\t['del', 'deletion'],\n\t\t['details', 'group'],\n\t\t['dfn', 'term'],\n\t\t['dialog', 'dialog'],\n\t\t['dt', 'term'],\n\t\t['em', 'emphasis'],\n\t\t['fieldset', 'group'],\n\t\t['figure', 'figure'],\n\t\t['footer', 'contentinfo'],\n\t\t['form', 'form'],\n\t\t['h1', 'heading'],\n\t\t['h2', 'heading'],\n\t\t['h3', 'heading'],\n\t\t['h4', 'heading'],\n\t\t['h5', 'heading'],\n\t\t['h6', 'heading'],\n\t\t['header', 'banner'],\n\t\t['hr', 'separator'],\n\t\t['html', 'document'],\n\t\t['img', 'img'],\n\t\t['ins', 'insertion'],\n\t\t['li', 'listitem'],\n\t\t['main', 'main'],\n\t\t['math', 'math'],\n\t\t['menu', 'list'],\n\t\t['meter', 'meter'],\n\t\t['nav', 'navigation'],\n\t\t['ol', 'list'],\n\t\t['optgroup', 'group'],\n\t\t['option', 'option'],\n\t\t['output', 'status'],\n\t\t['p', 'paragraph'],\n\t\t['progress', 'progressbar'],\n\t\t['search', 'search'],\n\t\t['section', 'region'],\n\t\t['select', 'combobox'],\n\t\t['strong', 'strong'],\n\t\t['sub', 'subscript'],\n\t\t['sup', 'superscript'],\n\t\t['table', 'table'],\n\t\t['tbody', 'rowgroup'],\n\t\t['td', 'cell'],\n\t\t['textarea', 'textbox'],\n\t\t['tfoot', 'rowgroup'],\n\t\t['th', 'columnheader'],\n\t\t['thead', 'rowgroup'],\n\t\t['time', 'time'],\n\t\t['tr', 'row'],\n\t\t['ul', 'list'],\n\t\t['input:button', 'button'],\n\t\t['input:checkbox', 'checkbox'],\n\t\t['input:email', 'textbox'],\n\t\t['input:image', 'button'],\n\t\t['input:number', 'spinbutton'],\n\t\t['input:password', 'textbox'],\n\t\t['input:radio', 'radio'],\n\t\t['input:range', 'slider'],\n\t\t['input:reset', 'button'],\n\t\t['input:search', 'searchbox'],\n\t\t['input:submit', 'button'],\n\t\t['input:tel', 'textbox'],\n\t\t['input:text', 'textbox'],\n\t\t['input:url', 'textbox'],\n\t]),\n)\n\n/**\n * Names the ARIA roles whose accessible name the accessible-name computation takes from the\n * element's content when no attribute or label names it.\n */\nexport const BROWSER_CONTENT_NAMED_ROLES: ReadonlySet<string> = Object.freeze(\n\tnew Set([\n\t\t'button',\n\t\t'cell',\n\t\t'checkbox',\n\t\t'columnheader',\n\t\t'gridcell',\n\t\t'heading',\n\t\t'link',\n\t\t'menuitem',\n\t\t'menuitemcheckbox',\n\t\t'menuitemradio',\n\t\t'option',\n\t\t'radio',\n\t\t'row',\n\t\t'rowheader',\n\t\t'switch',\n\t\t'tab',\n\t\t'tooltip',\n\t\t'treeitem',\n\t]),\n)\n\n/**\n * Names the link and form targets that navigate the current browsing context or one of its\n * ancestors. `_blank` opens another browsing context, and any other name targets the browsing\n * context carrying that name, which `matchesBrowserPopup` resolves.\n */\nexport const BROWSER_CONTEXT_TARGETS: ReadonlySet<string> = Object.freeze(\n\tnew Set(['', '_self', '_parent', '_top']),\n)\n\n/** Names the `input` type states whose value an untrusted `fill` sets as typed text. */\nexport const BROWSER_TYPED_INPUTS: ReadonlySet<string> = Object.freeze(\n\tnew Set([\n\t\t'date',\n\t\t'datetime-local',\n\t\t'email',\n\t\t'month',\n\t\t'number',\n\t\t'password',\n\t\t'search',\n\t\t'tel',\n\t\t'text',\n\t\t'time',\n\t\t'url',\n\t\t'week',\n\t]),\n)\n\n/**\n * Selects the HTML interactive content a click inside a `label` can land on without activating\n * the label, as the HTML interactive-content category lists it: `a` with `href`, `audio` and\n * `video` with `controls`, `button`, `details`, `embed`, `iframe`, `img` with `usemap` or\n * `controls`, `input` other than `hidden`, `label`, `select`, and `textarea`.\n */\nexport const BROWSER_INTERACTIVE_CONTENT =\n\t'a[href], audio[controls], button, details, embed, iframe, img[usemap], img[controls], input:not([type=\"hidden\" i]), label, select, textarea, video[controls]'\n","import type { BrowserReadingInput } from '@src/core'\nimport type { BrowserNameContext } from './types.js'\nimport { attempt, isObject, isString } from '@orkestrel/contract'\nimport { BROWSER_RESULT_LIMIT, BrowserResultLimitError, normalizeBrowserName } from '@src/core'\nimport {\n\tBROWSER_CONTENT_NAMED_ROLES,\n\tBROWSER_CONTEXT_TARGETS,\n\tBROWSER_IMPLICIT_ROLES,\n\tBROWSER_INTERACTIVE_CONTENT,\n\tBROWSER_TYPED_INPUTS,\n} from './constants.js'\n\n// === Browser document\n\n/**\n * Narrows a value to a `Document` attached to a window.\n *\n * @param value - The value to test\n * @returns `true` for an object that is a `Document` with a `defaultView`, otherwise `false`\n */\nexport function isBrowserDocument(value: unknown): value is Document {\n\treturn (\n\t\tisObject(value) &&\n\t\tReflect.get(value, 'nodeType') === 9 &&\n\t\tisObject(Reflect.get(value, 'defaultView'))\n\t)\n}\n\n/**\n * Reads the URL, title, and serialized markup a DOM reading is built from, refusing a capture\n * over the result limit before any parse.\n *\n * @remarks\n * The measure is the length of `JSON.stringify({ url, title, html })`, the form the CDP capture\n * guard compares with `BROWSER_RESULT_LIMIT`, so a character JSON escapes counts as its escape\n * sequence. A reading a caller builds with `createBrowserReading` passes through no limit.\n *\n * @param node - The element whose `outerHTML` is captured; its owner document supplies `URL`\n * and `title`\n * @returns The capture's `url`, `title`, and `html`\n * @throws Thrown as a `BrowserResultLimitError` when the serialized capture is longer than\n * `BROWSER_RESULT_LIMIT` characters, with `length` and `limit` in its context.\n */\nexport function readBrowserCapture(node: Element): BrowserReadingInput {\n\tconst document = node.ownerDocument\n\tconst capture = { url: document.URL, title: document.title, html: node.outerHTML }\n\tconst length = JSON.stringify(capture).length\n\tif (length > BROWSER_RESULT_LIMIT) {\n\t\tthrow new BrowserResultLimitError('Document capture exceeds BROWSER_RESULT_LIMIT', {\n\t\t\tlength,\n\t\t\tlimit: BROWSER_RESULT_LIMIT,\n\t\t})\n\t}\n\treturn capture\n}\n\n/**\n * Computes the ARIA role of an element from its `role` attribute or its implicit mapping.\n *\n * @remarks\n * The explicit role is the first token of the `role` attribute, with `presentation` folded into\n * its synonym `none`. Without one, the role follows the HTML Accessibility API Mappings\n * specification through `BROWSER_IMPLICIT_ROLES`, after the element-specific conditions that\n * table cannot express: a link needs `href`, a `select` with `multiple` or a `size` above 1 is a\n * `listbox`, an `img` with an empty `alt` is `none`, a `header` or `footer` inside sectioning\n * content has no landmark role, a `section` or `form` needs an accessible name, a text input with\n * a `list` is a `combobox`, and a `th` with `scope=\"row\"` is a `rowheader`.\n *\n * @param element - The element to classify\n * @returns The role, or `undefined` when the element maps to no role\n *\n * @example\n * ```ts\n * const input = document.createElement('input')\n * input.type = 'checkbox'\n * computeBrowserRole(input) // 'checkbox'\n * ```\n */\nexport function computeBrowserRole(element: Element): string | undefined {\n\tconst explicit = (element.getAttribute('role') ?? '').trim().toLowerCase().split(/\\s+/)[0] ?? ''\n\tif (explicit !== '') return explicit === 'presentation' ? 'none' : explicit\n\tconst tag = element.localName\n\tif (tag === 'a' || tag === 'area') return element.hasAttribute('href') ? 'link' : undefined\n\tif (tag === 'input') {\n\t\tconst type = Reflect.get(element, 'type')\n\t\tconst role = BROWSER_IMPLICIT_ROLES.get(`input:${isString(type) ? type : 'text'}`)\n\t\treturn element.hasAttribute('list') && (role === 'textbox' || role === 'searchbox')\n\t\t\t? 'combobox'\n\t\t\t: role\n\t}\n\tif (tag === 'select') {\n\t\treturn element.hasAttribute('multiple') || Number(element.getAttribute('size')) > 1\n\t\t\t? 'listbox'\n\t\t\t: 'combobox'\n\t}\n\tif (tag === 'img' && element.getAttribute('alt') === '') return 'none'\n\tif (\n\t\t(tag === 'header' || tag === 'footer') &&\n\t\t(element.parentElement?.closest('article, aside, main, nav, section') ?? null) !== null\n\t)\n\t\treturn undefined\n\tif (\n\t\t(tag === 'section' || tag === 'form') &&\n\t\t!element.hasAttribute('aria-label') &&\n\t\t!element.hasAttribute('aria-labelledby') &&\n\t\t!element.hasAttribute('title')\n\t)\n\t\treturn undefined\n\tif (tag === 'th' && element.getAttribute('scope')?.toLowerCase() === 'row') return 'rowheader'\n\treturn BROWSER_IMPLICIT_ROLES.get(tag)\n}\n\n/**\n * Computes the accessible name of an element, trimmed and whitespace-collapsed.\n *\n * @remarks\n * The steps follow the accessible-name computation, first match wins: the elements\n * that `aria-labelledby` references in the element's own tree, each through\n * `computeBrowserAlternative` with hidden content admitted when the referenced element is itself\n * hidden (`matchesBrowserOmitted` or `matchesBrowserInvisible`), `aria-label`, the `label` of an\n * `option`, the value of an `input` button, the `alt` of an\n * image, the text of every associated `label`, the element's own content for a role in\n * `BROWSER_CONTENT_NAMED_ROLES`, then the `title` attribute, then the `placeholder` of a text\n * control. Every traversal carries the element as its `target`, so an embedded control\n * contributes its value unless it is the element being named. The `title` step follows content because a tooltip names an element only when nothing\n * else does.\n *\n * @param element - The element to name\n * @param role - The element's role. Default: `computeBrowserRole(element)`\n * @returns The name, or the empty string when no step names the element\n *\n * @example\n * ```ts\n * const button = document.createElement('button')\n * button.textContent = ' Save draft '\n * computeBrowserName(button) // 'Save draft'\n * ```\n */\nexport function computeBrowserName(element: Element, role = computeBrowserRole(element)): string {\n\tconst view = element.ownerDocument.defaultView\n\tconst tree = element.getRootNode()\n\tconst scope = view !== null && tree instanceof view.ShadowRoot ? tree : element.ownerDocument\n\tconst referenced = normalizeBrowserName(\n\t\t(element.getAttribute('aria-labelledby') ?? '')\n\t\t\t.split(/\\s+/)\n\t\t\t.flatMap((id) => {\n\t\t\t\tconst target = id === '' ? null : scope.getElementById(id)\n\t\t\t\treturn target === null\n\t\t\t\t\t? []\n\t\t\t\t\t: [\n\t\t\t\t\t\t\tcomputeBrowserAlternative(target, {\n\t\t\t\t\t\t\t\thidden: matchesBrowserOmitted(target) || matchesBrowserInvisible(target),\n\t\t\t\t\t\t\t\ttarget: element,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t]\n\t\t\t})\n\t\t\t.join(' '),\n\t)\n\tif (referenced !== '') return referenced\n\tconst label = normalizeBrowserName(element.getAttribute('aria-label') ?? '')\n\tif (label !== '') return label\n\tif (view !== null && element instanceof view.HTMLOptionElement) {\n\t\tconst option = normalizeBrowserName(element.label)\n\t\tif (option !== '') return option\n\t}\n\tconst tag = element.localName\n\tconst type = tag === 'input' ? Reflect.get(element, 'type') : undefined\n\tif (type === 'button' || type === 'submit' || type === 'reset') {\n\t\tconst value = normalizeBrowserName(\n\t\t\telement.getAttribute('value') ??\n\t\t\t\t(type === 'submit' ? 'Submit' : type === 'reset' ? 'Reset' : ''),\n\t\t)\n\t\tif (value !== '') return value\n\t}\n\tif (type === 'image' || tag === 'img' || tag === 'area') {\n\t\tconst alt = normalizeBrowserName(element.getAttribute('alt') ?? '')\n\t\tif (alt !== '') return alt\n\t}\n\tconst labelled = normalizeBrowserName(\n\t\tArray.from(scope.querySelectorAll('label'))\n\t\t\t.filter((candidate) => candidate.control === element)\n\t\t\t.map((candidate) => computeBrowserText(candidate, { target: element }))\n\t\t\t.join(' '),\n\t)\n\tif (labelled !== '') return labelled\n\tif (role !== undefined && BROWSER_CONTENT_NAMED_ROLES.has(role)) {\n\t\tconst content = computeBrowserText(element, { target: element })\n\t\tif (content !== '') return content\n\t}\n\tconst title = normalizeBrowserName(element.getAttribute('title') ?? '')\n\tif (title !== '') return title\n\treturn tag === 'input' || tag === 'textarea'\n\t\t? normalizeBrowserName(element.getAttribute('placeholder') ?? '')\n\t\t: ''\n}\n\n/**\n * Computes the text an element's content contributes to an accessible name, in the flat tree,\n * trimmed and whitespace-collapsed.\n *\n * @remarks\n * The text is what `readBrowserContent` reads, normalized.\n *\n * @param root - The element or shadow root whose content is read\n * @param context - The traversal context. Default: no hidden content and no target\n * @returns The trimmed, whitespace-collapsed text\n *\n * @example\n * ```ts\n * const link = document.createElement('a')\n * link.innerHTML = '<div>Cars</div><div>Search the fleet</div>'\n * document.body.append(link)\n * computeBrowserText(link) // 'Cars Search the fleet'\n * ```\n */\nexport function computeBrowserText(\n\troot: Element | ShadowRoot,\n\tcontext?: BrowserNameContext,\n): string {\n\treturn normalizeBrowserName(readBrowserContent(root, context))\n}\n\n/**\n * Reads the untrimmed text an element's content contributes to an accessible name, in the flat\n * tree.\n *\n * @remarks\n * The content is the open shadow root's children for a shadow host, the flattened assigned nodes\n * for a `slot`, and the child nodes otherwise. Each child contributes what\n * `computeBrowserAlternative` returns for it, and a child that `matchesBrowserBlock` reports is\n * set apart from its neighbours by a space. Whitespace at the edges of an inline child is kept,\n * so `<b>Go </b>home` reads `Go home`.\n *\n * @param root - The element or shadow root whose content is read\n * @param context - The traversal context. Default: no hidden content and no target\n * @returns The untrimmed text\n *\n * @example\n * ```ts\n * const label = document.createElement('span')\n * label.innerHTML = '<b>Go </b>home'\n * document.body.append(label)\n * readBrowserContent(label) // 'Go home'\n * ```\n */\nexport function readBrowserContent(\n\troot: Element | ShadowRoot,\n\tcontext?: BrowserNameContext,\n): string {\n\tconst view = root.ownerDocument?.defaultView ?? null\n\tconst shadow = view !== null && root instanceof view.Element ? root.shadowRoot : null\n\tconst children: readonly Node[] =\n\t\tshadow !== null\n\t\t\t? Array.from(shadow.childNodes)\n\t\t\t: view !== null && root instanceof view.HTMLSlotElement\n\t\t\t\t? root.assignedNodes({ flatten: true })\n\t\t\t\t: Array.from(root.childNodes)\n\tlet text = ''\n\tlet previous = false\n\tfor (const child of children) {\n\t\tconst piece = computeBrowserAlternative(child, context)\n\t\tconst block = view !== null && child instanceof view.Element && matchesBrowserBlock(child)\n\t\tif (piece !== '') text += text !== '' && (block || previous) ? ` ${piece}` : piece\n\t\tprevious = block\n\t}\n\treturn text\n}\n\n/**\n * Computes the text one node contributes to an accessible name: its own text alternative, or its\n * content.\n *\n * @remarks\n * A text node contributes its data unless its parent is invisible; a parent without a box of its\n * own, such as a `slot` or a `display: contents` element, is not invisible. An element\n * contributes nothing when it is hidden or is a `script` or `style`, and an element that\n * `matchesBrowserInvisible` reports contributes only what its content contributes, never its\n * value, `aria-label`, `alt`, or `title`. The context's `hidden` admits both. An embedded control\n * that is not the context's `target` contributes its value: a text field or a range its `value`,\n * a `select` its selected options' labels; a password field and the target itself contribute\n * nothing. Any other element contributes its `aria-label`, the `alt` of an image, or its content\n * through `readBrowserContent`, and its `title` when those are empty.\n *\n * @param node - The node whose contribution is computed\n * @param context - The traversal context. Default: no hidden content and no target\n * @returns The untrimmed contribution\n *\n * @example\n * ```ts\n * const image = document.createElement('img')\n * image.alt = 'Save'\n * computeBrowserAlternative(image) // 'Save'\n * ```\n */\nexport function computeBrowserAlternative(node: Node, context?: BrowserNameContext): string {\n\tconst view = node.ownerDocument?.defaultView ?? null\n\tconst hidden = context?.hidden === true\n\tif (view === null) return node.textContent ?? ''\n\tif (!(node instanceof view.Element)) {\n\t\tconst parent = node.parentElement\n\t\tif (node.nodeType !== view.Node.TEXT_NODE) return ''\n\t\treturn !hidden && parent !== null && matchesBrowserInvisible(parent)\n\t\t\t? ''\n\t\t\t: (node.textContent ?? '')\n\t}\n\tconst tag = node.localName\n\tif (!hidden && matchesBrowserHidden(node)) return ''\n\tif (tag === 'script' || tag === 'style') return ''\n\t// An invisible element's descendants can still render, so only its content can contribute.\n\tif (!hidden && matchesBrowserInvisible(node)) return readBrowserContent(node, context)\n\tconst embedded = node !== context?.target\n\tif (node instanceof view.HTMLTextAreaElement) return embedded ? node.value : ''\n\tif (node instanceof view.HTMLSelectElement) {\n\t\treturn embedded ? Array.from(node.selectedOptions, (option) => option.label).join(' ') : ''\n\t}\n\tif (\n\t\tnode instanceof view.HTMLInputElement &&\n\t\tnode.type !== 'password' &&\n\t\t(BROWSER_TYPED_INPUTS.has(node.type) || node.type === 'range')\n\t) {\n\t\treturn embedded ? node.value : ''\n\t}\n\tconst label = normalizeBrowserName(node.getAttribute('aria-label') ?? '')\n\tif (label !== '') return label\n\tconst content =\n\t\ttag === 'img' || tag === 'area' || (tag === 'input' && Reflect.get(node, 'type') === 'image')\n\t\t\t? (node.getAttribute('alt') ?? '')\n\t\t\t: readBrowserContent(node, context)\n\treturn content.trim() !== '' ? content : (node.getAttribute('title') ?? '')\n}\n\n/**\n * Checks whether an element and its subtree are hidden from the rendered page.\n *\n * @param element - The element to test\n * @returns True if the element carries `hidden` or `aria-hidden=\"true\"`, or its computed\n * `display` is `none`; false otherwise\n *\n * @example\n * ```ts\n * const note = document.createElement('p')\n * note.hidden = true\n * matchesBrowserHidden(note) // true\n * ```\n */\nexport function matchesBrowserHidden(element: Element): boolean {\n\treturn (\n\t\telement.hasAttribute('hidden') ||\n\t\telement.getAttribute('aria-hidden') === 'true' ||\n\t\telement.ownerDocument.defaultView?.getComputedStyle(element).display === 'none'\n\t)\n}\n\n/**\n * Checks whether an element renders nothing visible of its own.\n *\n * @remarks\n * An element whose computed `visibility` is `hidden` or `collapse` is invisible. An element with\n * `display: contents` has no box of its own but renders its descendants, so it is not invisible.\n * Any other element is invisible when `checkVisibility` with `visibilityProperty` and\n * `contentVisibilityAuto` reports it, which covers an element without a box and one skipped by\n * `content-visibility: auto`. A descendant can still be visible, so the rule omits the element's\n * own row and text and keeps its subtree. An `option` or `optgroup` inside a `select` is\n * invisible where the `select` is, because a drop-down renders its options outside the page's\n * boxes. Zero-size and off-screen elements stay visible. An\n * element in a document without a window is never invisible, because nothing renders it.\n *\n * @param element - The element to test\n * @returns True if the element renders nothing visible of its own; false otherwise\n *\n * @example\n * ```ts\n * const button = document.createElement('button')\n * button.style.visibility = 'hidden'\n * document.body.append(button)\n * matchesBrowserInvisible(button) // true\n * ```\n */\nexport function matchesBrowserInvisible(element: Element): boolean {\n\tconst style = element.ownerDocument.defaultView?.getComputedStyle(element)\n\tif (style === undefined) return false\n\tif (style.visibility === 'hidden' || style.visibility === 'collapse') return true\n\t// A drop-down select renders its options in a popup outside the page's boxes, so an option or\n\t// group is visible where its select is.\n\tconst select =\n\t\telement.localName === 'option' || element.localName === 'optgroup'\n\t\t\t? element.closest('select')\n\t\t\t: null\n\tif (select !== null) return matchesBrowserInvisible(select)\n\treturn (\n\t\tstyle.display !== 'contents' &&\n\t\t!element.checkVisibility({ visibilityProperty: true, contentVisibilityAuto: true })\n\t)\n}\n\n/**\n * Checks whether an element sits in an omitted subtree: the element or a flat-tree ancestor that\n * `readBrowserParent` reaches matches `matchesBrowserHidden`, through assigned slots, shadow\n * hosts, and the frame elements of same-origin documents.\n *\n * @param element - The element to test\n * @returns True if the element or an ancestor is hidden; false otherwise\n *\n * @example\n * ```ts\n * const section = document.createElement('section')\n * section.hidden = true\n * const button = section.appendChild(document.createElement('button'))\n * matchesBrowserOmitted(button) // true\n * ```\n */\nexport function matchesBrowserOmitted(element: Element): boolean {\n\tfor (\n\t\tlet current: Element | null = element;\n\t\tcurrent !== null;\n\t\tcurrent = readBrowserParent(current)\n\t) {\n\t\tif (matchesBrowserHidden(current)) return true\n\t}\n\treturn false\n}\n\n/**\n * Reads an element's parent in the flat tree: the slot it is assigned to in an open shadow root,\n * its parent element, the host of the open shadow root it sits at the top of, or the frame\n * element of its same-origin document.\n *\n * @param element - The element whose parent is read\n * @returns The parent, or `null` at the top of a top-level or cross-origin-framed document\n *\n * @example\n * ```ts\n * readBrowserParent(document.body) // document.documentElement\n * readBrowserParent(document.documentElement) // null in a top-level document\n * ```\n */\nexport function readBrowserParent(element: Element): Element | null {\n\tif (element.assignedSlot !== null) return element.assignedSlot\n\tif (element.parentElement !== null) return element.parentElement\n\tconst view: (Window & typeof globalThis) | null = element.ownerDocument.defaultView\n\tif (view === null) return null\n\tconst tree = element.getRootNode()\n\treturn tree instanceof view.ShadowRoot ? tree.host : view.frameElement\n}\n\n/**\n * Checks whether an element starts a block of its own, the unit that separates runs of text.\n *\n * @param element - The element to test\n * @returns True if the element is a `br`, or its computed `display` is neither inline-level,\n * `contents`, nor `none`; false otherwise\n *\n * @example\n * ```ts\n * const paragraph = document.createElement('p')\n * document.body.append(paragraph)\n * matchesBrowserBlock(paragraph) // true\n * ```\n */\nexport function matchesBrowserBlock(element: Element): boolean {\n\tif (element.localName === 'br') return true\n\tconst display = element.ownerDocument.defaultView?.getComputedStyle(element).display ?? ''\n\treturn !display.startsWith('inline') && display !== 'contents' && display !== 'none'\n}\n\n/**\n * Collects the tree roots a wait observes under a node: the node's own root, then every open\n * shadow root and every same-origin frame document at or beneath it, recursively.\n *\n * @param root - The document, shadow root, or element to collect under\n * @returns The roots, the node's own root first; a cross-origin frame contributes none\n *\n * @example\n * ```ts\n * collectBrowserRoots(document) // [document, ...each open shadow root and frame document]\n * ```\n */\nexport function collectBrowserRoots(root: Document | ShadowRoot | Element): readonly Node[] {\n\tconst roots: Node[] = [root.getRootNode()]\n\tconst queue: Array<Document | ShadowRoot | Element> = [root]\n\tfor (let current = queue.shift(); current !== undefined; current = queue.shift()) {\n\t\tconst view = (isBrowserDocument(current) ? current : current.ownerDocument)?.defaultView ?? null\n\t\tconst own = view !== null && current instanceof view.Element ? [current] : []\n\t\tfor (const element of [...own, ...current.querySelectorAll('*')]) {\n\t\t\tconst shadow = element.shadowRoot\n\t\t\tif (shadow !== null) {\n\t\t\t\troots.push(shadow)\n\t\t\t\tqueue.push(shadow)\n\t\t\t}\n\t\t\tconst child =\n\t\t\t\tview !== null && element instanceof view.HTMLIFrameElement ? element.contentDocument : null\n\t\t\tif (child !== null) {\n\t\t\t\troots.push(child)\n\t\t\t\tqueue.push(child)\n\t\t\t}\n\t\t}\n\t}\n\treturn roots\n}\n\n/**\n * Checks whether activating an element opens another browsing context.\n *\n * @remarks\n * A link with `href` navigates its `target`, and a form, or a submit button inside one, navigates\n * the submitter's `formtarget` or the form's `target`; either falls back to the target of the\n * document's `base` element. `_blank` opens another context, and a target in\n * `BROWSER_CONTEXT_TARGETS` does not. A name reuses the browsing context carrying it when the\n * element's window, an ancestor window, or a frame element in one of their documents carries it,\n * and opens another context otherwise; an ancestor this realm cannot read is skipped.\n *\n * @param element - The element an untrusted activation would target\n * @returns True if the activation opens another browsing context; false otherwise, including\n * for an element whose activation navigates nothing\n *\n * @example\n * ```ts\n * const link = document.createElement('a')\n * link.href = '/cars'\n * link.target = '_blank'\n * matchesBrowserPopup(link) // true\n * ```\n */\nexport function matchesBrowserPopup(element: Element): boolean {\n\tconst document = element.ownerDocument\n\tconst view = document.defaultView\n\tconst base = document.querySelector('base[target]')?.getAttribute('target') ?? ''\n\tconst tag = element.localName\n\tconst type = Reflect.get(element, 'type')\n\tconst submitter =\n\t\t(tag === 'button' && type === 'submit') ||\n\t\t(tag === 'input' && (type === 'submit' || type === 'image'))\n\tconst form = tag === 'form' ? element : Reflect.get(element, 'form')\n\tlet target: string | undefined\n\tif ((tag === 'a' || tag === 'area') && element.hasAttribute('href'))\n\t\ttarget = element.getAttribute('target') ?? base\n\telse if (view !== null && form instanceof view.HTMLFormElement && (tag === 'form' || submitter))\n\t\ttarget =\n\t\t\t(submitter ? element.getAttribute('formtarget') : null) ?? form.getAttribute('target') ?? base\n\tif (target === undefined) return false\n\tconst keyword = target.trim().toLowerCase()\n\tif (BROWSER_CONTEXT_TARGETS.has(keyword)) return false\n\tif (keyword === '_blank') return true\n\tconst selector = `iframe[name=\"${CSS.escape(target)}\"], frame[name=\"${CSS.escape(target)}\"]`\n\tlet current: Window | null = view\n\twhile (current !== null) {\n\t\tconst frame: Window = current\n\t\tconst found = attempt(\n\t\t\t() => frame.name === target || frame.document.querySelector(selector) !== null,\n\t\t)\n\t\tif (found.success && found.value) return false\n\t\tcurrent = frame.parent === frame ? null : frame.parent\n\t}\n\treturn true\n}\n\n/**\n * Checks whether a click on an element activates the `label` that contains it, following the\n * HTML label activation rule.\n *\n * @remarks\n * The click activates the label when the target is the label itself, or when no element on the\n * path from the target up to the label, the target included, matches\n * `BROWSER_INTERACTIVE_CONTENT`.\n *\n * @param target - The element the click lands on\n * @param label - The label that contains the target, or the target itself\n * @returns True if the click activates the label; false otherwise\n *\n * @example\n * ```ts\n * const label = document.createElement('label')\n * label.innerHTML = '<a href=\"#help\">Help</a> <span>Photo</span>'\n * matchesBrowserActivation(label.querySelector('a'), label) // false\n * matchesBrowserActivation(label.querySelector('span'), label) // true\n * ```\n */\nexport function matchesBrowserActivation(target: Element, label: Element): boolean {\n\tfor (\n\t\tlet current: Element | null = target;\n\t\tcurrent !== null && current !== label;\n\t\tcurrent = current.parentElement\n\t) {\n\t\tif (current.matches(BROWSER_INTERACTIVE_CONTENT)) return false\n\t}\n\treturn true\n}\n\n/**\n * Moves a tree walker past the subtree of its current node.\n *\n * @param walker - The walker to move; its root bounds the move\n * @returns The first node after the subtree in document order, or `null` when the walk is done\n *\n * @example\n * ```ts\n * const walker = document.createTreeWalker(document.body)\n * walker.nextNode()\n * skipBrowserSubtree(walker) // the first node after the body's first child and its descendants\n * ```\n */\nexport function skipBrowserSubtree(walker: TreeWalker): Node | null {\n\tlet node = walker.nextSibling()\n\twhile (node === null) {\n\t\tif (walker.parentNode() === null) return null\n\t\tnode = walker.nextSibling()\n\t}\n\treturn node\n}\n\n/**\n * Reads the nearest block container of an element, the unit that separates runs of text.\n *\n * @param element - The element to start from, or `null` for a node without a parent element\n * @param root - The node that bounds the search\n * @returns The nearest inclusive ancestor, below `root`, that `matchesBrowserBlock` reports;\n * `root` when none is\n *\n * @example\n * ```ts\n * const strong = document.createElement('strong')\n * const paragraph = document.createElement('p')\n * paragraph.append(strong)\n * document.body.append(paragraph)\n * readBrowserBlock(strong, document.body) // paragraph\n * ```\n */\nexport function readBrowserBlock(element: Element | null, root: Node): Node {\n\tlet current = element\n\twhile (current !== null && current !== root) {\n\t\tif (matchesBrowserBlock(current)) return current\n\t\tcurrent = current.parentElement\n\t}\n\treturn root\n}\n\n/**\n * Subscribes one listener to a window's navigation events until a signal aborts.\n *\n * @remarks\n * The listener receives the Navigation API's `navigatesuccess` where the window has that API, and\n * `popstate` and `hashchange` where it does not, plus `pagehide` in both cases. A `pushState` in a\n * window without the Navigation API fires none of those events.\n *\n * @param window - The window whose navigation events are observed\n * @param listener - Receives each event; `event.type` tells an unload from a same-document\n * navigation\n * @param signal - Removes every subscription when it aborts\n *\n * @example\n * ```ts\n * const release = new AbortController()\n * listenBrowserNavigation(frame.contentWindow, (event) => console.log(event.type), release.signal)\n * ```\n */\nexport function listenBrowserNavigation(\n\twindow: Window,\n\tlistener: (event: Event) => void,\n\tsignal: AbortSignal,\n): void {\n\tconst options = { signal }\n\tif (Reflect.has(window, 'navigation')) {\n\t\twindow.navigation.addEventListener('navigatesuccess', listener, options)\n\t} else {\n\t\twindow.addEventListener('popstate', listener, options)\n\t\twindow.addEventListener('hashchange', listener, options)\n\t}\n\twindow.addEventListener('pagehide', listener, options)\n}\n","import type { BrowserCallOptions, BrowserReadingInterface } from '@src/core'\nimport type { BrowserDOMElementInput, BrowserDOMElementInterface } from '../types.js'\nimport { isString } from '@orkestrel/contract'\nimport { BrowserElementError, BrowserError, createBrowserReading } from '@src/core'\nimport { BROWSER_TYPED_INPUTS } from '../constants.js'\nimport {\n\tcomputeBrowserName,\n\tmatchesBrowserActivation,\n\tmatchesBrowserPopup,\n\treadBrowserCapture,\n} from '../helpers.js'\n\n/**\n * Drives a referenced element of a DOM document without trusted input.\n *\n * @remarks\n * `click` runs `HTMLElement.click()`; `fill` and `select` set the control through its native\n * prototype setter and dispatch `input` and `change`, and `fill` refuses `UNKNOWN` an element\n * that is not a text control and a read-only one; `submit` runs `form.requestSubmit()` and\n * observes the outcome through a `submit` listener registered across the call. Each action\n * refuses with a `BrowserElementError` naming the reason: `DISABLED` for a disabled control,\n * `HIDDEN` for an element that does not render, and `UNTRUSTED` for what an untrusted event\n * cannot do, which is a click or submission that opens another browsing context, a click that\n * opens a file chooser, and typing into a contenteditable element. A click that activates a\n * `label`, on the label itself or on a descendant that `matchesBrowserActivation` admits, is\n * judged by the label's control as well: a disabled control refuses `DISABLED`, and a file input\n * refuses `UNTRUSTED` as a direct click on it does. A click on an interactive descendant of a\n * label keeps only its own checks. `role` and `name` read the description the latest outline or\n * query that encountered the element captured, so a change to the element shows after the next\n * capture, and a dropped reference keeps its last capture. Every action on an element removed\n * from its document, collected, or held across a navigation reports `GONE`.\n *\n * @example\n * ```ts\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * await view.elements.outline()\n * await view.elements.element('e1')?.click()\n * ```\n */\nexport class BrowserDOMElement implements BrowserDOMElementInterface {\n\treadonly #input: BrowserDOMElementInput\n\n\tconstructor(input: BrowserDOMElementInput) {\n\t\tthis.#input = input\n\t}\n\n\tget reference(): string {\n\t\treturn this.#input.reference\n\t}\n\n\tget role(): string {\n\t\treturn this.#input.description().role\n\t}\n\n\tget name(): string {\n\t\treturn this.#input.description().name\n\t}\n\n\tasync click(options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#actionable(options)\n\t\tconst label = node instanceof view.HTMLLabelElement ? node : node.closest('label')\n\t\tconst control = label !== null && matchesBrowserActivation(node, label) ? label.control : null\n\t\tif (control !== null && control !== node) {\n\t\t\tif (control.matches(':disabled')) {\n\t\t\t\tthrow new BrowserElementError(this.reference, 'DISABLED', 'labels a disabled control')\n\t\t\t}\n\t\t\tthis.#refuse(control)\n\t\t}\n\t\tthis.#refuse(node)\n\t\tif (node instanceof view.HTMLElement) {\n\t\t\tnode.click()\n\t\t\treturn\n\t\t}\n\t\tnode.dispatchEvent(\n\t\t\tnew view.MouseEvent('click', { bubbles: true, cancelable: true, composed: true }),\n\t\t)\n\t}\n\n\tasync fill(value: string, options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#actionable(options)\n\t\tif (node instanceof view.HTMLElement && node.isContentEditable) {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'is contenteditable, which an untrusted event cannot type into',\n\t\t\t)\n\t\t}\n\t\tconst input = node instanceof view.HTMLInputElement ? node : undefined\n\t\tconst control = input ?? (node instanceof view.HTMLTextAreaElement ? node : undefined)\n\t\tconst setter = Reflect.getOwnPropertyDescriptor(\n\t\t\tinput === undefined ? view.HTMLTextAreaElement.prototype : view.HTMLInputElement.prototype,\n\t\t\t'value',\n\t\t)?.set\n\t\tif (control === undefined || (input !== undefined && !BROWSER_TYPED_INPUTS.has(input.type))) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not a text control')\n\t\t}\n\t\tif (control.readOnly || setter === undefined) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not editable')\n\t\t}\n\t\tcontrol.focus()\n\t\tReflect.apply(setter, control, [value])\n\t\tcontrol.dispatchEvent(\n\t\t\tnew view.InputEvent('input', {\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t\tinputType: 'insertReplacementText',\n\t\t\t\tdata: value,\n\t\t\t}),\n\t\t)\n\t\tcontrol.dispatchEvent(new view.Event('change', { bubbles: true }))\n\t}\n\n\tasync select(values: readonly string[], options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#actionable(options)\n\t\tif (!(node instanceof view.HTMLSelectElement)) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not a select control')\n\t\t}\n\t\tconst choices = Array.from(node.options)\n\t\tconst selected = values.map(\n\t\t\t(value) =>\n\t\t\t\tchoices.find((option) => option.value === value) ??\n\t\t\t\tchoices.find((option) => option.label === value),\n\t\t)\n\t\tconst missing = values.find((_value, index) => selected[index] === undefined)\n\t\tif (missing !== undefined) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'has no such option')\n\t\t}\n\t\tfor (const option of choices) option.selected = selected.includes(option)\n\t\tnode.dispatchEvent(new view.Event('input', { bubbles: true, composed: true }))\n\t\tnode.dispatchEvent(new view.Event('change', { bubbles: true }))\n\t}\n\n\tasync focus(options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#current(options)\n\t\tif (node instanceof view.HTMLElement || node instanceof view.SVGElement) node.focus()\n\t}\n\n\tasync read(options?: BrowserCallOptions): Promise<BrowserReadingInterface> {\n\t\tconst [node] = this.#current(options)\n\t\treturn createBrowserReading({ ...readBrowserCapture(node), navigation: this.#input.navigation })\n\t}\n\n\tasync submit(options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#current(options)\n\t\tconst owner = node instanceof view.HTMLFormElement ? node : Reflect.get(node, 'form')\n\t\tif (!(owner instanceof view.HTMLFormElement)) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not in a form')\n\t\t}\n\t\tconst type = Reflect.get(node, 'type')\n\t\tconst submitter =\n\t\t\t(node instanceof view.HTMLButtonElement && type === 'submit') ||\n\t\t\t(node instanceof view.HTMLInputElement && (type === 'submit' || type === 'image'))\n\t\t\t\t? node\n\t\t\t\t: undefined\n\t\tif (submitter?.matches(':disabled') === true) {\n\t\t\tthrow new BrowserElementError(this.reference, 'DISABLED')\n\t\t}\n\t\tif (matchesBrowserPopup(submitter ?? owner)) {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'submits into another browsing context, which an untrusted submission cannot open',\n\t\t\t)\n\t\t}\n\t\tlet submitted = false\n\t\tconst release = new AbortController()\n\t\towner.addEventListener(\n\t\t\t'submit',\n\t\t\t() => {\n\t\t\t\tsubmitted = true\n\t\t\t},\n\t\t\t{ signal: release.signal },\n\t\t)\n\t\ttry {\n\t\t\towner.requestSubmit(submitter ?? null)\n\t\t} finally {\n\t\t\trelease.abort()\n\t\t}\n\t\tif (submitted) return\n\t\tconst invalid = Array.from(owner.elements).find(\n\t\t\t(control) => control.localName !== 'fieldset' && control.matches(':invalid'),\n\t\t)\n\t\tif (invalid === undefined) {\n\t\t\tthrow new BrowserError('did not submit', 'BROWSER_DOCUMENT_SUBMIT', {\n\t\t\t\treference: this.reference,\n\t\t\t})\n\t\t}\n\t\tconst field = computeBrowserName(invalid) || (invalid.getAttribute('name') ?? invalid.localName)\n\t\tconst reason = Reflect.get(invalid, 'validationMessage')\n\t\tconst message = isString(reason) ? reason : ''\n\t\tthrow new BrowserError(`did not submit: ${field} — ${message}`, 'BROWSER_DOCUMENT_SUBMIT', {\n\t\t\treference: this.reference,\n\t\t\tfield,\n\t\t\tmessage,\n\t\t})\n\t}\n\n\t// Resolves the element and its realm, refusing an element its view no longer holds.\n\t#current(options?: BrowserCallOptions): readonly [Element, Window & typeof globalThis] {\n\t\toptions?.signal?.throwIfAborted()\n\t\tconst node = this.#input.node.deref()\n\t\tconst view = node?.ownerDocument.defaultView ?? null\n\t\tif (!this.#input.current() || node === undefined || !node.isConnected || view === null) {\n\t\t\tthrow new BrowserElementError(this.reference, 'GONE')\n\t\t}\n\t\treturn [node, view]\n\t}\n\n\t// Resolves an element an action targets: current, rendered, and enabled.\n\t#actionable(options?: BrowserCallOptions): readonly [Element, Window & typeof globalThis] {\n\t\tconst current = this.#current(options)\n\t\tconst [node] = current\n\t\tif (!node.checkVisibility()) throw new BrowserElementError(this.reference, 'HIDDEN')\n\t\tif (node.matches(':disabled')) throw new BrowserElementError(this.reference, 'DISABLED')\n\t\treturn current\n\t}\n\n\t// Refuses an activation target whose activation an untrusted click cannot perform.\n\t#refuse(target: Element): void {\n\t\tif (matchesBrowserPopup(target)) {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'opens another browsing context, which an untrusted click cannot do',\n\t\t\t)\n\t\t}\n\t\tif (target.localName === 'input' && Reflect.get(target, 'type') === 'file') {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'opens a file chooser, which an untrusted click cannot do',\n\t\t\t)\n\t\t}\n\t}\n}\n","import type { BrowserDOMWaitInterface, BrowserMutationWait } from './types.js'\nimport { attempt } from '@orkestrel/contract'\nimport { BrowserElementError, BrowserError } from '@src/core'\nimport { isBrowserDocument } from './helpers.js'\n\n/**\n * Parks one condition on DOM mutations until it holds, with one deadline and no other timer.\n *\n * @remarks\n * The wait observes every root `roots` returns, each through a `MutationObserver` of that root's\n * realm, and re-reads the roots after every mutation batch and every capture-phase `load` in an\n * observed root: a same-origin frame or an open shadow root that appears joins the observation,\n * and a root that departed (a replaced frame document, a removed shadow root) leaves it, with its\n * observer disconnected and its `load` listener removed. The check runs before the wait parks and\n * again after every subscription, and no check runs once the deadline, counted from `start`, has\n * passed, which the wait reads again after `roots` returns. The wait settles one time: on the\n * check's first value, on the signal's abort with its reason, at the deadline with\n * `BROWSER_WAIT_TIMEOUT`, on a `pagehide` in the first root's window with `GONE`, or with whatever\n * the check or the roots function throws. A signal that aborts while `check` or `roots` runs\n * settles the wait with its reason, and wins over a value that same check returns. Settlement\n * disconnects every observer and removes every listener synchronously, so a mutation queued\n * before it runs no check, and a `roots` or `check` that settles the wait from inside leaves no\n * observer, listener, or further check behind.\n *\n * A shadow root attached after the wait began is a declared limit: attaching one fires no\n * mutation record and no event, so the wait discovers it at the next mutation or `load` it\n * observes, and a match inserted into it with no other observed change is not seen before the\n * deadline. The wait never polls to close that gap.\n *\n * @example\n * ```ts\n * const ready = await new BrowserDOMWait({\n * \troots: () => [document],\n * \tcheck: () => document.querySelector('#ready') ?? undefined,\n * \ttimeout: 1_000,\n * \tstart: performance.now(),\n * \tsubject: 'Ready wait',\n * }).execute()\n * ```\n */\nexport class BrowserDOMWait<T> implements BrowserDOMWaitInterface<T> {\n\treadonly #wait: BrowserMutationWait<T>\n\treadonly #settled = Promise.withResolvers<T>()\n\treadonly #release = new AbortController()\n\treadonly #observers = new Map<\n\t\tNode,\n\t\t{ readonly observer: MutationObserver; readonly release: AbortController }\n\t>()\n\t#main: Window | undefined\n\t#timer: ReturnType<typeof setTimeout> | undefined\n\treadonly #recheckHandler = this.#recheck.bind(this)\n\treadonly #unloadHandler = this.#unload.bind(this)\n\n\tconstructor(wait: BrowserMutationWait<T>) {\n\t\tthis.#wait = wait\n\t}\n\n\tget roots(): readonly Node[] {\n\t\treturn [...this.#observers.keys()]\n\t}\n\n\tasync execute(): Promise<T> {\n\t\tconst signal = this.#wait.signal\n\t\tsignal?.throwIfAborted()\n\t\tconst first = this.#wait.check()\n\t\t// The abort listener is not registered yet, so an abort from inside the check is read here.\n\t\tsignal?.throwIfAborted()\n\t\tif (first !== undefined) return first\n\t\tthis.#timer = setTimeout(this.#expire.bind(this), Math.max(0, this.#remaining()))\n\t\tsignal?.addEventListener('abort', () => this.#fail(signal.reason), {\n\t\t\tsignal: this.#release.signal,\n\t\t})\n\t\tthis.#recheck()\n\t\treturn await this.#settled.promise\n\t}\n\n\t// Subscribes to every live root and prunes departed ones, then runs the check. From here on\n\t// the abort listener turns a caller's abort into settlement, so the release state carries it.\n\t#recheck(): void {\n\t\tif (this.#release.signal.aborted) return\n\t\tif (this.#remaining() <= 0) {\n\t\t\tthis.#expire()\n\t\t\treturn\n\t\t}\n\t\tconst result = attempt(() => {\n\t\t\tthis.#reconcile()\n\t\t\tif (this.#release.signal.aborted) return undefined\n\t\t\tif (this.#remaining() <= 0) {\n\t\t\t\tthis.#expire()\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn this.#wait.check()\n\t\t})\n\t\tif (!result.success) this.#fail(result.error)\n\t\telse if (result.value !== undefined) this.#succeed(result.value)\n\t}\n\n\t#reconcile(): void {\n\t\tconst live = new Set(this.#wait.roots())\n\t\tif (this.#release.signal.aborted) return\n\t\tfor (const [root, entry] of this.#observers) {\n\t\t\tif (live.has(root)) continue\n\t\t\tentry.observer.disconnect()\n\t\t\tentry.release.abort()\n\t\t\tthis.#observers.delete(root)\n\t\t}\n\t\tfor (const root of live) {\n\t\t\tif (this.#observers.has(root)) continue\n\t\t\tconst document = isBrowserDocument(root) ? root : root.ownerDocument\n\t\t\tconst view = document?.defaultView ?? null\n\t\t\tif (view === null) continue\n\t\t\tconst observer = new view.MutationObserver(this.#recheckHandler)\n\t\t\tobserver.observe(root, {\n\t\t\t\tsubtree: true,\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: true,\n\t\t\t\tcharacterData: true,\n\t\t\t})\n\t\t\tconst release = new AbortController()\n\t\t\troot.addEventListener('load', this.#recheckHandler, { capture: true, signal: release.signal })\n\t\t\tthis.#observers.set(root, { observer, release })\n\t\t\t// Only the first root's window failing ends the wait; a child frame's unload is followed\n\t\t\t// by its next document's `load`, which reconciles the roots.\n\t\t\tif (this.#main !== undefined) continue\n\t\t\tthis.#main = view\n\t\t\tview.addEventListener('pagehide', this.#unloadHandler, { signal: this.#release.signal })\n\t\t}\n\t}\n\n\t#remaining(): number {\n\t\tconst now = this.#wait.now\n\t\treturn this.#wait.start + this.#wait.timeout - (now === undefined ? performance.now() : now())\n\t}\n\n\t#expire(): void {\n\t\tthis.#fail(\n\t\t\tnew BrowserError(`${this.#wait.subject} timed out`, 'BROWSER_WAIT_TIMEOUT', {\n\t\t\t\ttimeout: this.#wait.timeout,\n\t\t\t}),\n\t\t)\n\t}\n\n\t#unload(): void {\n\t\tthis.#fail(new BrowserElementError({ subject: 'document' }, 'GONE'))\n\t}\n\n\t#succeed(value: T): void {\n\t\tthis.#stop()\n\t\tthis.#settled.resolve(value)\n\t}\n\n\t#fail(error: unknown): void {\n\t\tthis.#stop()\n\t\tthis.#settled.reject(error)\n\t}\n\n\t// Releases every observer, listener, and the timer before the promise settles.\n\t#stop(): void {\n\t\tclearTimeout(this.#timer)\n\t\tthis.#release.abort()\n\t\tfor (const entry of this.#observers.values()) {\n\t\t\tentry.observer.disconnect()\n\t\t\tentry.release.abort()\n\t\t}\n\t\tthis.#observers.clear()\n\t}\n}\n","import type {\n\tBrowserCallOptions,\n\tBrowserElementInterface,\n\tBrowserElementManagerInterface,\n\tBrowserElementQuery,\n\tBrowserElementWaitOptions,\n\tBrowserOutline,\n\tBrowserOutlineNode,\n\tBrowserOutlineOptions,\n} from '@src/core'\nimport type { BrowserDOMElementInterface, BrowserDOMElementManagerInput } from '../types.js'\nimport { attempt, isInteger } from '@orkestrel/contract'\nimport {\n\tBROWSER_INTERACTIVE_ROLES,\n\tBROWSER_OUTLINE_LIMIT,\n\tBROWSER_REFERENCE_PREFIX,\n\tBrowserElementError,\n\tBrowserError,\n\tfilterBrowserOutline,\n\tnormalizeBrowserName,\n\tparseBrowserReference,\n\trenderBrowserOutline,\n\tvalidateBrowserTimeout,\n} from '@src/core'\nimport { BrowserDOMElement } from './BrowserDOMElement.js'\nimport { BrowserDOMWait } from '../BrowserDOMWait.js'\nimport {\n\tBROWSER_CONTENT_NAMED_ROLES,\n\tBROWSER_DOCUMENT_TIMEOUT_MS,\n\tBROWSER_TYPED_INPUTS,\n} from '../constants.js'\nimport {\n\tcollectBrowserRoots,\n\tcomputeBrowserName,\n\tcomputeBrowserRole,\n\tlistenBrowserNavigation,\n\tmatchesBrowserHidden,\n\tmatchesBrowserInvisible,\n\tmatchesBrowserOmitted,\n\treadBrowserBlock,\n\tskipBrowserSubtree,\n} from '../helpers.js'\n\n/**\n * Outlines a DOM document from its elements and binds stable references to the interactive ones.\n *\n * @remarks\n * Rows come in document order from a `TreeWalker` over the flat tree: an open shadow root\n * contributes its rows in place of its host's children, a `slot` its assigned nodes, and a\n * same-origin `iframe` its document's rows, while a cross-origin one renders\n * `iframe \"NAME\" (cross-origin, not readable)`. An element that `matchesBrowserHidden` reports is\n * omitted with its subtree, a scope root in such a subtree yields no row, and an element that\n * `matchesBrowserInvisible` reports yields no row of its own. An element whose role\n * `BROWSER_INTERACTIVE_ROLES` names receives a reference bound through a `WeakRef`, which never\n * changes while the manager holds it, and a reference number is never reused. Every outline or\n * query that encounters a bound element records its role and name afresh, and the element's\n * wrapper reports that latest capture, also after the manager drops the reference. A reference\n * and a reading from any walked document record that document's epoch, which advances on its own\n * navigation events and on the view's; that document's `pagehide` drops its references. A form\n * carrying a `toolname` attribute renders `[tool=NAME]` after its role and name. A `select` row\n * is followed by one `option` row per option, named by its label. Whitespace between two texts of\n * one block renders as one space, as a rendered `br` between them does, and texts with neither\n * between them stay joined. A CSS query\n * searches the document the view drives, not its child documents or shadow trees. After the\n * input's `signal` aborts, `outline`, `find`, and `wait` reject with its reason.\n *\n * `wait` parks a `BrowserDOMWait` bound to the view's lifetime over every root that\n * `collectBrowserRoots` reaches from its scope, reconciled at every observed mutation and frame\n * `load`. A shadow root attached after the wait began is a declared limit: the wait discovers it\n * at the next observed mutation or `load`, so a match inserted there with no other observed\n * change is not seen before the deadline.\n *\n * @example\n * ```ts\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * const outline = await view.elements.outline()\n * const [save] = await view.elements.find({ role: 'button', name: 'save' })\n * ```\n */\nexport class BrowserDOMElementManager implements BrowserElementManagerInterface<BrowserDOMElementInterface> {\n\treadonly #input: BrowserDOMElementManagerInput\n\treadonly #records = new Map<\n\t\tstring,\n\t\t{ readonly node: WeakRef<Element>; readonly element: BrowserDOMElement }\n\t>()\n\treadonly #identities = new WeakMap<Element, string>()\n\treadonly #descriptions = new WeakMap<\n\t\tWeakRef<Element>,\n\t\tPick<BrowserElementInterface, 'role' | 'name'>\n\t>()\n\treadonly #epochs = new WeakMap<Document, number>()\n\treadonly #watched = new WeakSet<Document>()\n\t#count = 0\n\n\tconstructor(input: BrowserDOMElementManagerInput) {\n\t\tthis.#input = input\n\t}\n\n\tasync outline(options?: BrowserOutlineOptions): Promise<BrowserOutline> {\n\t\tthis.#input.signal.throwIfAborted()\n\t\tconst limit = options?.limit ?? BROWSER_OUTLINE_LIMIT\n\t\tif (!isInteger(limit) || limit < 0) {\n\t\t\tthrow new BrowserError('Outline limit must be a nonnegative integer', undefined, { limit })\n\t\t}\n\t\toptions?.signal?.throwIfAborted()\n\t\tconst document = this.#input.document()\n\t\tconst rows = this.#capture(this.#root(document, options?.within), options?.within)\n\t\treturn renderBrowserOutline(document.URL, document.title, rows, limit)\n\t}\n\n\tasync find(\n\t\tquery: BrowserElementQuery,\n\t\toptions?: BrowserCallOptions,\n\t): Promise<readonly BrowserDOMElementInterface[]> {\n\t\tthis.#input.signal.throwIfAborted()\n\t\toptions?.signal?.throwIfAborted()\n\t\treturn this.#find(query)\n\t}\n\n\tasync wait(\n\t\tquery: BrowserElementQuery,\n\t\toptions?: BrowserElementWaitOptions,\n\t): Promise<readonly BrowserDOMElementInterface[]> {\n\t\tthis.#input.signal.throwIfAborted()\n\t\tconst start = performance.now()\n\t\tconst timeout = options?.timeout ?? BROWSER_DOCUMENT_TIMEOUT_MS\n\t\tvalidateBrowserTimeout(timeout)\n\t\tconst signal =\n\t\t\toptions?.signal === undefined\n\t\t\t\t? this.#input.signal\n\t\t\t\t: AbortSignal.any([options.signal, this.#input.signal])\n\t\treturn await new BrowserDOMWait({\n\t\t\troots: this.#roots.bind(this, query.within),\n\t\t\tcheck: this.#match.bind(this, query, options?.absent === true),\n\t\t\ttimeout,\n\t\t\tstart,\n\t\t\tsignal,\n\t\t\tsubject: 'Element wait',\n\t\t}).execute()\n\t}\n\n\telement(reference: string): BrowserDOMElementInterface | undefined {\n\t\treturn this.#records.get(parseBrowserReference(reference) ?? '')?.element\n\t}\n\n\telements(): readonly BrowserDOMElementInterface[] {\n\t\tfor (const [reference, record] of this.#records) {\n\t\t\tif (record.node.deref() === undefined) this.#records.delete(reference)\n\t\t}\n\t\treturn [...this.#records.values()].map((record) => record.element)\n\t}\n\n\tclear(): void {\n\t\tthis.#records.clear()\n\t}\n\n\t// Reports the elements a wait settles on, or undefined while it keeps waiting.\n\t#match(\n\t\tquery: BrowserElementQuery,\n\t\tabsent: boolean,\n\t): readonly BrowserDOMElementInterface[] | undefined {\n\t\tconst found = this.#find(query)\n\t\treturn (absent ? found.length === 0 : found.length > 0) ? found : undefined\n\t}\n\n\t#find(query: BrowserElementQuery): readonly BrowserDOMElement[] {\n\t\tconst root = this.#root(this.#input.document(), query.within)\n\t\tconst matches = filterBrowserOutline(this.#capture(root, query.within), query).flatMap(\n\t\t\t(row) => {\n\t\t\t\tconst record = this.#records.get(row.reference ?? '')\n\t\t\t\treturn record === undefined ? [] : [record.element]\n\t\t\t},\n\t\t)\n\t\tconst css = query.css\n\t\tif (css === undefined) return matches\n\t\tconst selected = attempt(() => Array.from(root.querySelectorAll(css)))\n\t\tif (!selected.success) {\n\t\t\tthrow new BrowserError(`CSS query is invalid: ${css}`, 'BROWSER_ELEMENT_QUERY', { css })\n\t\t}\n\t\tconst bound = selected.value.map((element) => {\n\t\t\tconst role = computeBrowserRole(element) ?? 'generic'\n\t\t\treturn this.#bind(element, role, computeBrowserName(element, role))\n\t\t})\n\t\tif (query.role === undefined && query.name === undefined) return bound\n\t\treturn matches.filter((element) => bound.includes(element))\n\t}\n\n\t// Walks one scope; a scope root in an omitted subtree yields no row.\n\t#capture(root: Element, within?: string): readonly BrowserOutlineNode[] {\n\t\tconst rows: BrowserOutlineNode[] = []\n\t\tif (within === undefined || !matchesBrowserOmitted(root)) this.#walk(root, rows, false)\n\t\treturn rows\n\t}\n\n\t// Resolves the element an outline, query, or wait is scoped to.\n\t#root(document: Document, within?: string): Element {\n\t\tif (within === undefined) return document.documentElement\n\t\tconst node = this.#records.get(parseBrowserReference(within) ?? '')?.node.deref()\n\t\tif (node === undefined || !node.isConnected || node.ownerDocument.defaultView === null) {\n\t\t\tthrow new BrowserElementError(within, 'GONE')\n\t\t}\n\t\treturn node\n\t}\n\n\t// Collects the roots a wait observes, re-read after every mutation batch and frame load.\n\t#roots(within?: string): readonly Node[] {\n\t\treturn collectBrowserRoots(this.#root(this.#input.document(), within))\n\t}\n\n\t// Appends the rows of one flat-tree subtree, descending into shadow roots, slots, and frames.\n\t#walk(root: Element | ShadowRoot, rows: BrowserOutlineNode[], muted: boolean): void {\n\t\tconst document = root.ownerDocument\n\t\tconst view = document.defaultView\n\t\tif (view === null) return\n\t\tif (root instanceof view.Element && matchesBrowserHidden(root)) return\n\t\tthis.#watch(document)\n\t\tconst walker = document.createTreeWalker(\n\t\t\troot,\n\t\t\tNodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,\n\t\t\t(node) =>\n\t\t\t\tnode instanceof view.Element && matchesBrowserHidden(node)\n\t\t\t\t\t? NodeFilter.FILTER_REJECT\n\t\t\t\t\t: NodeFilter.FILTER_ACCEPT,\n\t\t)\n\t\tlet text = ''\n\t\tlet block: Node | undefined\n\t\tlet silenced: Element | undefined\n\t\tlet node: Node | null = root instanceof view.Element ? root : walker.nextNode()\n\t\twhile (node !== null) {\n\t\t\tif (silenced !== undefined && !silenced.contains(node)) silenced = undefined\n\t\t\tconst quiet = muted || silenced !== undefined\n\t\t\tif (!(node instanceof view.Element)) {\n\t\t\t\tconst parent = node.parentElement\n\t\t\t\tconst data = node.textContent ?? ''\n\t\t\t\tconst blank = data.trim() === ''\n\t\t\t\t// Whitespace between two texts of one block separates them, so it joins the pending text\n\t\t\t\t// and normalization collapses it; elsewhere it contributes nothing.\n\t\t\t\tif (\n\t\t\t\t\t!quiet &&\n\t\t\t\t\t(!blank || text !== '') &&\n\t\t\t\t\t(parent === null || !matchesBrowserInvisible(parent))\n\t\t\t\t) {\n\t\t\t\t\tconst container = readBrowserBlock(parent, root)\n\t\t\t\t\tif (!blank) {\n\t\t\t\t\t\tif (block !== undefined && block !== container) text = this.#flush(rows, text)\n\t\t\t\t\t\ttext += data\n\t\t\t\t\t\tblock = container\n\t\t\t\t\t} else if (container === block) text += data\n\t\t\t\t}\n\t\t\t\tnode = walker.nextNode()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst invisible = matchesBrowserInvisible(node)\n\t\t\t// A rendered break separates the texts of its block the way whitespace does; the walker never\n\t\t\t// reaches a hidden one.\n\t\t\tif (node.localName === 'br') {\n\t\t\t\tif (!quiet && text !== '') text += '\\n'\n\t\t\t\tnode = walker.nextNode()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (node instanceof view.HTMLIFrameElement) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\tconst child = node.contentDocument\n\t\t\t\tif (invisible) {\n\t\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (child === null) {\n\t\t\t\t\tthis.#text(\n\t\t\t\t\t\trows,\n\t\t\t\t\t\t`iframe ${JSON.stringify(computeBrowserName(node))} (cross-origin, not readable)`,\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tthis.#walk(child.documentElement, rows, quiet)\n\t\t\t\t}\n\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (node instanceof view.HTMLSlotElement) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\tfor (const assigned of node.assignedNodes({ flatten: true })) {\n\t\t\t\t\tif (assigned instanceof view.Element) this.#walk(assigned, rows, quiet)\n\t\t\t\t\telse if (!quiet) this.#flush(rows, assigned.textContent ?? '')\n\t\t\t\t}\n\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst tool = node.localName === 'form' ? (node.getAttribute('toolname') ?? '') : ''\n\t\t\tconst role = tool === '' ? computeBrowserRole(node) : 'form'\n\t\t\tif (\n\t\t\t\t!invisible &&\n\t\t\t\trole !== undefined &&\n\t\t\t\t(BROWSER_INTERACTIVE_ROLES.has(role) || role === 'heading' || tool !== '')\n\t\t\t) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\trows.push(this.#row(node, role, view, String(rows.length)))\n\t\t\t\tif (silenced === undefined && BROWSER_CONTENT_NAMED_ROLES.has(role)) silenced = node\n\t\t\t\tif (node.localName === 'textarea') {\n\t\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst shadow = node.shadowRoot\n\t\t\tif (shadow !== null) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\tthis.#walk(shadow, rows, muted || silenced !== undefined)\n\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tnode = walker.nextNode()\n\t\t}\n\t\tthis.#flush(rows, text)\n\t}\n\n\t// Subscribes one time to a walked document's navigation events.\n\t#watch(document: Document): void {\n\t\tconst view = document.defaultView\n\t\tif (this.#watched.has(document) || view === null) return\n\t\tthis.#watched.add(document)\n\t\tlistenBrowserNavigation(\n\t\t\tview,\n\t\t\tthis.#advance.bind(this, new WeakRef(document)),\n\t\t\tthis.#input.signal,\n\t\t)\n\t}\n\n\t// Advances one document's epoch; its unload drops the references bound in it.\n\t#advance(document: WeakRef<Document>, event: Event): void {\n\t\tconst target = document.deref()\n\t\tif (target === undefined) return\n\t\tthis.#epochs.set(target, (this.#epochs.get(target) ?? 0) + 1)\n\t\tif (event.type !== 'pagehide') return\n\t\tfor (const [reference, record] of this.#records) {\n\t\t\tconst node = record.node.deref()\n\t\t\tif (node === undefined || node.ownerDocument === target) this.#records.delete(reference)\n\t\t}\n\t}\n\n\t// Reads the epoch a reading from one document records; a collected document reads -1.\n\t#epoch(document: WeakRef<Document>): number {\n\t\tconst target = document.deref()\n\t\treturn target === undefined ? -1 : this.#input.navigation() + (this.#epochs.get(target) ?? 0)\n\t}\n\n\t// Emits the pending text as one row and returns the emptied buffer.\n\t#flush(rows: BrowserOutlineNode[], text: string): string {\n\t\tif (normalizeBrowserName(text) !== '') this.#text(rows, text)\n\t\treturn ''\n\t}\n\n\t#text(rows: BrowserOutlineNode[], text: string): void {\n\t\trows.push({\n\t\t\tid: String(rows.length),\n\t\t\tparent: undefined,\n\t\t\tchildren: [],\n\t\t\tbackend: undefined,\n\t\t\tframe: undefined,\n\t\t\tignored: false,\n\t\t\trole: 'StaticText',\n\t\t\tname: normalizeBrowserName(text),\n\t\t\tdescription: undefined,\n\t\t\tvalue: undefined,\n\t\t\tproperties: {},\n\t\t\tsession: '',\n\t\t\treference: undefined,\n\t\t})\n\t}\n\n\t#row(\n\t\telement: Element,\n\t\trole: string,\n\t\tview: Window & typeof globalThis,\n\t\tid: string,\n\t): BrowserOutlineNode {\n\t\tconst name = computeBrowserName(element, role)\n\t\tconst tool = element.localName === 'form' ? element.getAttribute('toolname') : null\n\t\tconst reference = role === 'heading' ? undefined : this.#bind(element, role, name).reference\n\t\tconst input = element instanceof view.HTMLInputElement ? element : undefined\n\t\tconst checked =\n\t\t\tinput !== undefined && (input.type === 'checkbox' || input.type === 'radio')\n\t\t\t\t? input.checked\n\t\t\t\t: element.getAttribute('aria-checked') === 'true'\n\t\tlet value: string | undefined\n\t\tif (element instanceof view.HTMLSelectElement)\n\t\t\tvalue = Array.from(element.selectedOptions, (option) => option.label).join(', ')\n\t\telse if (element instanceof view.HTMLTextAreaElement) value = element.value\n\t\telse if (\n\t\t\tinput !== undefined &&\n\t\t\tinput.type !== 'password' &&\n\t\t\t(BROWSER_TYPED_INPUTS.has(input.type) || input.type === 'range')\n\t\t)\n\t\t\tvalue = input.value\n\t\treturn {\n\t\t\tid: reference ?? id,\n\t\t\tparent: undefined,\n\t\t\tchildren: [],\n\t\t\tbackend: undefined,\n\t\t\tframe: undefined,\n\t\t\tignored: false,\n\t\t\trole,\n\t\t\tname,\n\t\t\tdescription: undefined,\n\t\t\tvalue,\n\t\t\tproperties: { checked, disabled: element.matches(':disabled') },\n\t\t\t...(tool === null || tool === '' ? {} : { tool }),\n\t\t\tsession: '',\n\t\t\treference,\n\t\t}\n\t}\n\n\t#bind(element: Element, role: string, name: string): BrowserDOMElement {\n\t\tconst known = this.#identities.get(element)\n\t\tconst existing = known === undefined ? undefined : this.#records.get(known)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#descriptions.set(existing.node, { role, name })\n\t\t\treturn existing.element\n\t\t}\n\t\tthis.#count += 1\n\t\tconst reference = `${BROWSER_REFERENCE_PREFIX}${this.#count}`\n\t\tconst node = new WeakRef(element)\n\t\tconst description = { role, name }\n\t\tthis.#descriptions.set(node, description)\n\t\tconst created = new BrowserDOMElement({\n\t\t\treference,\n\t\t\tdescription: this.#description.bind(this, node, description),\n\t\t\tnode,\n\t\t\tcurrent: this.#holds.bind(this, reference),\n\t\t\tnavigation: this.#epoch.bind(this, new WeakRef(element.ownerDocument)),\n\t\t})\n\t\tthis.#records.set(reference, { node, element: created })\n\t\tthis.#identities.set(element, reference)\n\t\treturn created\n\t}\n\n\t#holds(reference: string): boolean {\n\t\treturn this.#records.has(reference)\n\t}\n\n\t// Reads the latest capture of a binding; the entry lives as long as the wrapper's weak node.\n\t#description(\n\t\tnode: WeakRef<Element>,\n\t\tcaptured: Pick<BrowserElementInterface, 'role' | 'name'>,\n\t): Pick<BrowserElementInterface, 'role' | 'name'> {\n\t\treturn this.#descriptions.get(node) ?? captured\n\t}\n}\n","import type {\n\tBrowserCallOptions,\n\tBrowserElementManagerInterface,\n\tBrowserReadingInterface,\n} from '@src/core'\nimport type {\n\tBrowserDOMElementInterface,\n\tBrowserDOMViewInterface,\n\tBrowserDOMViewOptions,\n} from './types.js'\nimport { BrowserError, createBrowserReading, validateBrowserTimeout } from '@src/core'\nimport { BrowserDOMElementManager } from './elements/BrowserDOMElementManager.js'\nimport { BROWSER_DOCUMENT_TIMEOUT_MS } from './constants.js'\nimport { BrowserDOMWait } from './BrowserDOMWait.js'\nimport {\n\tcollectBrowserRoots,\n\tisBrowserDocument,\n\tlistenBrowserNavigation,\n\treadBrowserCapture,\n} from './helpers.js'\n\n/**\n * Reads and drives a DOM document from a realm that can reach it, without trusted input.\n *\n * @remarks\n * The view follows the window of the document it was given, so after that window navigates it\n * drives the window's next document. A reading records the view's navigation epoch, and reports\n * stale after the epoch advances. The epoch advances on the Navigation API's `navigatesuccess`\n * where the window has that API, on `popstate` and `hashchange` where it does not, on `pagehide`,\n * and when the window's document changes. A `pushState` in a window without the Navigation API\n * fires none of those events, so a reading there stays current across it. A cross-document\n * navigation also clears every element reference. `destroy()` releases the listeners and every\n * reference, and fails every pending wait with a `BrowserError` coded\n * `BROWSER_DOCUMENT_DESTROYED`; after it, `title()`, `read()`, `wait()`, and the element manager's\n * `outline()`, `find()`, and `wait()` reject with that error, and a second `destroy()` does\n * nothing more. `trusted` is `false`: no action grants user activation, and\n * every event the view's actions dispatch themselves carries `isTrusted` `false`. The `submit`\n * event that `requestSubmit()` fires during a `submit` is generated by the browser and carries\n * `isTrusted` `true`.\n *\n * @example\n * ```ts\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * const reading = await view.read()\n * reading.text().text\n * ```\n */\nexport class BrowserDOMView implements BrowserDOMViewInterface {\n\treadonly #window: Window\n\treadonly #elements: BrowserDOMElementManager\n\treadonly #release = new AbortController()\n\treadonly #navigateHandler = this.#navigate.bind(this)\n\t#document: Document\n\t#epoch = 0\n\t#listeners = new AbortController()\n\n\tconstructor(options: BrowserDOMViewOptions) {\n\t\tconst document = options.document\n\t\tif (!isBrowserDocument(document) || document.defaultView === null) {\n\t\t\tthrow new BrowserError(\n\t\t\t\t'Browser DOM view requires a document attached to a window',\n\t\t\t\t'BROWSER_DOCUMENT',\n\t\t\t)\n\t\t}\n\t\tif (document === globalThis.document && options.own !== true) {\n\t\t\tthrow new BrowserError(\n\t\t\t\t'Browser DOM view drives globalThis.document only with own: true, because an action that navigates the realm it runs in cannot return',\n\t\t\t\t'BROWSER_DOCUMENT_OWN',\n\t\t\t)\n\t\t}\n\t\tthis.#window = document.defaultView\n\t\tthis.#document = document\n\t\tthis.#elements = new BrowserDOMElementManager({\n\t\t\tdocument: this.#current.bind(this),\n\t\t\tnavigation: this.#navigation.bind(this),\n\t\t\tsignal: this.#release.signal,\n\t\t})\n\t\tthis.#listen()\n\t}\n\n\tget url(): string {\n\t\treturn this.#current().URL\n\t}\n\n\tget trusted(): boolean {\n\t\treturn false\n\t}\n\n\tget elements(): BrowserElementManagerInterface<BrowserDOMElementInterface> {\n\t\treturn this.#elements\n\t}\n\n\tasync title(options?: BrowserCallOptions): Promise<string> {\n\t\tthis.#release.signal.throwIfAborted()\n\t\toptions?.signal?.throwIfAborted()\n\t\treturn this.#current().title\n\t}\n\n\tasync read(options?: BrowserCallOptions): Promise<BrowserReadingInterface> {\n\t\tthis.#release.signal.throwIfAborted()\n\t\toptions?.signal?.throwIfAborted()\n\t\treturn createBrowserReading({\n\t\t\t...readBrowserCapture(this.#current().documentElement),\n\t\t\tnavigation: this.#navigation.bind(this),\n\t\t})\n\t}\n\n\tasync wait(text: string, options?: BrowserCallOptions): Promise<void> {\n\t\tthis.#release.signal.throwIfAborted()\n\t\tconst start = performance.now()\n\t\tconst timeout = options?.timeout ?? BROWSER_DOCUMENT_TIMEOUT_MS\n\t\tvalidateBrowserTimeout(timeout)\n\t\tconst document = this.#current()\n\t\tawait new BrowserDOMWait({\n\t\t\troots: collectBrowserRoots.bind(undefined, document),\n\t\t\tcheck: this.#contains.bind(this, document, text),\n\t\t\ttimeout,\n\t\t\tstart,\n\t\t\tsignal:\n\t\t\t\toptions?.signal === undefined\n\t\t\t\t\t? this.#release.signal\n\t\t\t\t\t: AbortSignal.any([options.signal, this.#release.signal]),\n\t\t\tsubject: 'Browser text wait',\n\t\t}).execute()\n\t}\n\n\tdestroy(): void {\n\t\tthis.#release.abort(\n\t\t\tnew BrowserError('Browser DOM view was destroyed', 'BROWSER_DOCUMENT_DESTROYED'),\n\t\t)\n\t\tthis.#listeners.abort()\n\t\tthis.#elements.clear()\n\t}\n\n\t// Returns the window's document, first moving the view onto it after a document change.\n\t#current(): Document {\n\t\tconst document = this.#window.document\n\t\tif (document !== this.#document && !this.#release.signal.aborted) {\n\t\t\tthis.#document = document\n\t\t\tthis.#navigate()\n\t\t\tthis.#listen()\n\t\t}\n\t\treturn this.#document\n\t}\n\n\t#navigation(): number {\n\t\tthis.#current()\n\t\treturn this.#epoch\n\t}\n\n\t#navigate(event?: Event): void {\n\t\tthis.#epoch += 1\n\t\tif (event === undefined || event.type === 'pagehide') this.#elements.clear()\n\t}\n\n\t#contains(document: Document, text: string): true | undefined {\n\t\treturn (document.body?.innerText ?? '').includes(text) ? true : undefined\n\t}\n\n\t// Subscribes to the navigation events of the window's current document.\n\t#listen(): void {\n\t\tthis.#listeners.abort()\n\t\tthis.#listeners = new AbortController()\n\t\tlistenBrowserNavigation(this.#window, this.#navigateHandler, this.#listeners.signal)\n\t}\n}\n","import type { CDPTransportEventMap, CDPTransportInterface } from '@src/core'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { SocketCDPTransportOptions } from '../types.js'\nimport { attempt, isString } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { BROWSER_DEFAULT_TIMEOUT_MS, BrowserConnectionError, BrowserTransition } from '@src/core'\n\n/**\n * Provides a raw CDP text transport over the browser's native `WebSocket`.\n *\n * @remarks\n * `start()` resolves on the socket's `open` event and rejects with a `BrowserConnectionError`\n * carrying `url` for a URL whose scheme is not `ws:` or `wss:`, for a URL the `WebSocket`\n * constructor refuses (one with a fragment), for a socket that fails or closes before it opens,\n * and at the `timeout` deadline. Concurrent and repeated `start()` and `close()`\n * calls share their active transition, and a later `start()` opens a fresh socket after the\n * prior one closes. A close the remote end initiates emits `close`. The driven Chromium must\n * allow the caller's origin through `--remote-allow-origins`.\n *\n * @example\n * ```ts\n * const transport = new SocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' })\n * await transport.start()\n * await transport.close()\n * ```\n */\nexport class SocketCDPTransport implements CDPTransportInterface {\n\treadonly #emitter: Emitter<CDPTransportEventMap>\n\treadonly #url: string\n\treadonly #timeout: number\n\treadonly #starting = new BrowserTransition()\n\treadonly #closing = new BrowserTransition()\n\t#socket: WebSocket | undefined\n\t#opening: PromiseWithResolvers<void> | undefined\n\n\tconstructor(options: SocketCDPTransportOptions) {\n\t\tthis.#emitter = new Emitter({\n\t\t\t...(options.on !== undefined ? { on: options.on } : {}),\n\t\t\t...(options.error !== undefined ? { error: options.error } : {}),\n\t\t})\n\t\tthis.#url = options.url\n\t\tthis.#timeout = options.timeout ?? BROWSER_DEFAULT_TIMEOUT_MS\n\t}\n\n\tget emitter(): EmitterInterface<CDPTransportEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tasync start(): Promise<void> {\n\t\tconst closing = this.#closing.pending\n\t\tif (closing !== undefined) await closing\n\t\tif (this.#socket?.readyState === WebSocket.OPEN) return\n\t\tconst active = this.#starting.pending\n\t\tif (active !== undefined) {\n\t\t\tawait active\n\t\t\treturn\n\t\t}\n\t\tawait this.#starting.execute(this.#start.bind(this))\n\t}\n\n\tasync send(data: string): Promise<void> {\n\t\tconst socket = this.#socket\n\t\tif (socket === undefined || socket.readyState !== WebSocket.OPEN) {\n\t\t\tthrow new BrowserConnectionError('Socket CDP transport is not open', { url: this.#url })\n\t\t}\n\t\tsocket.send(data)\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this.#closing.execute(this.#close.bind(this))\n\t}\n\n\tasync #start(): Promise<void> {\n\t\tconst parsed = attempt(() => new URL(this.#url))\n\t\tif (!parsed.success) {\n\t\t\tthrow new BrowserConnectionError(`Socket CDP URL is invalid: ${this.#url}`, {\n\t\t\t\turl: this.#url,\n\t\t\t\terror: parsed.error,\n\t\t\t})\n\t\t}\n\t\tif (parsed.value.protocol !== 'ws:' && parsed.value.protocol !== 'wss:') {\n\t\t\tthrow new BrowserConnectionError(\n\t\t\t\t`Socket CDP connection requires a ws: or wss: URL: ${this.#url}`,\n\t\t\t\t{ url: this.#url },\n\t\t\t)\n\t\t}\n\t\tconst created = attempt(() => new WebSocket(this.#url))\n\t\tif (!created.success) {\n\t\t\tthrow new BrowserConnectionError(`Socket CDP connection to ${this.#url} could not open`, {\n\t\t\t\turl: this.#url,\n\t\t\t\terror: created.error,\n\t\t\t})\n\t\t}\n\t\tconst socket = created.value\n\t\tthis.#socket = socket\n\t\tconst opened = Promise.withResolvers<void>()\n\t\tthis.#opening = opened\n\t\tconst release = new AbortController()\n\t\tconst options = { signal: release.signal }\n\t\tsocket.addEventListener('open', () => opened.resolve(), options)\n\t\tsocket.addEventListener('error', () => opened.reject(this.#refuse('failed')), options)\n\t\tsocket.addEventListener(\n\t\t\t'close',\n\t\t\t() => opened.reject(this.#refuse('closed before it opened')),\n\t\t\toptions,\n\t\t)\n\t\tconst timer = setTimeout(() => {\n\t\t\topened.reject(this.#refuse(`timed out after ${this.#timeout}ms`))\n\t\t}, this.#timeout)\n\t\ttry {\n\t\t\tawait opened.promise\n\t\t} catch (error) {\n\t\t\tif (this.#socket === socket) this.#socket = undefined\n\t\t\tsocket.close()\n\t\t\tthrow error\n\t\t} finally {\n\t\t\tif (this.#opening === opened) this.#opening = undefined\n\t\t\tclearTimeout(timer)\n\t\t\trelease.abort()\n\t\t}\n\t\tthis.#bind(socket)\n\t}\n\n\tasync #close(): Promise<void> {\n\t\tthis.#opening?.reject(this.#refuse('was closed before it finished connecting'))\n\t\tconst socket = this.#socket\n\t\tthis.#socket = undefined\n\t\tif (socket === undefined || socket.readyState === WebSocket.CLOSED) {\n\t\t\tawait this.#starting.pending?.catch(() => undefined)\n\t\t\treturn\n\t\t}\n\t\tconst closed = Promise.withResolvers<void>()\n\t\tsocket.addEventListener('close', () => closed.resolve(), { once: true })\n\t\tsocket.close()\n\t\tawait this.#starting.pending?.catch(() => undefined)\n\t\tawait closed.promise\n\t}\n\n\t#bind(socket: WebSocket): void {\n\t\tsocket.binaryType = 'arraybuffer'\n\t\tsocket.addEventListener('message', (event) => {\n\t\t\tconst data: unknown = event.data\n\t\t\tif (isString(data)) this.#emitter.emit('message', data)\n\t\t\telse if (data instanceof ArrayBuffer)\n\t\t\t\tthis.#emitter.emit('message', new TextDecoder().decode(data))\n\t\t})\n\t\tsocket.addEventListener('close', () => {\n\t\t\tif (this.#socket === socket) this.#socket = undefined\n\t\t\tthis.#emitter.emit('close')\n\t\t})\n\t\tsocket.addEventListener('error', () => {\n\t\t\tthis.#emitter.emit('error', this.#refuse('failed'))\n\t\t})\n\t}\n\n\t#refuse(reason: string): BrowserConnectionError {\n\t\treturn new BrowserConnectionError(`Socket CDP connection to ${this.#url} ${reason}`, {\n\t\t\turl: this.#url,\n\t\t})\n\t}\n}\n","import type { BrowserToolsetInterface, CDPTransportInterface } from '@src/core'\nimport type {\n\tBrowserDOMViewOptions,\n\tBrowserDocumentToolsetOptions,\n\tBrowserDOMViewInterface,\n\tSocketCDPTransportOptions,\n} from './types.js'\nimport { BrowserToolset } from '@src/core'\nimport { BrowserDOMView } from './BrowserDOMView.js'\nimport { SocketCDPTransport } from './transports/SocketCDPTransport.js'\n\n/**\n * Creates a view that reads and drives a DOM document without trusted input.\n *\n * @param options - The driven document, and `own` to admit the realm's own document\n * @returns A {@link BrowserDOMViewInterface} over the document's window\n * @throws Thrown when `document` is not a document attached to a window, with the code\n * `BROWSER_DOCUMENT`, and when it is `globalThis.document` without `own: true`, with the code\n * `BROWSER_DOCUMENT_OWN`.\n *\n * @example\n * ```ts\n * const frame = document.createElement('iframe')\n * document.body.append(frame)\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * await view.elements.outline() // { text: 'page \"\" about:blank\\n(0 of 0 elements)', … }\n * ```\n */\nexport function createBrowserDOMView(options: BrowserDOMViewOptions): BrowserDOMViewInterface {\n\treturn new BrowserDOMView(options)\n}\n\n/**\n * Creates a `BrowserToolsetInterface` that publishes the five view tools over a DOM document and\n * adopts a source's page tools beside them.\n *\n * @remarks\n * The toolset runs over a view {@link createBrowserDOMView} creates for `document`, so it\n * advertises `look`, `read`, `click`, `type`, and `wait`, and a click or type receipt ends with\n * ` (untrusted event)`. `source` supplies page tools, which the toolset adopts during `start()`\n * and again on every `change`; `toolset.native` never includes them, so publishing it to a\n * registry leaves that registry's own tools alone. The view belongs to the toolset: `destroy()`\n * removes the toolset's tools, then destroys the view, which releases its listeners and fails\n * its pending waits, and a construction that throws destroys the view before it rethrows.\n * `journeys` adds `record`, `save`, `journeys`, `edit`, and `replay` at construction; a replay\n * runs the steps the document placement executes.\n *\n * @param options - The driven document, `own`, the page-tool source, the manager, the bound, the\n * journey stores, and the emitter hooks\n * @returns A {@link BrowserToolsetInterface} whose `view` drives the document\n * @throws Thrown when `document` is not a document attached to a window, with the code\n * `BROWSER_DOCUMENT`, when it is `globalThis.document` without `own: true`, with the code\n * `BROWSER_DOCUMENT_OWN`, and when `limit` is not a positive integer.\n *\n * @example\n * ```ts\n * const toolset = createDocumentToolset({ document: frame.contentDocument, source: bridge })\n * await toolset.start()\n * await toolset.tools.execute({ id: '1', name: 'look', arguments: { what: 'form' } })\n * ```\n */\nexport function createDocumentToolset(\n\toptions: BrowserDocumentToolsetOptions,\n): BrowserToolsetInterface {\n\tconst view = createBrowserDOMView({\n\t\tdocument: options.document,\n\t\t...(options.own === undefined ? {} : { own: options.own }),\n\t})\n\ttry {\n\t\treturn new BrowserToolset(view, {\n\t\t\t...(options.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options.error === undefined ? {} : { error: options.error }),\n\t\t\t...(options.tools === undefined ? {} : { tools: options.tools }),\n\t\t\t...(options.source === undefined ? {} : { source: options.source }),\n\t\t\t...(options.limit === undefined ? {} : { limit: options.limit }),\n\t\t\t...(options.journeys === undefined ? {} : { journeys: options.journeys }),\n\t\t\trelease: view.destroy.bind(view),\n\t\t})\n\t} catch (error) {\n\t\tview.destroy()\n\t\tthrow error\n\t}\n}\n\n/**\n * Creates a CDP transport over the browser's native `WebSocket`.\n *\n * @param options - The CDP WebSocket debugger URL, the opening deadline, and emitter hooks\n * @returns A {@link CDPTransportInterface} a `CDPClient` sends and receives frames over\n *\n * @example\n * ```ts\n * const client = createCDPClient({\n * \ttransport: createSocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' }),\n * })\n * await client.connect()\n * ```\n */\nexport function createSocketCDPTransport(\n\toptions: SocketCDPTransportOptions,\n): CDPTransportInterface {\n\treturn new SocketCDPTransport(options)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/browser/constants.ts","../../../src/browser/helpers.ts","../../../src/browser/elements/BrowserDOMElement.ts","../../../src/browser/BrowserDOMWait.ts","../../../src/browser/elements/BrowserDOMElementManager.ts","../../../src/browser/BrowserDOMView.ts","../../../src/browser/transports/SocketCDPTransport.ts","../../../src/browser/factories.ts"],"sourcesContent":["// === Browser document\n\n/**\n * Sets the default `wait` deadline for DOM waits in a browser document toolset, `5_000`\n * milliseconds.\n */\nexport const BROWSER_DOCUMENT_TIMEOUT_MS = 5_000\n\n/**\n * Maps an HTML element to the ARIA role the HTML Accessibility API Mappings specification gives\n * it when it carries no `role` attribute.\n *\n * @remarks\n * A key is a lowercase element name, or `input:` followed by the input's `type` state. An element\n * whose mapping depends on more than its name — `a` and `area` without `href`, `select` with\n * `multiple` or a `size` above 1, an `img` with an empty `alt`, a scoped `header` or `footer`, a\n * `section` or `form` without an accessible name, and a text input with a `list` — is resolved\n * by `computeBrowserRole` before this table is read. An element or input state the mapping gives\n * no role has no entry.\n */\nexport const BROWSER_IMPLICIT_ROLES: ReadonlyMap<string, string> = Object.freeze(\n\tnew Map([\n\t\t['a', 'link'],\n\t\t['area', 'link'],\n\t\t['article', 'article'],\n\t\t['aside', 'complementary'],\n\t\t['blockquote', 'blockquote'],\n\t\t['button', 'button'],\n\t\t['caption', 'caption'],\n\t\t['code', 'code'],\n\t\t['datalist', 'listbox'],\n\t\t['dd', 'definition'],\n\t\t['del', 'deletion'],\n\t\t['details', 'group'],\n\t\t['dfn', 'term'],\n\t\t['dialog', 'dialog'],\n\t\t['dt', 'term'],\n\t\t['em', 'emphasis'],\n\t\t['fieldset', 'group'],\n\t\t['figure', 'figure'],\n\t\t['footer', 'contentinfo'],\n\t\t['form', 'form'],\n\t\t['h1', 'heading'],\n\t\t['h2', 'heading'],\n\t\t['h3', 'heading'],\n\t\t['h4', 'heading'],\n\t\t['h5', 'heading'],\n\t\t['h6', 'heading'],\n\t\t['header', 'banner'],\n\t\t['hr', 'separator'],\n\t\t['html', 'document'],\n\t\t['img', 'img'],\n\t\t['ins', 'insertion'],\n\t\t['li', 'listitem'],\n\t\t['main', 'main'],\n\t\t['math', 'math'],\n\t\t['menu', 'list'],\n\t\t['meter', 'meter'],\n\t\t['nav', 'navigation'],\n\t\t['ol', 'list'],\n\t\t['optgroup', 'group'],\n\t\t['option', 'option'],\n\t\t['output', 'status'],\n\t\t['p', 'paragraph'],\n\t\t['progress', 'progressbar'],\n\t\t['search', 'search'],\n\t\t['section', 'region'],\n\t\t['select', 'combobox'],\n\t\t['strong', 'strong'],\n\t\t['sub', 'subscript'],\n\t\t['sup', 'superscript'],\n\t\t['table', 'table'],\n\t\t['tbody', 'rowgroup'],\n\t\t['td', 'cell'],\n\t\t['textarea', 'textbox'],\n\t\t['tfoot', 'rowgroup'],\n\t\t['th', 'columnheader'],\n\t\t['thead', 'rowgroup'],\n\t\t['time', 'time'],\n\t\t['tr', 'row'],\n\t\t['ul', 'list'],\n\t\t['input:button', 'button'],\n\t\t['input:checkbox', 'checkbox'],\n\t\t['input:email', 'textbox'],\n\t\t['input:image', 'button'],\n\t\t['input:number', 'spinbutton'],\n\t\t['input:password', 'textbox'],\n\t\t['input:radio', 'radio'],\n\t\t['input:range', 'slider'],\n\t\t['input:reset', 'button'],\n\t\t['input:search', 'searchbox'],\n\t\t['input:submit', 'button'],\n\t\t['input:tel', 'textbox'],\n\t\t['input:text', 'textbox'],\n\t\t['input:url', 'textbox'],\n\t]),\n)\n\n/**\n * Names the ARIA roles whose accessible name the accessible-name computation takes from the\n * element's content when no attribute or label names it.\n */\nexport const BROWSER_CONTENT_NAMED_ROLES: ReadonlySet<string> = Object.freeze(\n\tnew Set([\n\t\t'button',\n\t\t'cell',\n\t\t'checkbox',\n\t\t'columnheader',\n\t\t'gridcell',\n\t\t'heading',\n\t\t'link',\n\t\t'menuitem',\n\t\t'menuitemcheckbox',\n\t\t'menuitemradio',\n\t\t'option',\n\t\t'radio',\n\t\t'row',\n\t\t'rowheader',\n\t\t'switch',\n\t\t'tab',\n\t\t'tooltip',\n\t\t'treeitem',\n\t]),\n)\n\n/**\n * Names the link and form targets that navigate the current browsing context or one of its\n * ancestors. `_blank` opens another browsing context, and any other name targets the browsing\n * context carrying that name, which `matchesBrowserPopup` resolves.\n */\nexport const BROWSER_CONTEXT_TARGETS: ReadonlySet<string> = Object.freeze(\n\tnew Set(['', '_self', '_parent', '_top']),\n)\n\n/**\n * Names the roles whose ARIA expansion state the DOM outline reads.\n *\n * @remarks\n * The role set follows the accessibility-tree reading from Chromium 141.0.7390.37.\n */\nexport const BROWSER_EXPANDED_ROLES: ReadonlySet<string> = Object.freeze(\n\tnew Set([\n\t\t'button',\n\t\t'link',\n\t\t'checkbox',\n\t\t'switch',\n\t\t'menuitem',\n\t\t'menuitemcheckbox',\n\t\t'menuitemradio',\n\t\t'tab',\n\t\t'treeitem',\n\t\t'combobox',\n\t]),\n)\n\n/**\n * Names the roles whose selection state the DOM outline reads.\n *\n * @remarks\n * The role set follows the accessibility-tree reading from Chromium 141.0.7390.37.\n */\nexport const BROWSER_SELECTED_ROLES: ReadonlySet<string> = Object.freeze(\n\tnew Set(['option', 'tab', 'treeitem']),\n)\n\n/** Names the `input` type states whose value an untrusted `fill` sets as typed text. */\nexport const BROWSER_TYPED_INPUTS: ReadonlySet<string> = Object.freeze(\n\tnew Set([\n\t\t'date',\n\t\t'datetime-local',\n\t\t'email',\n\t\t'month',\n\t\t'number',\n\t\t'password',\n\t\t'search',\n\t\t'tel',\n\t\t'text',\n\t\t'time',\n\t\t'url',\n\t\t'week',\n\t]),\n)\n\n/**\n * Selects the HTML interactive content a click inside a `label` can land on without activating\n * the label, as the HTML interactive-content category lists it: `a` with `href`, `audio` and\n * `video` with `controls`, `button`, `details`, `embed`, `iframe`, `img` with `usemap` or\n * `controls`, `input` other than `hidden`, `label`, `select`, and `textarea`.\n */\nexport const BROWSER_INTERACTIVE_CONTENT =\n\t'a[href], audio[controls], button, details, embed, iframe, img[usemap], img[controls], input:not([type=\"hidden\" i]), label, select, textarea, video[controls]'\n","import type { BrowserReadingInput } from '@src/core'\nimport type { BrowserNameContext } from './types.js'\nimport { attempt, isObject, isString } from '@orkestrel/contract'\nimport { BROWSER_RESULT_LIMIT, BrowserResultLimitError, normalizeBrowserName } from '@src/core'\nimport {\n\tBROWSER_CONTENT_NAMED_ROLES,\n\tBROWSER_CONTEXT_TARGETS,\n\tBROWSER_IMPLICIT_ROLES,\n\tBROWSER_INTERACTIVE_CONTENT,\n\tBROWSER_TYPED_INPUTS,\n\tBROWSER_EXPANDED_ROLES,\n\tBROWSER_SELECTED_ROLES,\n} from './constants.js'\n\n// === Browser document\n\n/**\n * Narrows a value to a `Document` attached to a window.\n *\n * @param value - The value to test\n * @returns `true` for an object that is a `Document` with a `defaultView`, otherwise `false`\n */\nexport function isBrowserDocument(value: unknown): value is Document {\n\treturn (\n\t\tisObject(value) &&\n\t\tReflect.get(value, 'nodeType') === 9 &&\n\t\tisObject(Reflect.get(value, 'defaultView'))\n\t)\n}\n\n/**\n * Reads the URL, title, and rendered markup a DOM reading is built from, refusing a capture\n * over the result limit before any parse.\n *\n * @remarks\n * The measure is the length of `JSON.stringify({ url, title, html })`, the form the CDP capture\n * guard compares with `BROWSER_RESULT_LIMIT`, so a character JSON escapes counts as its escape\n * sequence. A reading a caller builds with `createBrowserReading` passes through no limit.\n * {@link BrowserReadingInput} defines the inert capture, lowering, redaction, and limits.\n *\n * @param node - The root whose rendered markup is captured; its owner document supplies `URL`\n * and `title`\n * @returns The capture's `url`, `title`, and `html`\n * @throws Thrown as a `BrowserResultLimitError` when the serialized capture is longer than\n * `BROWSER_RESULT_LIMIT` characters, with `length` and `limit` in its context.\n */\nexport function readBrowserCapture(node: Element): BrowserReadingInput {\n\tconst document = node.ownerDocument\n\tconst capture = { url: document.URL, title: document.title, html: '' }\n\tconst view = document.defaultView\n\tconst rendered = view !== null && node.isConnected\n\tconst inert = document.implementation.createHTMLDocument('')\n\tlet root: Element | undefined = inert.importNode(node, true)\n\tconst pending: Array<{\n\t\tlive: Element\n\t\ttwin: Element\n\t\tstyle?: CSSStyleDeclaration | undefined\n\t\tvisited: boolean\n\t}> = [{ live: node, twin: root, visited: false }]\n\tif (rendered) {\n\t\tlet child = node\n\t\tfor (\n\t\t\tlet parent: Element | null = node;\n\t\t\tparent?.ownerDocument === document;\n\t\t\tparent = readBrowserParent(parent)\n\t\t) {\n\t\t\tconst style = view.getComputedStyle(parent)\n\t\t\tconst outside =\n\t\t\t\tparent !== node &&\n\t\t\t\t(style.contentVisibility === 'hidden' ||\n\t\t\t\t\t['canvas', 'video', 'audio'].includes(parent.localName) ||\n\t\t\t\t\tparent instanceof view.HTMLInputElement ||\n\t\t\t\t\tparent instanceof view.HTMLTextAreaElement ||\n\t\t\t\t\tparent instanceof view.HTMLOptionElement ||\n\t\t\t\t\t(parent.namespaceURI === 'http://www.w3.org/2000/svg' &&\n\t\t\t\t\t\tparent.localName === 'switch' &&\n\t\t\t\t\t\tchild !==\n\t\t\t\t\t\t\t(Array.from(parent.children).find(\n\t\t\t\t\t\t\t\t(candidate) => candidate.getClientRects().length > 0,\n\t\t\t\t\t\t\t) ?? parent.firstElementChild)) ||\n\t\t\t\t\t((parent instanceof view.HTMLSelectElement ||\n\t\t\t\t\t\tparent instanceof view.HTMLOptGroupElement) &&\n\t\t\t\t\t\t!(\n\t\t\t\t\t\t\tnode instanceof view.HTMLOptionElement || node instanceof view.HTMLOptGroupElement\n\t\t\t\t\t\t)) ||\n\t\t\t\t\t[\n\t\t\t\t\t\t'script',\n\t\t\t\t\t\t'style',\n\t\t\t\t\t\t'template',\n\t\t\t\t\t\t'frame',\n\t\t\t\t\t\t'frameset',\n\t\t\t\t\t\t'iframe',\n\t\t\t\t\t\t'object',\n\t\t\t\t\t\t'embed',\n\t\t\t\t\t\t'applet',\n\t\t\t\t\t\t'noscript',\n\t\t\t\t\t\t'meta',\n\t\t\t\t\t\t'link',\n\t\t\t\t\t\t'base',\n\t\t\t\t\t\t'math',\n\t\t\t\t\t].includes(parent.localName) ||\n\t\t\t\t\t(parent.localName === 'details' &&\n\t\t\t\t\t\t!parent.hasAttribute('open') &&\n\t\t\t\t\t\tchild !== parent.querySelector(':scope > summary')))\n\t\t\tconst unassigned =\n\t\t\t\tchild.parentElement?.shadowRoot !== null &&\n\t\t\t\tchild.parentElement?.shadowRoot !== undefined &&\n\t\t\t\tchild.assignedSlot === null\n\t\t\tif (style.display === 'none' || outside || unassigned) {\n\t\t\t\troot = undefined\n\t\t\t\tpending.length = 0\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tchild = parent\n\t\t}\n\t}\n\twhile (pending.length > 0) {\n\t\tconst entry = pending.pop()\n\t\tif (entry === undefined) continue\n\t\tconst { live, twin, visited } = entry\n\t\tconst tag = live.localName\n\t\tconst input = tag === 'input' ? (live.getAttribute('type')?.toLowerCase() ?? 'text') : ''\n\t\tif (\n\t\t\t[\n\t\t\t\t'script',\n\t\t\t\t'style',\n\t\t\t\t'template',\n\t\t\t\t'frame',\n\t\t\t\t'frameset',\n\t\t\t\t'iframe',\n\t\t\t\t'object',\n\t\t\t\t'embed',\n\t\t\t\t'applet',\n\t\t\t\t'noscript',\n\t\t\t\t'meta',\n\t\t\t\t'link',\n\t\t\t\t'base',\n\t\t\t\t'math',\n\t\t\t].includes(tag) ||\n\t\t\t(tag === 'input' && ['password', 'hidden'].includes(input))\n\t\t) {\n\t\t\ttwin.remove()\n\t\t\tif (twin === root) root = undefined\n\t\t\tcontinue\n\t\t}\n\t\tconst style = entry.style ?? (rendered ? view.getComputedStyle(live) : undefined)\n\t\tconst invisible = style?.visibility === 'hidden' || style?.visibility === 'collapse'\n\t\tif (style?.display === 'none' || (invisible && !live.hasChildNodes())) {\n\t\t\ttwin.remove()\n\t\t\tif (twin === root) root = undefined\n\t\t\tcontinue\n\t\t}\n\t\tif (!visited) {\n\t\t\tpending.push({ live, twin, style, visited: true })\n\t\t\tif (rendered) {\n\t\t\t\ttwin.removeAttribute('hidden')\n\t\t\t\ttwin.removeAttribute('aria-hidden')\n\t\t\t}\n\t\t\tif (\n\t\t\t\trendered &&\n\t\t\t\t(live instanceof view.HTMLAnchorElement || live instanceof view.HTMLAreaElement) &&\n\t\t\t\tlive.hasAttribute('href')\n\t\t\t)\n\t\t\t\ttwin.setAttribute('href', live.href)\n\t\t\tif (style?.contentVisibility === 'hidden' || ['canvas', 'video', 'audio'].includes(tag)) {\n\t\t\t\ttwin.replaceChildren()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (\n\t\t\t\trendered &&\n\t\t\t\t(live instanceof view.HTMLInputElement ||\n\t\t\t\t\tlive instanceof view.HTMLTextAreaElement ||\n\t\t\t\t\tlive instanceof view.HTMLSelectElement ||\n\t\t\t\t\tlive instanceof view.HTMLOptionElement ||\n\t\t\t\t\tlive instanceof view.HTMLOptGroupElement)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tconst summary =\n\t\t\t\ttag === 'details' && !live.hasAttribute('open')\n\t\t\t\t\t? live.querySelector(':scope > summary')\n\t\t\t\t\t: undefined\n\n\t\t\t// Native layout selects the switch branch after its conditional processing tests.\n\t\t\tconst conditional = tag === 'switch' && live.namespaceURI === 'http://www.w3.org/2000/svg'\n\t\t\tconst branch =\n\t\t\t\trendered && conditional\n\t\t\t\t\t? (Array.from(live.children).find((candidate) => candidate.getClientRects().length > 0) ??\n\t\t\t\t\t\tlive.firstElementChild)\n\t\t\t\t\t: undefined\n\t\t\t// Save sibling pointers before pruning invalidates the copied child collections.\n\t\t\tlet element = live.lastElementChild\n\t\t\tlet counterpart = twin.lastElementChild\n\t\t\tlet child = live.lastChild\n\t\t\tlet mirror = twin.lastChild\n\t\t\twhile (child !== null && mirror !== null) {\n\t\t\t\tconst previous = child.previousSibling\n\t\t\t\tconst previousMirror = mirror.previousSibling\n\t\t\t\tconst previousElement: Element | null = element?.previousElementSibling ?? null\n\t\t\t\tconst previousCounterpart: Element | null = counterpart?.previousElementSibling ?? null\n\t\t\t\tlet omitted =\n\t\t\t\t\trendered &&\n\t\t\t\t\t((summary !== undefined && child !== summary) || (conditional && child !== branch))\n\t\t\t\tif (rendered && live.shadowRoot !== null) {\n\t\t\t\t\tconst slot =\n\t\t\t\t\t\tchild instanceof view.Element || child instanceof view.Text ? child.assignedSlot : null\n\t\t\t\t\tif (slot === null) omitted = true\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\tlet parent: Element | null = slot;\n\t\t\t\t\t\t\tparent !== null && parent !== live;\n\t\t\t\t\t\t\tparent = readBrowserParent(parent)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tif (view.getComputedStyle(parent).display === 'none') omitted = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (omitted || (child.nodeType === 3 && invisible)) mirror.parentNode?.removeChild(mirror)\n\t\t\t\telse if (child.nodeType === 1) {\n\t\t\t\t\t// Element sibling pointers retain their type across windowless document realms.\n\t\t\t\t\tif (element !== null && counterpart !== null)\n\t\t\t\t\t\tpending.push({ live: element, twin: counterpart, visited: false })\n\t\t\t\t}\n\t\t\t\tif (child.nodeType === 1) {\n\t\t\t\t\telement = previousElement\n\t\t\t\t\tcounterpart = previousCounterpart\n\t\t\t\t}\n\t\t\t\tchild = previous\n\t\t\t\tmirror = previousMirror\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif (!rendered || style?.contentVisibility === 'hidden') continue\n\t\tif (\n\t\t\t['div', 'summary', 'details'].includes(tag) &&\n\t\t\t!style?.display.startsWith('inline') &&\n\t\t\tstyle?.display !== 'contents' &&\n\t\t\ttwin.hasChildNodes()\n\t\t) {\n\t\t\ttwin.prepend(inert.createElement('br'))\n\t\t\ttwin.append(inert.createElement('br'))\n\t\t}\n\t\tlet fragments: Node[] | undefined\n\t\tlet lines: string[] | undefined\n\t\tlet container = false\n\t\tif (live instanceof view.HTMLInputElement) {\n\t\t\tlines = []\n\t\t\tif (['text', 'email', 'search', 'tel', 'url', 'number'].includes(live.type)) {\n\t\t\t\tif (live.type !== 'number' || !live.validity.badInput) {\n\t\t\t\t\tconst placeholder = view.getComputedStyle(live, '::placeholder')\n\t\t\t\t\tlines = [\n\t\t\t\t\t\tlive.value ||\n\t\t\t\t\t\t\t(live.matches(':placeholder-shown') &&\n\t\t\t\t\t\t\tplaceholder.visibility === 'visible' &&\n\t\t\t\t\t\t\tplaceholder.opacity !== '0' &&\n\t\t\t\t\t\t\tplaceholder.color !== 'rgba(0, 0, 0, 0)'\n\t\t\t\t\t\t\t\t? live.placeholder\n\t\t\t\t\t\t\t\t: ''),\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t} else if (['submit', 'reset', 'button'].includes(live.type)) lines = [live.value]\n\t\t\telse if (live.type === 'file' && live.files?.length === 1)\n\t\t\t\tlines = Array.from(live.files ?? [], (file) => file.name)\n\t\t\telse if (live.type === 'image' && live.getAttribute('aria-hidden') !== 'true')\n\t\t\t\tlines = [live.getAttribute('aria-label')?.trim() || live.alt]\n\t\t} else if (live instanceof view.HTMLTextAreaElement) {\n\t\t\tconst placeholder = view.getComputedStyle(live, '::placeholder')\n\t\t\tconst value =\n\t\t\t\tlive.value ||\n\t\t\t\t(live.matches(':placeholder-shown') &&\n\t\t\t\tplaceholder.visibility === 'visible' &&\n\t\t\t\tplaceholder.opacity !== '0' &&\n\t\t\t\tplaceholder.color !== 'rgba(0, 0, 0, 0)'\n\t\t\t\t\t? live.placeholder\n\t\t\t\t\t: '')\n\t\t\tlines = value.split(/\\r?\\n/)\n\t\t} else if (\n\t\t\tlive instanceof view.HTMLSelectElement ||\n\t\t\tlive instanceof view.HTMLOptionElement ||\n\t\t\tlive instanceof view.HTMLOptGroupElement\n\t\t) {\n\t\t\tlines = []\n\t\t\tconst select = live instanceof view.HTMLSelectElement ? live : live.closest('select')\n\t\t\tif (select !== null) {\n\t\t\t\tif (!select.multiple && select.size <= 1) {\n\t\t\t\t\tconst option = select.selectedOptions[0]\n\t\t\t\t\tif (option !== undefined && (live === select || live === option || live.contains(option)))\n\t\t\t\t\t\tlines.push(option.label)\n\t\t\t\t} else {\n\t\t\t\t\tconst box = select.getBoundingClientRect()\n\t\t\t\t\tconst top = box.top + select.clientTop\n\t\t\t\t\tconst bottom = top + select.clientHeight\n\t\t\t\t\tconst rows =\n\t\t\t\t\t\tlive === select\n\t\t\t\t\t\t\t? select.querySelectorAll('option,optgroup')\n\t\t\t\t\t\t\t: [live, ...live.querySelectorAll('option')]\n\t\t\t\t\tfor (const row of rows) {\n\t\t\t\t\t\tconst rowStyle = view.getComputedStyle(row)\n\t\t\t\t\t\tconst groupStyle =\n\t\t\t\t\t\t\trow.parentElement instanceof view.HTMLOptGroupElement\n\t\t\t\t\t\t\t\t? view.getComputedStyle(row.parentElement)\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\trowStyle.display === 'none' ||\n\t\t\t\t\t\t\trowStyle.visibility !== 'visible' ||\n\t\t\t\t\t\t\tgroupStyle?.display === 'none'\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\tconst rect = row.getBoundingClientRect()\n\t\t\t\t\t\t// The group box includes its options; its caption ends where the first row starts.\n\t\t\t\t\t\tconst end =\n\t\t\t\t\t\t\trow instanceof view.HTMLOptGroupElement\n\t\t\t\t\t\t\t\t? (Array.from(row.querySelectorAll('option'))\n\t\t\t\t\t\t\t\t\t\t.find((option) => option.getClientRects().length > 0)\n\t\t\t\t\t\t\t\t\t\t?.getBoundingClientRect().top ?? rect.bottom)\n\t\t\t\t\t\t\t\t: rect.bottom\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tend > top &&\n\t\t\t\t\t\t\trect.top < bottom &&\n\t\t\t\t\t\t\trect.right > box.left + select.clientLeft &&\n\t\t\t\t\t\t\trect.left < box.left + select.clientLeft + select.clientWidth &&\n\t\t\t\t\t\t\t(row instanceof view.HTMLOptionElement || row instanceof view.HTMLOptGroupElement)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tlines.push(row.label)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (tag === 'svg') {\n\t\t\tif (twin.parentElement?.closest('svg, foreignObject')?.localName === 'svg') continue\n\t\t\tlines = []\n\t\t\tfragments = []\n\t\t\tfor (const content of twin.querySelectorAll('text, foreignObject')) {\n\t\t\t\tif (content.parentElement?.closest('svg, foreignObject')?.localName === 'foreignObject')\n\t\t\t\t\tcontinue\n\t\t\t\tif (\n\t\t\t\t\tcontent.localName === 'text' &&\n\t\t\t\t\tcontent.parentElement?.closest('text')?.closest('svg') === content.closest('svg')\n\t\t\t\t)\n\t\t\t\t\tcontinue\n\t\t\t\tif (content.localName === 'foreignObject') fragments.push(...content.childNodes)\n\t\t\t\telse if (content.textContent) fragments.push(inert.createTextNode(content.textContent))\n\t\t\t}\n\t\t\tif (fragments.length === 0) fragments = undefined\n\t\t\tif (!invisible && fragments === undefined && live.getAttribute('aria-hidden') !== 'true')\n\t\t\t\tlines.push(\n\t\t\t\t\tlive.getAttribute('aria-label')?.trim() ||\n\t\t\t\t\t\tlive.querySelector(':scope > title')?.textContent ||\n\t\t\t\t\t\t'',\n\t\t\t\t)\n\t\t} else if (['form', 'dialog', 'button'].includes(tag)) {\n\t\t\tcontainer = true\n\t\t\tif (live instanceof view.HTMLButtonElement && !invisible && live.innerText.trim() === '') {\n\t\t\t\tconst name = live.getAttribute('aria-label')?.trim()\n\t\t\t\tif (name) {\n\t\t\t\t\tlines = [name]\n\t\t\t\t\tcontainer = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (lines === undefined && !container) continue\n\t\tif (invisible && !container && tag !== 'svg') lines = []\n\t\tconst block = !style?.display.startsWith('inline') && style?.display !== 'contents'\n\t\tconst carrier = inert.createElement(block ? 'div' : 'span')\n\t\tif (container) carrier.append(...twin.childNodes)\n\t\telse if (fragments !== undefined) {\n\t\t\tfor (const fragment of fragments) {\n\t\t\t\tcarrier.append(fragment, inert.createElement('br'))\n\t\t\t}\n\t\t} else\n\t\t\tfor (const [index, line] of (lines ?? []).entries()) {\n\t\t\t\tif (index > 0) carrier.append(inert.createElement('br'))\n\t\t\t\tcarrier.append(inert.createTextNode(line))\n\t\t\t}\n\t\tif (carrier.hasChildNodes()) {\n\t\t\tcarrier.prepend(inert.createElement('br'))\n\t\t\tcarrier.append(inert.createElement('br'))\n\t\t}\n\t\ttwin.replaceWith(carrier)\n\t\tif (twin === root) root = carrier\n\t}\n\t// Guard a copy that has fallen out of step with the live tree.\n\tfor (const input of root?.querySelectorAll('input[type=\"password\" i],input[type=\"hidden\" i]') ??\n\t\t[])\n\t\tinput.remove()\n\tcapture.html = root?.outerHTML ?? ''\n\tconst length = JSON.stringify(capture).length\n\tif (length > BROWSER_RESULT_LIMIT) {\n\t\tthrow new BrowserResultLimitError('Document capture exceeds BROWSER_RESULT_LIMIT', {\n\t\t\tlength,\n\t\t\tlimit: BROWSER_RESULT_LIMIT,\n\t\t})\n\t}\n\treturn capture\n}\n\n/**\n * Computes the ARIA role of an element from its `role` attribute or its implicit mapping.\n *\n * @remarks\n * The explicit role is the first token of the `role` attribute, with `presentation` folded into\n * its synonym `none`. Without one, the role follows the HTML Accessibility API Mappings\n * specification through `BROWSER_IMPLICIT_ROLES`, after the element-specific conditions that\n * table cannot express: a link needs `href`, a `select` with `multiple` or a `size` above 1 is a\n * `listbox`, an `img` with an empty `alt` is `none`, a `header` or `footer` inside sectioning\n * content has no landmark role, a `section` or `form` needs an accessible name, a text input with\n * a `list` is a `combobox`, and a `th` with `scope=\"row\"` is a `rowheader`.\n *\n * @param element - The element to classify\n * @returns The role, or `undefined` when the element maps to no role\n *\n * @example\n * ```ts\n * const input = document.createElement('input')\n * input.type = 'checkbox'\n * computeBrowserRole(input) // 'checkbox'\n * ```\n */\nexport function computeBrowserRole(element: Element): string | undefined {\n\tconst explicit = (element.getAttribute('role') ?? '').trim().toLowerCase().split(/\\s+/)[0] ?? ''\n\tif (explicit !== '') return explicit === 'presentation' ? 'none' : explicit\n\tconst tag = element.localName\n\tif (tag === 'a' || tag === 'area') return element.hasAttribute('href') ? 'link' : undefined\n\tif (tag === 'input') {\n\t\tconst type = Reflect.get(element, 'type')\n\t\tconst role = BROWSER_IMPLICIT_ROLES.get(`input:${isString(type) ? type : 'text'}`)\n\t\treturn element.hasAttribute('list') && (role === 'textbox' || role === 'searchbox')\n\t\t\t? 'combobox'\n\t\t\t: role\n\t}\n\tif (tag === 'select') {\n\t\treturn element.hasAttribute('multiple') || Number(element.getAttribute('size')) > 1\n\t\t\t? 'listbox'\n\t\t\t: 'combobox'\n\t}\n\tif (tag === 'img' && element.getAttribute('alt') === '') return 'none'\n\tif (\n\t\t(tag === 'header' || tag === 'footer') &&\n\t\t(element.parentElement?.closest('article, aside, main, nav, section') ?? null) !== null\n\t)\n\t\treturn undefined\n\tif (\n\t\t(tag === 'section' || tag === 'form') &&\n\t\t!element.hasAttribute('aria-label') &&\n\t\t!element.hasAttribute('aria-labelledby') &&\n\t\t!element.hasAttribute('title')\n\t)\n\t\treturn undefined\n\tif (tag === 'th' && element.getAttribute('scope')?.toLowerCase() === 'row') return 'rowheader'\n\treturn BROWSER_IMPLICIT_ROLES.get(tag)\n}\n\n/**\n * Computes the accessible name of an element, trimmed and whitespace-collapsed.\n *\n * @remarks\n * The steps follow the accessible-name computation, first match wins: the elements\n * that `aria-labelledby` references in the element's own tree, each through\n * `computeBrowserAlternative` with hidden content admitted when the referenced element is itself\n * hidden (`matchesBrowserOmitted` or `matchesBrowserInvisible`), `aria-label`, the `label` of an\n * `option`, the value of an `input` button, the `alt` of an\n * image, the text of every associated `label`, the element's own content for a role in\n * `BROWSER_CONTENT_NAMED_ROLES`, then the `title` attribute, then the `placeholder` of a text\n * control. Every traversal carries the element as its `target`, so an embedded control\n * contributes its value unless it is the element being named. The `title` step follows content because a tooltip names an element only when nothing\n * else does.\n *\n * @param element - The element to name\n * @param role - The element's role. Default: `computeBrowserRole(element)`\n * @returns The name, or the empty string when no step names the element\n *\n * @example\n * ```ts\n * const button = document.createElement('button')\n * button.textContent = ' Save draft '\n * computeBrowserName(button) // 'Save draft'\n * ```\n */\nexport function computeBrowserName(element: Element, role = computeBrowserRole(element)): string {\n\tconst view = element.ownerDocument.defaultView\n\tconst tree = element.getRootNode()\n\tconst scope = view !== null && tree instanceof view.ShadowRoot ? tree : element.ownerDocument\n\tconst referenced = normalizeBrowserName(\n\t\t(element.getAttribute('aria-labelledby') ?? '')\n\t\t\t.split(/\\s+/)\n\t\t\t.flatMap((id) => {\n\t\t\t\tconst target = id === '' ? null : scope.getElementById(id)\n\t\t\t\treturn target === null\n\t\t\t\t\t? []\n\t\t\t\t\t: [\n\t\t\t\t\t\t\tcomputeBrowserAlternative(target, {\n\t\t\t\t\t\t\t\thidden: matchesBrowserOmitted(target) || matchesBrowserInvisible(target),\n\t\t\t\t\t\t\t\ttarget: element,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t]\n\t\t\t})\n\t\t\t.join(' '),\n\t)\n\tif (referenced !== '') return referenced\n\tconst label = normalizeBrowserName(element.getAttribute('aria-label') ?? '')\n\tif (label !== '') return label\n\tif (view !== null && element instanceof view.HTMLOptionElement) {\n\t\tconst option = normalizeBrowserName(element.label)\n\t\tif (option !== '') return option\n\t}\n\tconst tag = element.localName\n\tconst type = tag === 'input' ? Reflect.get(element, 'type') : undefined\n\tif (type === 'button' || type === 'submit' || type === 'reset') {\n\t\tconst value = normalizeBrowserName(\n\t\t\telement.getAttribute('value') ??\n\t\t\t\t(type === 'submit' ? 'Submit' : type === 'reset' ? 'Reset' : ''),\n\t\t)\n\t\tif (value !== '') return value\n\t}\n\tif (type === 'image' || tag === 'img' || tag === 'area') {\n\t\tconst alt = normalizeBrowserName(element.getAttribute('alt') ?? '')\n\t\tif (alt !== '') return alt\n\t}\n\tconst labelled = normalizeBrowserName(\n\t\tArray.from(scope.querySelectorAll('label'))\n\t\t\t.filter((candidate) => candidate.control === element)\n\t\t\t.map((candidate) => computeBrowserText(candidate, { target: element }))\n\t\t\t.join(' '),\n\t)\n\tif (labelled !== '') return labelled\n\tif (role !== undefined && BROWSER_CONTENT_NAMED_ROLES.has(role)) {\n\t\tconst content = computeBrowserText(element, { target: element })\n\t\tif (content !== '') return content\n\t}\n\tconst title = normalizeBrowserName(element.getAttribute('title') ?? '')\n\tif (title !== '') return title\n\treturn tag === 'input' || tag === 'textarea'\n\t\t? normalizeBrowserName(element.getAttribute('placeholder') ?? '')\n\t\t: ''\n}\n\n/**\n * Computes the text an element's content contributes to an accessible name, in the flat tree,\n * trimmed and whitespace-collapsed.\n *\n * @remarks\n * The text is what `readBrowserContent` reads, normalized.\n *\n * @param root - The element or shadow root whose content is read\n * @param context - The traversal context. Default: no hidden content and no target\n * @returns The trimmed, whitespace-collapsed text\n *\n * @example\n * ```ts\n * const link = document.createElement('a')\n * link.innerHTML = '<div>Cars</div><div>Search the fleet</div>'\n * document.body.append(link)\n * computeBrowserText(link) // 'Cars Search the fleet'\n * ```\n */\nexport function computeBrowserText(\n\troot: Element | ShadowRoot,\n\tcontext?: BrowserNameContext,\n): string {\n\treturn normalizeBrowserName(readBrowserContent(root, context))\n}\n\n/**\n * Reads the untrimmed text an element's content contributes to an accessible name, in the flat\n * tree.\n *\n * @remarks\n * The content is the open shadow root's children for a shadow host, the flattened assigned nodes\n * for a `slot`, and the child nodes otherwise. Each child contributes what\n * `computeBrowserAlternative` returns for it, and a child that `matchesBrowserBlock` reports is\n * set apart from its neighbours by a space. Whitespace at the edges of an inline child is kept,\n * so `<b>Go </b>home` reads `Go home`.\n *\n * @param root - The element or shadow root whose content is read\n * @param context - The traversal context. Default: no hidden content and no target\n * @returns The untrimmed text\n *\n * @example\n * ```ts\n * const label = document.createElement('span')\n * label.innerHTML = '<b>Go </b>home'\n * document.body.append(label)\n * readBrowserContent(label) // 'Go home'\n * ```\n */\nexport function readBrowserContent(\n\troot: Element | ShadowRoot,\n\tcontext?: BrowserNameContext,\n): string {\n\tconst view = root.ownerDocument?.defaultView ?? null\n\tconst shadow = view !== null && root instanceof view.Element ? root.shadowRoot : null\n\tconst children: readonly Node[] =\n\t\tshadow !== null\n\t\t\t? Array.from(shadow.childNodes)\n\t\t\t: view !== null && root instanceof view.HTMLSlotElement\n\t\t\t\t? root.assignedNodes({ flatten: true })\n\t\t\t\t: Array.from(root.childNodes)\n\tlet text = ''\n\tlet previous = false\n\tfor (const child of children) {\n\t\tconst piece = computeBrowserAlternative(child, context)\n\t\tconst block = view !== null && child instanceof view.Element && matchesBrowserBlock(child)\n\t\tif (piece !== '') text += text !== '' && (block || previous) ? ` ${piece}` : piece\n\t\tprevious = block\n\t}\n\treturn text\n}\n\n/**\n * Computes the text one node contributes to an accessible name: its own text alternative, or its\n * content.\n *\n * @remarks\n * A text node contributes its data unless its parent is invisible; a parent without a box of its\n * own, such as a `slot` or a `display: contents` element, is not invisible. An element\n * contributes nothing when it is hidden or is a `script` or `style`, and an element that\n * `matchesBrowserInvisible` reports contributes only what its content contributes, never its\n * value, `aria-label`, `alt`, or `title`. The context's `hidden` admits both. An embedded control\n * that is not the context's `target` contributes its value: a text field or a range its `value`,\n * a `select` its selected options' labels; a password field and the target itself contribute\n * nothing. Any other element contributes its `aria-label`, the `alt` of an image, or its content\n * through `readBrowserContent`, and its `title` when those are empty.\n *\n * @param node - The node whose contribution is computed\n * @param context - The traversal context. Default: no hidden content and no target\n * @returns The untrimmed contribution\n *\n * @example\n * ```ts\n * const image = document.createElement('img')\n * image.alt = 'Save'\n * computeBrowserAlternative(image) // 'Save'\n * ```\n */\nexport function computeBrowserAlternative(node: Node, context?: BrowserNameContext): string {\n\tconst view = node.ownerDocument?.defaultView ?? null\n\tconst hidden = context?.hidden === true\n\tif (view === null) return node.textContent ?? ''\n\tif (!(node instanceof view.Element)) {\n\t\tconst parent = node.parentElement\n\t\tif (node.nodeType !== view.Node.TEXT_NODE) return ''\n\t\treturn !hidden && parent !== null && matchesBrowserInvisible(parent)\n\t\t\t? ''\n\t\t\t: (node.textContent ?? '')\n\t}\n\tconst tag = node.localName\n\tif (!hidden && matchesBrowserHidden(node)) return ''\n\tif (tag === 'script' || tag === 'style') return ''\n\t// An invisible element's descendants can still render, so only its content can contribute.\n\tif (!hidden && matchesBrowserInvisible(node)) return readBrowserContent(node, context)\n\tconst embedded = node !== context?.target\n\tif (node instanceof view.HTMLTextAreaElement) return embedded ? node.value : ''\n\tif (node instanceof view.HTMLSelectElement) {\n\t\treturn embedded ? Array.from(node.selectedOptions, (option) => option.label).join(' ') : ''\n\t}\n\tif (\n\t\tnode instanceof view.HTMLInputElement &&\n\t\tnode.type !== 'password' &&\n\t\t(BROWSER_TYPED_INPUTS.has(node.type) || node.type === 'range')\n\t) {\n\t\treturn embedded ? node.value : ''\n\t}\n\tconst label = normalizeBrowserName(node.getAttribute('aria-label') ?? '')\n\tif (label !== '') return label\n\tconst content =\n\t\ttag === 'img' || tag === 'area' || (tag === 'input' && Reflect.get(node, 'type') === 'image')\n\t\t\t? (node.getAttribute('alt') ?? '')\n\t\t\t: readBrowserContent(node, context)\n\treturn content.trim() !== '' ? content : (node.getAttribute('title') ?? '')\n}\n\n/**\n * Checks whether an element and its subtree are hidden from the rendered page.\n *\n * @param element - The element to test\n * @returns True if the element carries `hidden` or `aria-hidden=\"true\"`, or its computed\n * `display` is `none`; false otherwise\n *\n * @example\n * ```ts\n * const note = document.createElement('p')\n * note.hidden = true\n * matchesBrowserHidden(note) // true\n * ```\n */\nexport function matchesBrowserHidden(element: Element): boolean {\n\treturn (\n\t\telement.hasAttribute('hidden') ||\n\t\telement.getAttribute('aria-hidden') === 'true' ||\n\t\telement.ownerDocument.defaultView?.getComputedStyle(element).display === 'none'\n\t)\n}\n\n/**\n * Checks whether an element renders nothing visible of its own.\n *\n * @remarks\n * An element whose computed `visibility` is `hidden` or `collapse` is invisible. An element with\n * `display: contents` has no box of its own but renders its descendants, so it is not invisible.\n * Any other element is invisible when `checkVisibility` with `visibilityProperty` and\n * `contentVisibilityAuto` reports it, which covers an element without a box and one skipped by\n * `content-visibility: auto`. A descendant can still be visible, so the rule omits the element's\n * own row and text and keeps its subtree. An `option` or `optgroup` inside a `select` is\n * invisible where the `select` is, because a drop-down renders its options outside the page's\n * boxes. Zero-size and off-screen elements stay visible. An\n * element in a document without a window is never invisible, because nothing renders it.\n *\n * @param element - The element to test\n * @returns True if the element renders nothing visible of its own; false otherwise\n *\n * @example\n * ```ts\n * const button = document.createElement('button')\n * button.style.visibility = 'hidden'\n * document.body.append(button)\n * matchesBrowserInvisible(button) // true\n * ```\n */\nexport function matchesBrowserInvisible(element: Element): boolean {\n\tconst style = element.ownerDocument.defaultView?.getComputedStyle(element)\n\tif (style === undefined) return false\n\tif (style.visibility === 'hidden' || style.visibility === 'collapse') return true\n\t// A drop-down select renders its options in a popup outside the page's boxes, so an option or\n\t// group is visible where its select is.\n\tconst select =\n\t\telement.localName === 'option' || element.localName === 'optgroup'\n\t\t\t? element.closest('select')\n\t\t\t: null\n\tif (select !== null) return matchesBrowserInvisible(select)\n\treturn (\n\t\tstyle.display !== 'contents' &&\n\t\t!element.checkVisibility({ visibilityProperty: true, contentVisibilityAuto: true })\n\t)\n}\n\n/**\n * Checks whether an element sits in an omitted subtree: the element or a flat-tree ancestor that\n * `readBrowserParent` reaches matches `matchesBrowserHidden`, through assigned slots, shadow\n * hosts, and the frame elements of same-origin documents.\n *\n * @param element - The element to test\n * @returns True if the element or an ancestor is hidden; false otherwise\n *\n * @example\n * ```ts\n * const section = document.createElement('section')\n * section.hidden = true\n * const button = section.appendChild(document.createElement('button'))\n * matchesBrowserOmitted(button) // true\n * ```\n */\nexport function matchesBrowserOmitted(element: Element): boolean {\n\tfor (\n\t\tlet current: Element | null = element;\n\t\tcurrent !== null;\n\t\tcurrent = readBrowserParent(current)\n\t) {\n\t\tif (matchesBrowserHidden(current)) return true\n\t}\n\treturn false\n}\n\n/**\n * Reads an element's parent in the flat tree: the slot it is assigned to in an open shadow root,\n * its parent element, the host of the open shadow root it sits at the top of, or the frame\n * element of its same-origin document.\n *\n * @param element - The element whose parent is read\n * @returns The parent, or `null` at the top of a top-level or cross-origin-framed document\n *\n * @example\n * ```ts\n * readBrowserParent(document.body) // document.documentElement\n * readBrowserParent(document.documentElement) // null in a top-level document\n * ```\n */\nexport function readBrowserParent(element: Element): Element | null {\n\tif (element.assignedSlot !== null) return element.assignedSlot\n\tif (element.parentElement !== null) return element.parentElement\n\tconst view: (Window & typeof globalThis) | null = element.ownerDocument.defaultView\n\tif (view === null) return null\n\tconst tree = element.getRootNode()\n\treturn tree instanceof view.ShadowRoot ? tree.host : view.frameElement\n}\n\n/**\n * Checks whether an element starts a block of its own, the unit that separates runs of text.\n *\n * @param element - The element to test\n * @returns True if the element is a `br`, or its computed `display` is neither inline-level,\n * `contents`, nor `none`; false otherwise\n *\n * @example\n * ```ts\n * const paragraph = document.createElement('p')\n * document.body.append(paragraph)\n * matchesBrowserBlock(paragraph) // true\n * ```\n */\nexport function matchesBrowserBlock(element: Element): boolean {\n\tif (element.localName === 'br') return true\n\tconst display = element.ownerDocument.defaultView?.getComputedStyle(element).display ?? ''\n\treturn !display.startsWith('inline') && display !== 'contents' && display !== 'none'\n}\n\n/**\n * Collects the tree roots a wait observes under a node: the node's own root, then every open\n * shadow root and every same-origin frame document at or beneath it, recursively.\n *\n * @param root - The document, shadow root, or element to collect under\n * @returns The roots, the node's own root first; a cross-origin frame contributes none\n *\n * @example\n * ```ts\n * collectBrowserRoots(document) // [document, ...each open shadow root and frame document]\n * ```\n */\nexport function collectBrowserRoots(root: Document | ShadowRoot | Element): readonly Node[] {\n\tconst roots: Node[] = [root.getRootNode()]\n\tconst queue: Array<Document | ShadowRoot | Element> = [root]\n\tfor (let current = queue.shift(); current !== undefined; current = queue.shift()) {\n\t\tconst view = (isBrowserDocument(current) ? current : current.ownerDocument)?.defaultView ?? null\n\t\tconst own = view !== null && current instanceof view.Element ? [current] : []\n\t\tfor (const element of [...own, ...current.querySelectorAll('*')]) {\n\t\t\tconst shadow = element.shadowRoot\n\t\t\tif (shadow !== null) {\n\t\t\t\troots.push(shadow)\n\t\t\t\tqueue.push(shadow)\n\t\t\t}\n\t\t\tconst child =\n\t\t\t\tview !== null && element instanceof view.HTMLIFrameElement ? element.contentDocument : null\n\t\t\tif (child !== null) {\n\t\t\t\troots.push(child)\n\t\t\t\tqueue.push(child)\n\t\t\t}\n\t\t}\n\t}\n\treturn roots\n}\n\n/**\n * Checks whether activating an element opens another browsing context.\n *\n * @remarks\n * A link with `href` navigates its `target`, and a form, or a submit button inside one, navigates\n * the submitter's `formtarget` or the form's `target`; either falls back to the target of the\n * document's `base` element. `_blank` opens another context, and a target in\n * `BROWSER_CONTEXT_TARGETS` does not. A name reuses the browsing context carrying it when the\n * element's window, an ancestor window, or a frame element in one of their documents carries it,\n * and opens another context otherwise; an ancestor this realm cannot read is skipped.\n *\n * @param element - The element an untrusted activation would target\n * @returns True if the activation opens another browsing context; false otherwise, including\n * for an element whose activation navigates nothing\n *\n * @example\n * ```ts\n * const link = document.createElement('a')\n * link.href = '/cars'\n * link.target = '_blank'\n * matchesBrowserPopup(link) // true\n * ```\n */\nexport function matchesBrowserPopup(element: Element): boolean {\n\tconst document = element.ownerDocument\n\tconst view = document.defaultView\n\tconst base = document.querySelector('base[target]')?.getAttribute('target') ?? ''\n\tconst tag = element.localName\n\tconst type = Reflect.get(element, 'type')\n\tconst submitter =\n\t\t(tag === 'button' && type === 'submit') ||\n\t\t(tag === 'input' && (type === 'submit' || type === 'image'))\n\tconst form = tag === 'form' ? element : Reflect.get(element, 'form')\n\tlet target: string | undefined\n\tif ((tag === 'a' || tag === 'area') && element.hasAttribute('href'))\n\t\ttarget = element.getAttribute('target') ?? base\n\telse if (view !== null && form instanceof view.HTMLFormElement && (tag === 'form' || submitter))\n\t\ttarget =\n\t\t\t(submitter ? element.getAttribute('formtarget') : null) ?? form.getAttribute('target') ?? base\n\tif (target === undefined) return false\n\tconst keyword = target.trim().toLowerCase()\n\tif (BROWSER_CONTEXT_TARGETS.has(keyword)) return false\n\tif (keyword === '_blank') return true\n\tconst selector = `iframe[name=\"${CSS.escape(target)}\"], frame[name=\"${CSS.escape(target)}\"]`\n\tlet current: Window | null = view\n\twhile (current !== null) {\n\t\tconst frame: Window = current\n\t\tconst found = attempt(\n\t\t\t() => frame.name === target || frame.document.querySelector(selector) !== null,\n\t\t)\n\t\tif (found.success && found.value) return false\n\t\tcurrent = frame.parent === frame ? null : frame.parent\n\t}\n\treturn true\n}\n\n/**\n * Checks whether a click on an element activates the `label` that contains it, following the\n * HTML label activation rule.\n *\n * @remarks\n * The click activates the label when the target is the label itself, or when no element on the\n * path from the target up to the label, the target included, matches\n * `BROWSER_INTERACTIVE_CONTENT`.\n *\n * @param target - The element the click lands on\n * @param label - The label that contains the target, or the target itself\n * @returns True if the click activates the label; false otherwise\n *\n * @example\n * ```ts\n * const label = document.createElement('label')\n * label.innerHTML = '<a href=\"#help\">Help</a> <span>Photo</span>'\n * matchesBrowserActivation(label.querySelector('a'), label) // false\n * matchesBrowserActivation(label.querySelector('span'), label) // true\n * ```\n */\nexport function matchesBrowserActivation(target: Element, label: Element): boolean {\n\tfor (\n\t\tlet current: Element | null = target;\n\t\tcurrent !== null && current !== label;\n\t\tcurrent = current.parentElement\n\t) {\n\t\tif (current.matches(BROWSER_INTERACTIVE_CONTENT)) return false\n\t}\n\treturn true\n}\n\n/**\n * Moves a tree walker past the subtree of its current node.\n *\n * @param walker - The walker to move; its root bounds the move\n * @returns The first node after the subtree in document order, or `null` when the walk is done\n *\n * @example\n * ```ts\n * const walker = document.createTreeWalker(document.body)\n * walker.nextNode()\n * skipBrowserSubtree(walker) // the first node after the body's first child and its descendants\n * ```\n */\nexport function skipBrowserSubtree(walker: TreeWalker): Node | null {\n\tlet node = walker.nextSibling()\n\twhile (node === null) {\n\t\tif (walker.parentNode() === null) return null\n\t\tnode = walker.nextSibling()\n\t}\n\treturn node\n}\n\n/**\n * Reads the nearest block container of an element, the unit that separates runs of text.\n *\n * @param element - The element to start from, or `null` for a node without a parent element\n * @param root - The node that bounds the search\n * @returns The nearest inclusive ancestor, below `root`, that `matchesBrowserBlock` reports;\n * `root` when none is\n *\n * @example\n * ```ts\n * const strong = document.createElement('strong')\n * const paragraph = document.createElement('p')\n * paragraph.append(strong)\n * document.body.append(paragraph)\n * readBrowserBlock(strong, document.body) // paragraph\n * ```\n */\nexport function readBrowserBlock(element: Element | null, root: Node): Node {\n\tlet current = element\n\twhile (current !== null && current !== root) {\n\t\tif (matchesBrowserBlock(current)) return current\n\t\tcurrent = current.parentElement\n\t}\n\treturn root\n}\n\n/**\n * Subscribes one listener to a window's navigation events until a signal aborts.\n *\n * @remarks\n * The listener receives the Navigation API's `navigatesuccess` where the window has that API, and\n * `popstate` and `hashchange` where it does not, plus `pagehide` in both cases. A `pushState` in a\n * window without the Navigation API fires none of those events.\n *\n * @param window - The window whose navigation events are observed\n * @param listener - Receives each event; `event.type` tells an unload from a same-document\n * navigation\n * @param signal - Removes every subscription when it aborts\n *\n * @example\n * ```ts\n * const release = new AbortController()\n * listenBrowserNavigation(frame.contentWindow, (event) => console.log(event.type), release.signal)\n * ```\n */\nexport function listenBrowserNavigation(\n\twindow: Window,\n\tlistener: (event: Event) => void,\n\tsignal: AbortSignal,\n): void {\n\tconst options = { signal }\n\tif (Reflect.has(window, 'navigation')) {\n\t\twindow.navigation.addEventListener('navigatesuccess', listener, options)\n\t} else {\n\t\twindow.addEventListener('popstate', listener, options)\n\t\twindow.addEventListener('hashchange', listener, options)\n\t}\n\twindow.addEventListener('pagehide', listener, options)\n}\n\n/**\n * Reads a lowercased ARIA token, preserving whitespace and treating empty or undefined tokens as absent.\n *\n * @param element - The element carrying the attribute\n * @param attribute - The ARIA attribute name\n * @returns The lowercased token, or `undefined` for a missing, empty, or `undefined` attribute\n *\n * @example\n * ```ts\n * const button = document.createElement('button')\n * button.setAttribute('aria-pressed', 'TRUE')\n * readBrowserToken(button, 'aria-pressed') // 'true'\n * ```\n */\nexport function readBrowserToken(element: Element, attribute: string): string | undefined {\n\tconst token = element.getAttribute(attribute)?.toLowerCase()\n\treturn token === '' || token === 'undefined' ? undefined : token\n}\n\n/**\n * Reads the pressed, expanded, and selected states the DOM outline assigns to an element's role.\n *\n * @remarks\n * Only buttons carry pressed state. Expansion follows `BROWSER_EXPANDED_ROLES`, with native\n * single selects always collapsed. Selection follows `BROWSER_SELECTED_ROLES`: an ARIA token\n * overrides native option selectedness, and other elements without a token omit selection. Tokens are not\n * trimmed; values other than `false` are true, except the pressed token `mixed`.\n *\n * @param element - The element whose attributes and native state are read\n * @param role - Its computed accessibility role\n * @returns Present states, including false, with pressed represented as a tristate string\n *\n * @example\n * ```ts\n * const button = document.createElement('button')\n * button.setAttribute('aria-pressed', 'mixed')\n * readBrowserStates(button, 'button') // { pressed: 'mixed' }\n * ```\n */\nexport function readBrowserStates(\n\telement: Element,\n\trole: string,\n): Readonly<Record<string, string | boolean>> {\n\tconst states: Record<string, string | boolean> = {}\n\tconst pressed = readBrowserToken(element, 'aria-pressed')\n\tconst expanded = readBrowserToken(element, 'aria-expanded')\n\tconst selected = readBrowserToken(element, 'aria-selected')\n\tconst view = element.ownerDocument.defaultView\n\tif (role === 'button' && pressed !== undefined)\n\t\tstates['pressed'] = pressed === 'false' || pressed === 'mixed' ? pressed : 'true'\n\tif (\n\t\trole === 'combobox' &&\n\t\tview !== null &&\n\t\telement instanceof view.HTMLSelectElement &&\n\t\t!element.multiple &&\n\t\telement.size <= 1\n\t)\n\t\tstates['expanded'] = false\n\telse if (BROWSER_EXPANDED_ROLES.has(role) && expanded !== undefined)\n\t\tstates['expanded'] = expanded !== 'false'\n\tif (BROWSER_SELECTED_ROLES.has(role)) {\n\t\tif (selected !== undefined) states['selected'] = selected !== 'false'\n\t\telse if (view !== null && element instanceof view.HTMLOptionElement)\n\t\t\tstates['selected'] = element.selected\n\t}\n\treturn states\n}\n","import type { BrowserCallOptions, BrowserReadingInterface } from '@src/core'\nimport type { BrowserDOMElementInput, BrowserDOMElementInterface } from '../types.js'\nimport { isString } from '@orkestrel/contract'\nimport { BrowserElementError, BrowserError, createBrowserReading } from '@src/core'\nimport { BROWSER_TYPED_INPUTS } from '../constants.js'\nimport {\n\tcomputeBrowserName,\n\tmatchesBrowserActivation,\n\tmatchesBrowserPopup,\n\treadBrowserCapture,\n} from '../helpers.js'\n\n/**\n * Drives a referenced element of a DOM document without trusted input.\n *\n * @remarks\n * `click` runs `HTMLElement.click()`; `fill` and `select` set the control through its native\n * prototype setter and dispatch `input` and `change`, and `fill` refuses `UNKNOWN` an element\n * that is not a text control and a read-only one; `submit` runs `form.requestSubmit()` and\n * observes the outcome through a `submit` listener registered across the call. Each action\n * refuses with a `BrowserElementError` naming the reason: `DISABLED` for a disabled control,\n * `HIDDEN` for an element that does not render, and `UNTRUSTED` for what an untrusted event\n * cannot do, which is a click or submission that opens another browsing context, a click that\n * opens a file chooser, and typing into a contenteditable element. A click that activates a\n * `label`, on the label itself or on a descendant that `matchesBrowserActivation` admits, is\n * judged by the label's control as well: a disabled control refuses `DISABLED`, and a file input\n * refuses `UNTRUSTED` as a direct click on it does. A click on an interactive descendant of a\n * label keeps only its own checks. `role` and `name` read the description the latest outline or\n * query that encountered the element captured, so a change to the element shows after the next\n * capture, and a dropped reference keeps its last capture. Every action on an element removed\n * from its document, collected, or held across a navigation reports `GONE`.\n *\n * @example\n * ```ts\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * await view.elements.outline()\n * await view.elements.element('e1')?.click()\n * ```\n */\nexport class BrowserDOMElement implements BrowserDOMElementInterface {\n\treadonly #input: BrowserDOMElementInput\n\n\tconstructor(input: BrowserDOMElementInput) {\n\t\tthis.#input = input\n\t}\n\n\tget reference(): string {\n\t\treturn this.#input.reference\n\t}\n\n\tget role(): string {\n\t\treturn this.#input.description().role\n\t}\n\n\tget name(): string {\n\t\treturn this.#input.description().name\n\t}\n\n\tasync click(options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#actionable(options)\n\t\tconst label = node instanceof view.HTMLLabelElement ? node : node.closest('label')\n\t\tconst control = label !== null && matchesBrowserActivation(node, label) ? label.control : null\n\t\tif (control !== null && control !== node) {\n\t\t\tif (control.matches(':disabled')) {\n\t\t\t\tthrow new BrowserElementError(this.reference, 'DISABLED', 'labels a disabled control')\n\t\t\t}\n\t\t\tthis.#refuse(control)\n\t\t}\n\t\tthis.#refuse(node)\n\t\tif (node instanceof view.HTMLElement) {\n\t\t\tnode.click()\n\t\t\treturn\n\t\t}\n\t\tnode.dispatchEvent(\n\t\t\tnew view.MouseEvent('click', { bubbles: true, cancelable: true, composed: true }),\n\t\t)\n\t}\n\n\tasync fill(value: string, options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#actionable(options)\n\t\tif (node instanceof view.HTMLElement && node.isContentEditable) {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'is contenteditable, which an untrusted event cannot type into',\n\t\t\t)\n\t\t}\n\t\tconst input = node instanceof view.HTMLInputElement ? node : undefined\n\t\tconst control = input ?? (node instanceof view.HTMLTextAreaElement ? node : undefined)\n\t\tconst setter = Reflect.getOwnPropertyDescriptor(\n\t\t\tinput === undefined ? view.HTMLTextAreaElement.prototype : view.HTMLInputElement.prototype,\n\t\t\t'value',\n\t\t)?.set\n\t\tif (control === undefined || (input !== undefined && !BROWSER_TYPED_INPUTS.has(input.type))) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not a text control')\n\t\t}\n\t\tif (control.readOnly || setter === undefined) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not editable')\n\t\t}\n\t\tcontrol.focus()\n\t\tReflect.apply(setter, control, [value])\n\t\tcontrol.dispatchEvent(\n\t\t\tnew view.InputEvent('input', {\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t\tinputType: 'insertReplacementText',\n\t\t\t\tdata: value,\n\t\t\t}),\n\t\t)\n\t\tcontrol.dispatchEvent(new view.Event('change', { bubbles: true }))\n\t}\n\n\tasync select(values: readonly string[], options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#actionable(options)\n\t\tif (!(node instanceof view.HTMLSelectElement)) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not a select control')\n\t\t}\n\t\tconst choices = Array.from(node.options)\n\t\tconst selected = values.map(\n\t\t\t(value) =>\n\t\t\t\tchoices.find((option) => option.value === value) ??\n\t\t\t\tchoices.find((option) => option.label === value),\n\t\t)\n\t\tconst missing = values.find((_value, index) => selected[index] === undefined)\n\t\tif (missing !== undefined) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'has no such option')\n\t\t}\n\t\tfor (const option of choices) option.selected = selected.includes(option)\n\t\tnode.dispatchEvent(new view.Event('input', { bubbles: true, composed: true }))\n\t\tnode.dispatchEvent(new view.Event('change', { bubbles: true }))\n\t}\n\n\tasync focus(options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#current(options)\n\t\tif (node instanceof view.HTMLElement || node instanceof view.SVGElement) node.focus()\n\t}\n\n\tasync read(options?: BrowserCallOptions): Promise<BrowserReadingInterface> {\n\t\tconst [node] = this.#current(options)\n\t\treturn createBrowserReading({ ...readBrowserCapture(node), navigation: this.#input.navigation })\n\t}\n\n\tasync submit(options?: BrowserCallOptions): Promise<void> {\n\t\tconst [node, view] = this.#current(options)\n\t\tconst owner = node instanceof view.HTMLFormElement ? node : Reflect.get(node, 'form')\n\t\tif (!(owner instanceof view.HTMLFormElement)) {\n\t\t\tthrow new BrowserElementError(this.reference, 'UNKNOWN', 'is not in a form')\n\t\t}\n\t\tconst type = Reflect.get(node, 'type')\n\t\tconst submitter =\n\t\t\t(node instanceof view.HTMLButtonElement && type === 'submit') ||\n\t\t\t(node instanceof view.HTMLInputElement && (type === 'submit' || type === 'image'))\n\t\t\t\t? node\n\t\t\t\t: undefined\n\t\tif (submitter?.matches(':disabled') === true) {\n\t\t\tthrow new BrowserElementError(this.reference, 'DISABLED')\n\t\t}\n\t\tif (matchesBrowserPopup(submitter ?? owner)) {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'submits into another browsing context, which an untrusted submission cannot open',\n\t\t\t)\n\t\t}\n\t\tlet submitted = false\n\t\tconst release = new AbortController()\n\t\towner.addEventListener(\n\t\t\t'submit',\n\t\t\t() => {\n\t\t\t\tsubmitted = true\n\t\t\t},\n\t\t\t{ signal: release.signal },\n\t\t)\n\t\ttry {\n\t\t\towner.requestSubmit(submitter ?? null)\n\t\t} finally {\n\t\t\trelease.abort()\n\t\t}\n\t\tif (submitted) return\n\t\tconst invalid = Array.from(owner.elements).find(\n\t\t\t(control) => control.localName !== 'fieldset' && control.matches(':invalid'),\n\t\t)\n\t\tif (invalid === undefined) {\n\t\t\tthrow new BrowserError('did not submit', 'BROWSER_DOCUMENT_SUBMIT', {\n\t\t\t\treference: this.reference,\n\t\t\t})\n\t\t}\n\t\tconst field = computeBrowserName(invalid) || (invalid.getAttribute('name') ?? invalid.localName)\n\t\tconst reason = Reflect.get(invalid, 'validationMessage')\n\t\tconst message = isString(reason) ? reason : ''\n\t\tthrow new BrowserError(`did not submit: ${field} — ${message}`, 'BROWSER_DOCUMENT_SUBMIT', {\n\t\t\treference: this.reference,\n\t\t\tfield,\n\t\t\tmessage,\n\t\t})\n\t}\n\n\t// Resolves the element and its realm, refusing an element its view no longer holds.\n\t#current(options?: BrowserCallOptions): readonly [Element, Window & typeof globalThis] {\n\t\toptions?.signal?.throwIfAborted()\n\t\tconst node = this.#input.node.deref()\n\t\tconst view = node?.ownerDocument.defaultView ?? null\n\t\tif (!this.#input.current() || node === undefined || !node.isConnected || view === null) {\n\t\t\tthrow new BrowserElementError(this.reference, 'GONE')\n\t\t}\n\t\treturn [node, view]\n\t}\n\n\t// Resolves an element an action targets: current, rendered, and enabled.\n\t#actionable(options?: BrowserCallOptions): readonly [Element, Window & typeof globalThis] {\n\t\tconst current = this.#current(options)\n\t\tconst [node] = current\n\t\tif (!node.checkVisibility()) throw new BrowserElementError(this.reference, 'HIDDEN')\n\t\tif (node.matches(':disabled')) throw new BrowserElementError(this.reference, 'DISABLED')\n\t\treturn current\n\t}\n\n\t// Refuses an activation target whose activation an untrusted click cannot perform.\n\t#refuse(target: Element): void {\n\t\tif (matchesBrowserPopup(target)) {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'opens another browsing context, which an untrusted click cannot do',\n\t\t\t)\n\t\t}\n\t\tif (target.localName === 'input' && Reflect.get(target, 'type') === 'file') {\n\t\t\tthrow new BrowserElementError(\n\t\t\t\tthis.reference,\n\t\t\t\t'UNTRUSTED',\n\t\t\t\t'opens a file chooser, which an untrusted click cannot do',\n\t\t\t)\n\t\t}\n\t}\n}\n","import type { BrowserDOMWaitInterface, BrowserMutationWait } from './types.js'\nimport { attempt } from '@orkestrel/contract'\nimport { BROWSER_WAIT_EVENTS, BrowserElementError, BrowserError } from '@src/core'\nimport { isBrowserDocument } from './helpers.js'\n\n/**\n * Parks one condition on DOM mutations and finished transitions and animations until it holds, with one deadline and coalesced wake tasks.\n *\n * @remarks\n * The wait observes every root `roots` returns, each through a `MutationObserver` of that root's\n * realm, and re-reads the roots after every mutation batch, every capture-phase `load`, and\n * the task after a `BROWSER_WAIT_EVENTS` event in an observed root: a same-origin\n * frame or an open shadow root that appears joins the observation,\n * and a root that departed (a replaced frame document, a removed shadow root) leaves it, with its\n * observer disconnected and its listeners removed. The check runs before the wait parks and\n * again after every subscription, and no check runs once the deadline, counted from `start`, has\n * passed, which the wait reads again after `roots` returns. The wait settles one time: on the\n * check's first value, on the signal's abort with its reason, at the deadline with\n * `BROWSER_WAIT_TIMEOUT`, on a `pagehide` in the first root's window with `GONE`, or with whatever\n * the check or the roots function throws. A signal that aborts while `check` or `roots` runs\n * settles the wait with its reason, and wins over a value that same check returns. Settlement\n * disconnects every observer and removes every listener synchronously, so a mutation queued\n * before it runs no check, and a `roots` or `check` that settles the wait from inside leaves no\n * observer, listener, or further check behind.\n *\n * A shadow root attached after the wait began is a declared limit: attaching one fires no\n * mutation record and no event, so the wait discovers it at the next mutation batch, `load`,\n * or `BROWSER_WAIT_EVENTS` event it observes, and a match inserted into it with no other\n * observed change is not seen before the deadline. The wait never polls to close that gap.\n *\n * @example\n * ```ts\n * const ready = await new BrowserDOMWait({\n * \troots: () => [document],\n * \tcheck: () => document.querySelector('#ready') ?? undefined,\n * \ttimeout: 1_000,\n * \tstart: performance.now(),\n * \tsubject: 'Ready wait',\n * }).execute()\n * ```\n */\nexport class BrowserDOMWait<T> implements BrowserDOMWaitInterface<T> {\n\treadonly #wait: BrowserMutationWait<T>\n\treadonly #settled = Promise.withResolvers<T>()\n\treadonly #release = new AbortController()\n\treadonly #observers = new Map<\n\t\tNode,\n\t\t{ readonly observer: MutationObserver; readonly release: AbortController }\n\t>()\n\t#main: Window | undefined\n\t#timer: ReturnType<typeof setTimeout> | undefined\n\t#task: ReturnType<typeof setTimeout> | undefined\n\treadonly #recheckHandler = this.#recheck.bind(this)\n\treadonly #scheduleHandler = this.#schedule.bind(this)\n\treadonly #wakeHandler = this.#wake.bind(this)\n\treadonly #unloadHandler = this.#unload.bind(this)\n\n\tconstructor(wait: BrowserMutationWait<T>) {\n\t\tthis.#wait = wait\n\t}\n\n\tget roots(): readonly Node[] {\n\t\treturn [...this.#observers.keys()]\n\t}\n\n\tasync execute(): Promise<T> {\n\t\tconst signal = this.#wait.signal\n\t\tsignal?.throwIfAborted()\n\t\tconst first = this.#wait.check()\n\t\t// The abort listener is not registered yet, so an abort from inside the check is read here.\n\t\tsignal?.throwIfAborted()\n\t\tif (first !== undefined) return first\n\t\tthis.#timer = setTimeout(this.#expire.bind(this), Math.max(0, this.#remaining()))\n\t\tsignal?.addEventListener('abort', () => this.#fail(signal.reason), {\n\t\t\tsignal: this.#release.signal,\n\t\t})\n\t\tthis.#recheck()\n\t\treturn await this.#settled.promise\n\t}\n\n\t// Hidden documents suspend animation frames; tasks still run.\n\t#schedule(): void {\n\t\tif (this.#release.signal.aborted || this.#task !== undefined) return\n\t\tthis.#task = setTimeout(this.#wakeHandler, 0)\n\t}\n\n\t#wake(): void {\n\t\tthis.#task = undefined\n\t\tthis.#recheck()\n\t}\n\n\t// Subscribes to every live root and prunes departed ones, then runs the check. From here on\n\t// the abort listener turns a caller's abort into settlement, so the release state carries it.\n\t#recheck(): void {\n\t\tif (this.#release.signal.aborted) return\n\t\tif (this.#remaining() <= 0) {\n\t\t\tthis.#expire()\n\t\t\treturn\n\t\t}\n\t\tconst result = attempt(() => {\n\t\t\tthis.#reconcile()\n\t\t\tif (this.#release.signal.aborted) return undefined\n\t\t\tif (this.#remaining() <= 0) {\n\t\t\t\tthis.#expire()\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn this.#wait.check()\n\t\t})\n\t\tif (!result.success) this.#fail(result.error)\n\t\telse if (result.value !== undefined) this.#succeed(result.value)\n\t}\n\n\t#reconcile(): void {\n\t\tconst live = new Set(this.#wait.roots())\n\t\tif (this.#release.signal.aborted) return\n\t\tfor (const [root, entry] of this.#observers) {\n\t\t\tif (live.has(root)) continue\n\t\t\tentry.observer.disconnect()\n\t\t\tentry.release.abort()\n\t\t\tthis.#observers.delete(root)\n\t\t}\n\t\tfor (const root of live) {\n\t\t\tif (this.#observers.has(root)) continue\n\t\t\tconst document = isBrowserDocument(root) ? root : root.ownerDocument\n\t\t\tconst view = document?.defaultView ?? null\n\t\t\tif (view === null) continue\n\t\t\tconst observer = new view.MutationObserver(this.#recheckHandler)\n\t\t\tobserver.observe(root, {\n\t\t\t\tsubtree: true,\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: true,\n\t\t\t\tcharacterData: true,\n\t\t\t})\n\t\t\tconst release = new AbortController()\n\t\t\troot.addEventListener('load', this.#recheckHandler, { capture: true, signal: release.signal })\n\t\t\tfor (const name of BROWSER_WAIT_EVENTS)\n\t\t\t\troot.addEventListener(name, this.#scheduleHandler, {\n\t\t\t\t\tcapture: true,\n\t\t\t\t\tsignal: release.signal,\n\t\t\t\t})\n\t\t\tthis.#observers.set(root, { observer, release })\n\t\t\t// Only the first root's window failing ends the wait; a child frame's unload is followed\n\t\t\t// by its next document's `load`, which reconciles the roots.\n\t\t\tif (this.#main !== undefined) continue\n\t\t\tthis.#main = view\n\t\t\tview.addEventListener('pagehide', this.#unloadHandler, { signal: this.#release.signal })\n\t\t}\n\t}\n\n\t#remaining(): number {\n\t\tconst now = this.#wait.now\n\t\treturn this.#wait.start + this.#wait.timeout - (now === undefined ? performance.now() : now())\n\t}\n\n\t#expire(): void {\n\t\tthis.#fail(\n\t\t\tnew BrowserError(`${this.#wait.subject} timed out`, 'BROWSER_WAIT_TIMEOUT', {\n\t\t\t\ttimeout: this.#wait.timeout,\n\t\t\t}),\n\t\t)\n\t}\n\n\t#unload(): void {\n\t\tthis.#fail(new BrowserElementError({ subject: 'document' }, 'GONE'))\n\t}\n\n\t#succeed(value: T): void {\n\t\tthis.#stop()\n\t\tthis.#settled.resolve(value)\n\t}\n\n\t#fail(error: unknown): void {\n\t\tthis.#stop()\n\t\tthis.#settled.reject(error)\n\t}\n\n\t// Releases every observer, listener, and the timer before the promise settles.\n\t#stop(): void {\n\t\tclearTimeout(this.#timer)\n\t\tclearTimeout(this.#task)\n\t\tthis.#task = undefined\n\t\tthis.#release.abort()\n\t\tfor (const entry of this.#observers.values()) {\n\t\t\tentry.observer.disconnect()\n\t\t\tentry.release.abort()\n\t\t}\n\t\tthis.#observers.clear()\n\t}\n}\n","import type {\n\tBrowserCallOptions,\n\tBrowserElementInterface,\n\tBrowserElementManagerInterface,\n\tBrowserElementQuery,\n\tBrowserWaitOptions,\n\tBrowserOutline,\n\tBrowserOutlineNode,\n\tBrowserOutlineOptions,\n} from '@src/core'\nimport type { BrowserDOMElementInterface, BrowserDOMElementManagerInput } from '../types.js'\nimport { attempt, isInteger } from '@orkestrel/contract'\nimport {\n\tBROWSER_INTERACTIVE_ROLES,\n\tBROWSER_OUTLINE_LIMIT,\n\tBROWSER_REFERENCE_PREFIX,\n\tBrowserElementError,\n\tBrowserError,\n\tfilterBrowserOutline,\n\tnormalizeBrowserName,\n\tparseBrowserReference,\n\trenderBrowserOutline,\n\tvalidateBrowserTimeout,\n} from '@src/core'\nimport { BrowserDOMElement } from './BrowserDOMElement.js'\nimport { BrowserDOMWait } from '../BrowserDOMWait.js'\nimport {\n\tBROWSER_CONTENT_NAMED_ROLES,\n\tBROWSER_DOCUMENT_TIMEOUT_MS,\n\tBROWSER_TYPED_INPUTS,\n} from '../constants.js'\nimport {\n\tcollectBrowserRoots,\n\tcomputeBrowserName,\n\tcomputeBrowserRole,\n\tlistenBrowserNavigation,\n\tmatchesBrowserHidden,\n\tmatchesBrowserInvisible,\n\tmatchesBrowserOmitted,\n\treadBrowserBlock,\n\treadBrowserStates,\n\tskipBrowserSubtree,\n} from '../helpers.js'\n\n/**\n * Outlines a DOM document from its elements and binds stable references to the interactive ones.\n *\n * @remarks\n * Rows come in document order from a `TreeWalker` over the flat tree: an open shadow root\n * contributes its rows in place of its host's children, a `slot` its assigned nodes, and a\n * same-origin `iframe` its document's rows, while a cross-origin one renders\n * `iframe \"NAME\" (cross-origin, not readable)`. An element that `matchesBrowserHidden` reports is\n * omitted with its subtree, a scope root in such a subtree yields no row, and an element that\n * `matchesBrowserInvisible` reports yields no row of its own. An element whose role\n * `BROWSER_INTERACTIVE_ROLES` names receives a reference bound through a `WeakRef`, which never\n * changes while the manager holds it, and a reference number is never reused. Every outline or\n * query that encounters a bound element records its role and name afresh, and the element's\n * wrapper reports that latest capture, also after the manager drops the reference. A reference\n * and a reading from any walked document record that document's epoch, which advances on its own\n * navigation events and on the view's; that document's `pagehide` drops its references. A form\n * carrying a `toolname` attribute renders `[tool=NAME]` after its role and name. A row carries\n * `focused` when its element is the active element of its own document or shadow root. Rows carry\n * pressed, expanded, and selected states through the Chromium mapping in `readBrowserStates`.\n * A `select` row is followed by one `option` row per option, named by its label. Whitespace between two texts of\n * one block renders as one space, as a rendered `br` between them does, and texts with neither\n * between them stay joined. A CSS query\n * searches the document the view drives, not its child documents or shadow trees. After the\n * input's `signal` aborts, `outline`, `find`, and `wait` reject with its reason.\n *\n * `wait` parks a `BrowserDOMWait` bound to the view's lifetime over every root that\n * `collectBrowserRoots` reaches from its scope, reconciled at every observed mutation and frame\n * `load`. A shadow root attached after the wait began is a declared limit: the wait discovers it\n * at the next observed mutation or `load`, so a match inserted there with no other observed\n * change is not seen before the deadline.\n *\n * @example\n * ```ts\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * const outline = await view.elements.outline()\n * const [save] = await view.elements.find({ role: 'button', name: 'save' })\n * ```\n */\nexport class BrowserDOMElementManager implements BrowserElementManagerInterface<BrowserDOMElementInterface> {\n\treadonly #input: BrowserDOMElementManagerInput\n\treadonly #records = new Map<\n\t\tstring,\n\t\t{ readonly node: WeakRef<Element>; readonly element: BrowserDOMElement }\n\t>()\n\treadonly #identities = new WeakMap<Element, string>()\n\treadonly #descriptions = new WeakMap<\n\t\tWeakRef<Element>,\n\t\tPick<BrowserElementInterface, 'role' | 'name'>\n\t>()\n\treadonly #epochs = new WeakMap<Document, number>()\n\treadonly #watched = new WeakSet<Document>()\n\t#count = 0\n\n\tconstructor(input: BrowserDOMElementManagerInput) {\n\t\tthis.#input = input\n\t}\n\n\tasync outline(options?: BrowserOutlineOptions): Promise<BrowserOutline> {\n\t\tthis.#input.signal.throwIfAborted()\n\t\tconst limit = options?.limit ?? BROWSER_OUTLINE_LIMIT\n\t\tif (!isInteger(limit) || limit < 0) {\n\t\t\tthrow new BrowserError('Outline limit must be a nonnegative integer', undefined, { limit })\n\t\t}\n\t\toptions?.signal?.throwIfAborted()\n\t\tconst document = this.#input.document()\n\t\tconst rows = this.#capture(this.#root(document, options?.within), options?.within)\n\t\treturn renderBrowserOutline(document.URL, document.title, rows, limit, options?.search)\n\t}\n\n\tasync find(\n\t\tquery: BrowserElementQuery,\n\t\toptions?: BrowserCallOptions,\n\t): Promise<readonly BrowserDOMElementInterface[]> {\n\t\tthis.#input.signal.throwIfAborted()\n\t\toptions?.signal?.throwIfAborted()\n\t\treturn this.#find(query)\n\t}\n\n\tasync wait(\n\t\tquery: BrowserElementQuery,\n\t\toptions?: BrowserWaitOptions,\n\t): Promise<readonly BrowserDOMElementInterface[]> {\n\t\tthis.#input.signal.throwIfAborted()\n\t\tconst start = performance.now()\n\t\tconst timeout = options?.timeout ?? BROWSER_DOCUMENT_TIMEOUT_MS\n\t\tvalidateBrowserTimeout(timeout)\n\t\tconst signal =\n\t\t\toptions?.signal === undefined\n\t\t\t\t? this.#input.signal\n\t\t\t\t: AbortSignal.any([options.signal, this.#input.signal])\n\t\treturn await new BrowserDOMWait({\n\t\t\troots: this.#roots.bind(this, query.within),\n\t\t\tcheck: this.#match.bind(this, query, options?.absent === true),\n\t\t\ttimeout,\n\t\t\tstart,\n\t\t\tsignal,\n\t\t\tsubject: 'Element wait',\n\t\t}).execute()\n\t}\n\n\telement(reference: string): BrowserDOMElementInterface | undefined {\n\t\treturn this.#records.get(parseBrowserReference(reference) ?? '')?.element\n\t}\n\n\telements(): readonly BrowserDOMElementInterface[] {\n\t\tfor (const [reference, record] of this.#records) {\n\t\t\tif (record.node.deref() === undefined) this.#records.delete(reference)\n\t\t}\n\t\treturn [...this.#records.values()].map((record) => record.element)\n\t}\n\n\tclear(): void {\n\t\tthis.#records.clear()\n\t}\n\n\t// Reports the elements a wait settles on, or undefined while it keeps waiting.\n\t#match(\n\t\tquery: BrowserElementQuery,\n\t\tabsent: boolean,\n\t): readonly BrowserDOMElementInterface[] | undefined {\n\t\tconst found = this.#find(query)\n\t\treturn (absent ? found.length === 0 : found.length > 0) ? found : undefined\n\t}\n\n\t#find(query: BrowserElementQuery): readonly BrowserDOMElement[] {\n\t\tconst root = this.#root(this.#input.document(), query.within)\n\t\tconst matches = filterBrowserOutline(this.#capture(root, query.within), query).flatMap(\n\t\t\t(row) => {\n\t\t\t\tconst record = this.#records.get(row.reference ?? '')\n\t\t\t\treturn record === undefined ? [] : [record.element]\n\t\t\t},\n\t\t)\n\t\tconst css = query.css\n\t\tif (css === undefined) return matches\n\t\tconst selected = attempt(() => Array.from(root.querySelectorAll(css)))\n\t\tif (!selected.success) {\n\t\t\tthrow new BrowserError(`CSS query is invalid: ${css}`, 'BROWSER_ELEMENT_QUERY', { css })\n\t\t}\n\t\tconst bound = selected.value.map((element) => {\n\t\t\tconst role = computeBrowserRole(element) ?? 'generic'\n\t\t\treturn this.#bind(element, role, computeBrowserName(element, role))\n\t\t})\n\t\tif (query.role === undefined && query.name === undefined) return bound\n\t\treturn matches.filter((element) => bound.includes(element))\n\t}\n\n\t// Walks one scope; a scope root in an omitted subtree yields no row.\n\t#capture(root: Element, within?: string): readonly BrowserOutlineNode[] {\n\t\tconst rows: BrowserOutlineNode[] = []\n\t\tif (within === undefined || !matchesBrowserOmitted(root)) this.#walk(root, rows, false)\n\t\treturn rows\n\t}\n\n\t// Resolves the element an outline, query, or wait is scoped to.\n\t#root(document: Document, within?: string): Element {\n\t\tif (within === undefined) return document.documentElement\n\t\tconst node = this.#records.get(parseBrowserReference(within) ?? '')?.node.deref()\n\t\tif (node === undefined || !node.isConnected || node.ownerDocument.defaultView === null) {\n\t\t\tthrow new BrowserElementError(within, 'GONE')\n\t\t}\n\t\treturn node\n\t}\n\n\t// Collects the roots a wait observes, re-read after every mutation batch and frame load.\n\t#roots(within?: string): readonly Node[] {\n\t\treturn collectBrowserRoots(this.#root(this.#input.document(), within))\n\t}\n\n\t// Appends the rows of one flat-tree subtree, descending into shadow roots, slots, and frames.\n\t#walk(root: Element | ShadowRoot, rows: BrowserOutlineNode[], muted: boolean): void {\n\t\tconst document = root.ownerDocument\n\t\tconst view = document.defaultView\n\t\tif (view === null) return\n\t\tif (root instanceof view.Element && matchesBrowserHidden(root)) return\n\t\tthis.#watch(document)\n\t\tconst walker = document.createTreeWalker(\n\t\t\troot,\n\t\t\tNodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,\n\t\t\t(node) =>\n\t\t\t\tnode instanceof view.Element && matchesBrowserHidden(node)\n\t\t\t\t\t? NodeFilter.FILTER_REJECT\n\t\t\t\t\t: NodeFilter.FILTER_ACCEPT,\n\t\t)\n\t\tlet text = ''\n\t\tlet block: Node | undefined\n\t\tlet silenced: Element | undefined\n\t\tlet node: Node | null = root instanceof view.Element ? root : walker.nextNode()\n\t\twhile (node !== null) {\n\t\t\tif (silenced !== undefined && !silenced.contains(node)) silenced = undefined\n\t\t\tconst quiet = muted || silenced !== undefined\n\t\t\tif (!(node instanceof view.Element)) {\n\t\t\t\tconst parent = node.parentElement\n\t\t\t\tconst data = node.textContent ?? ''\n\t\t\t\tconst blank = data.trim() === ''\n\t\t\t\t// Whitespace between two texts of one block separates them, so it joins the pending text\n\t\t\t\t// and normalization collapses it; elsewhere it contributes nothing.\n\t\t\t\tif (\n\t\t\t\t\t!quiet &&\n\t\t\t\t\t(!blank || text !== '') &&\n\t\t\t\t\t(parent === null || !matchesBrowserInvisible(parent))\n\t\t\t\t) {\n\t\t\t\t\tconst container = readBrowserBlock(parent, root)\n\t\t\t\t\tif (!blank) {\n\t\t\t\t\t\tif (block !== undefined && block !== container) text = this.#flush(rows, text)\n\t\t\t\t\t\ttext += data\n\t\t\t\t\t\tblock = container\n\t\t\t\t\t} else if (container === block) text += data\n\t\t\t\t}\n\t\t\t\tnode = walker.nextNode()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst invisible = matchesBrowserInvisible(node)\n\t\t\t// A rendered break separates the texts of its block the way whitespace does; the walker never\n\t\t\t// reaches a hidden one.\n\t\t\tif (node.localName === 'br') {\n\t\t\t\tif (!quiet && text !== '') text += '\\n'\n\t\t\t\tnode = walker.nextNode()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (node instanceof view.HTMLIFrameElement) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\tconst child = node.contentDocument\n\t\t\t\tif (invisible) {\n\t\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (child === null) {\n\t\t\t\t\tthis.#text(\n\t\t\t\t\t\trows,\n\t\t\t\t\t\t`iframe ${JSON.stringify(computeBrowserName(node))} (cross-origin, not readable)`,\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tthis.#walk(child.documentElement, rows, quiet)\n\t\t\t\t}\n\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (node instanceof view.HTMLSlotElement) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\tfor (const assigned of node.assignedNodes({ flatten: true })) {\n\t\t\t\t\tif (assigned instanceof view.Element) this.#walk(assigned, rows, quiet)\n\t\t\t\t\telse if (!quiet) this.#flush(rows, assigned.textContent ?? '')\n\t\t\t\t}\n\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst tool = node.localName === 'form' ? (node.getAttribute('toolname') ?? '') : ''\n\t\t\tconst role = tool === '' ? computeBrowserRole(node) : 'form'\n\t\t\tif (\n\t\t\t\t!invisible &&\n\t\t\t\trole !== undefined &&\n\t\t\t\t(BROWSER_INTERACTIVE_ROLES.has(role) || role === 'heading' || tool !== '')\n\t\t\t) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\trows.push(this.#row(node, role, view, String(rows.length)))\n\t\t\t\tif (silenced === undefined && BROWSER_CONTENT_NAMED_ROLES.has(role)) silenced = node\n\t\t\t\tif (node.localName === 'textarea') {\n\t\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst shadow = node.shadowRoot\n\t\t\tif (shadow !== null) {\n\t\t\t\ttext = this.#flush(rows, text)\n\t\t\t\tthis.#walk(shadow, rows, muted || silenced !== undefined)\n\t\t\t\tnode = skipBrowserSubtree(walker)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tnode = walker.nextNode()\n\t\t}\n\t\tthis.#flush(rows, text)\n\t}\n\n\t// Subscribes one time to a walked document's navigation events.\n\t#watch(document: Document): void {\n\t\tconst view = document.defaultView\n\t\tif (this.#watched.has(document) || view === null) return\n\t\tthis.#watched.add(document)\n\t\tlistenBrowserNavigation(\n\t\t\tview,\n\t\t\tthis.#advance.bind(this, new WeakRef(document)),\n\t\t\tthis.#input.signal,\n\t\t)\n\t}\n\n\t// Advances one document's epoch; its unload drops the references bound in it.\n\t#advance(document: WeakRef<Document>, event: Event): void {\n\t\tconst target = document.deref()\n\t\tif (target === undefined) return\n\t\tthis.#epochs.set(target, (this.#epochs.get(target) ?? 0) + 1)\n\t\tif (event.type !== 'pagehide') return\n\t\tfor (const [reference, record] of this.#records) {\n\t\t\tconst node = record.node.deref()\n\t\t\tif (node === undefined || node.ownerDocument === target) this.#records.delete(reference)\n\t\t}\n\t}\n\n\t// Reads the epoch a reading from one document records; a collected document reads -1.\n\t#epoch(document: WeakRef<Document>): number {\n\t\tconst target = document.deref()\n\t\treturn target === undefined ? -1 : this.#input.navigation() + (this.#epochs.get(target) ?? 0)\n\t}\n\n\t// Emits the pending text as one row and returns the emptied buffer.\n\t#flush(rows: BrowserOutlineNode[], text: string): string {\n\t\tif (normalizeBrowserName(text) !== '') this.#text(rows, text)\n\t\treturn ''\n\t}\n\n\t#text(rows: BrowserOutlineNode[], text: string): void {\n\t\trows.push({\n\t\t\tid: String(rows.length),\n\t\t\tparent: undefined,\n\t\t\tchildren: [],\n\t\t\tbackend: undefined,\n\t\t\tframe: undefined,\n\t\t\tignored: false,\n\t\t\trole: 'StaticText',\n\t\t\tname: normalizeBrowserName(text),\n\t\t\tdescription: undefined,\n\t\t\tvalue: undefined,\n\t\t\tproperties: {},\n\t\t\tsession: '',\n\t\t\treference: undefined,\n\t\t})\n\t}\n\n\t#row(\n\t\telement: Element,\n\t\trole: string,\n\t\tview: Window & typeof globalThis,\n\t\tid: string,\n\t): BrowserOutlineNode {\n\t\tconst name = computeBrowserName(element, role)\n\t\tconst tool = element.localName === 'form' ? element.getAttribute('toolname') : null\n\t\tconst reference = role === 'heading' ? undefined : this.#bind(element, role, name).reference\n\t\tconst input = element instanceof view.HTMLInputElement ? element : undefined\n\t\tconst checked =\n\t\t\tinput !== undefined && (input.type === 'checkbox' || input.type === 'radio')\n\t\t\t\t? input.checked\n\t\t\t\t: element.getAttribute('aria-checked') === 'true'\n\t\t// Focus inside a shadow tree leaves its host as the document's active element, so the\n\t\t// element is compared with the active element of its own root.\n\t\tconst root = element.getRootNode()\n\t\tconst focused =\n\t\t\t(root instanceof view.Document || root instanceof view.ShadowRoot) &&\n\t\t\troot.activeElement === element\n\t\tlet value: string | undefined\n\t\tif (element instanceof view.HTMLSelectElement)\n\t\t\tvalue = Array.from(element.selectedOptions, (option) => option.label).join(', ')\n\t\telse if (element instanceof view.HTMLTextAreaElement) value = element.value\n\t\telse if (\n\t\t\tinput !== undefined &&\n\t\t\tinput.type !== 'password' &&\n\t\t\t(BROWSER_TYPED_INPUTS.has(input.type) || input.type === 'range')\n\t\t)\n\t\t\tvalue = input.value\n\t\treturn {\n\t\t\tid: reference ?? id,\n\t\t\tparent: undefined,\n\t\t\tchildren: [],\n\t\t\tbackend: undefined,\n\t\t\tframe: undefined,\n\t\t\tignored: false,\n\t\t\trole,\n\t\t\tname,\n\t\t\tdescription: undefined,\n\t\t\tvalue,\n\t\t\tproperties: {\n\t\t\t\tchecked,\n\t\t\t\tdisabled: element.matches(':disabled'),\n\t\t\t\tfocused,\n\t\t\t\t...readBrowserStates(element, role),\n\t\t\t},\n\t\t\t...(tool === null || tool === '' ? {} : { tool }),\n\t\t\tsession: '',\n\t\t\treference,\n\t\t}\n\t}\n\n\t#bind(element: Element, role: string, name: string): BrowserDOMElement {\n\t\tconst known = this.#identities.get(element)\n\t\tconst existing = known === undefined ? undefined : this.#records.get(known)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#descriptions.set(existing.node, { role, name })\n\t\t\treturn existing.element\n\t\t}\n\t\tthis.#count += 1\n\t\tconst reference = `${BROWSER_REFERENCE_PREFIX}${this.#count}`\n\t\tconst node = new WeakRef(element)\n\t\tconst description = { role, name }\n\t\tthis.#descriptions.set(node, description)\n\t\tconst created = new BrowserDOMElement({\n\t\t\treference,\n\t\t\tdescription: this.#description.bind(this, node, description),\n\t\t\tnode,\n\t\t\tcurrent: this.#holds.bind(this, reference),\n\t\t\tnavigation: this.#epoch.bind(this, new WeakRef(element.ownerDocument)),\n\t\t})\n\t\tthis.#records.set(reference, { node, element: created })\n\t\tthis.#identities.set(element, reference)\n\t\treturn created\n\t}\n\n\t#holds(reference: string): boolean {\n\t\treturn this.#records.has(reference)\n\t}\n\n\t// Reads the latest capture of a binding; the entry lives as long as the wrapper's weak node.\n\t#description(\n\t\tnode: WeakRef<Element>,\n\t\tcaptured: Pick<BrowserElementInterface, 'role' | 'name'>,\n\t): Pick<BrowserElementInterface, 'role' | 'name'> {\n\t\treturn this.#descriptions.get(node) ?? captured\n\t}\n}\n","import type {\n\tBrowserCallOptions,\n\tBrowserWaitOptions,\n\tBrowserElementManagerInterface,\n\tBrowserReadingInterface,\n} from '@src/core'\nimport type {\n\tBrowserDOMElementInterface,\n\tBrowserDOMViewInterface,\n\tBrowserDOMViewOptions,\n} from './types.js'\nimport { BrowserError, createBrowserReading, validateBrowserTimeout } from '@src/core'\nimport { BrowserDOMElementManager } from './elements/BrowserDOMElementManager.js'\nimport { BROWSER_DOCUMENT_TIMEOUT_MS } from './constants.js'\nimport { BrowserDOMWait } from './BrowserDOMWait.js'\nimport {\n\tcollectBrowserRoots,\n\tisBrowserDocument,\n\tlistenBrowserNavigation,\n\treadBrowserCapture,\n} from './helpers.js'\n\n/**\n * Reads and drives a DOM document from a realm that can reach it, without trusted input.\n *\n * @remarks\n * The view follows the window of the document it was given, so after that window navigates it\n * drives the window's next document. A reading records the view's navigation epoch, and reports\n * stale after the epoch advances. The epoch advances on the Navigation API's `navigatesuccess`\n * where the window has that API, on `popstate` and `hashchange` where it does not, on `pagehide`,\n * and when the window's document changes. A `pushState` in a window without the Navigation API\n * fires none of those events, so a reading there stays current across it. A cross-document\n * navigation also clears every element reference. `destroy()` releases the listeners and every\n * reference, and fails every pending wait with a `BrowserError` coded\n * `BROWSER_DOCUMENT_DESTROYED`; after it, `title()`, `read()`, `wait()`, and the element manager's\n * `outline()`, `find()`, and `wait()` reject with that error, and a second `destroy()` does\n * nothing more. `trusted` is `false`: no action grants user activation, and\n * every event the view's actions dispatch themselves carries `isTrusted` `false`. The `submit`\n * event that `requestSubmit()` fires during a `submit` is generated by the browser and carries\n * `isTrusted` `true`.\n *\n * @example\n * ```ts\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * const reading = await view.read()\n * reading.text().text\n * ```\n */\nexport class BrowserDOMView implements BrowserDOMViewInterface {\n\treadonly #window: Window\n\treadonly #elements: BrowserDOMElementManager\n\treadonly #release = new AbortController()\n\treadonly #navigateHandler = this.#navigate.bind(this)\n\t#document: Document\n\t#epoch = 0\n\t#listeners = new AbortController()\n\n\tconstructor(options: BrowserDOMViewOptions) {\n\t\tconst document = options.document\n\t\tif (!isBrowserDocument(document) || document.defaultView === null) {\n\t\t\tthrow new BrowserError(\n\t\t\t\t'Browser DOM view requires a document attached to a window',\n\t\t\t\t'BROWSER_DOCUMENT',\n\t\t\t)\n\t\t}\n\t\tif (document === globalThis.document && options.own !== true) {\n\t\t\tthrow new BrowserError(\n\t\t\t\t'Browser DOM view drives globalThis.document only with own: true, because an action that navigates the realm it runs in cannot return',\n\t\t\t\t'BROWSER_DOCUMENT_OWN',\n\t\t\t)\n\t\t}\n\t\tthis.#window = document.defaultView\n\t\tthis.#document = document\n\t\tthis.#elements = new BrowserDOMElementManager({\n\t\t\tdocument: this.#current.bind(this),\n\t\t\tnavigation: this.#navigation.bind(this),\n\t\t\tsignal: this.#release.signal,\n\t\t})\n\t\tthis.#listen()\n\t}\n\n\tget url(): string {\n\t\treturn this.#current().URL\n\t}\n\n\tget trusted(): boolean {\n\t\treturn false\n\t}\n\n\tget elements(): BrowserElementManagerInterface<BrowserDOMElementInterface> {\n\t\treturn this.#elements\n\t}\n\n\tasync title(options?: BrowserCallOptions): Promise<string> {\n\t\tthis.#release.signal.throwIfAborted()\n\t\toptions?.signal?.throwIfAborted()\n\t\treturn this.#current().title\n\t}\n\n\tasync read(options?: BrowserCallOptions): Promise<BrowserReadingInterface> {\n\t\tthis.#release.signal.throwIfAborted()\n\t\toptions?.signal?.throwIfAborted()\n\t\treturn createBrowserReading({\n\t\t\t...readBrowserCapture(this.#current().documentElement),\n\t\t\tnavigation: this.#navigation.bind(this),\n\t\t})\n\t}\n\n\tasync wait(text: string, options?: BrowserWaitOptions): Promise<void> {\n\t\tthis.#release.signal.throwIfAborted()\n\t\tconst start = performance.now()\n\t\tconst timeout = options?.timeout ?? BROWSER_DOCUMENT_TIMEOUT_MS\n\t\tvalidateBrowserTimeout(timeout)\n\t\tconst document = this.#current()\n\t\tawait new BrowserDOMWait({\n\t\t\troots: collectBrowserRoots.bind(undefined, document),\n\t\t\tcheck: this.#contains.bind(this, document, text, options?.absent === true),\n\t\t\ttimeout,\n\t\t\tstart,\n\t\t\tsignal:\n\t\t\t\toptions?.signal === undefined\n\t\t\t\t\t? this.#release.signal\n\t\t\t\t\t: AbortSignal.any([options.signal, this.#release.signal]),\n\t\t\tsubject: 'Browser text wait',\n\t\t}).execute()\n\t}\n\n\tdestroy(): void {\n\t\tthis.#release.abort(\n\t\t\tnew BrowserError('Browser DOM view was destroyed', 'BROWSER_DOCUMENT_DESTROYED'),\n\t\t)\n\t\tthis.#listeners.abort()\n\t\tthis.#elements.clear()\n\t}\n\n\t// Returns the window's document, first moving the view onto it after a document change.\n\t#current(): Document {\n\t\tconst document = this.#window.document\n\t\tif (document !== this.#document && !this.#release.signal.aborted) {\n\t\t\tthis.#document = document\n\t\t\tthis.#navigate()\n\t\t\tthis.#listen()\n\t\t}\n\t\treturn this.#document\n\t}\n\n\t#navigation(): number {\n\t\tthis.#current()\n\t\treturn this.#epoch\n\t}\n\n\t#navigate(event?: Event): void {\n\t\tthis.#epoch += 1\n\t\tif (event === undefined || event.type === 'pagehide') this.#elements.clear()\n\t}\n\n\t#contains(document: Document, text: string, absent: boolean): true | undefined {\n\t\treturn (document.body?.innerText ?? '').includes(text) !== absent ? true : undefined\n\t}\n\n\t// Subscribes to the navigation events of the window's current document.\n\t#listen(): void {\n\t\tthis.#listeners.abort()\n\t\tthis.#listeners = new AbortController()\n\t\tlistenBrowserNavigation(this.#window, this.#navigateHandler, this.#listeners.signal)\n\t}\n}\n","import type { CDPTransportEventMap, CDPTransportInterface } from '@src/core'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { SocketCDPTransportOptions } from '../types.js'\nimport { attempt, isString } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { BROWSER_DEFAULT_TIMEOUT_MS, BrowserConnectionError, BrowserTransition } from '@src/core'\n\n/**\n * Provides a raw CDP text transport over the browser's native `WebSocket`.\n *\n * @remarks\n * `start()` resolves on the socket's `open` event and rejects with a `BrowserConnectionError`\n * carrying `url` for a URL whose scheme is not `ws:` or `wss:`, for a URL the `WebSocket`\n * constructor refuses (one with a fragment), for a socket that fails or closes before it opens,\n * and at the `timeout` deadline. Concurrent and repeated `start()` and `close()`\n * calls share their active transition, and a later `start()` opens a fresh socket after the\n * prior one closes. A close the remote end initiates emits `close`. The driven Chromium must\n * allow the caller's origin through `--remote-allow-origins`.\n *\n * @example\n * ```ts\n * const transport = new SocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' })\n * await transport.start()\n * await transport.close()\n * ```\n */\nexport class SocketCDPTransport implements CDPTransportInterface {\n\treadonly #emitter: Emitter<CDPTransportEventMap>\n\treadonly #url: string\n\treadonly #timeout: number\n\treadonly #starting = new BrowserTransition()\n\treadonly #closing = new BrowserTransition()\n\t#socket: WebSocket | undefined\n\t#opening: PromiseWithResolvers<void> | undefined\n\n\tconstructor(options: SocketCDPTransportOptions) {\n\t\tthis.#emitter = new Emitter({\n\t\t\t...(options.on !== undefined ? { on: options.on } : {}),\n\t\t\t...(options.error !== undefined ? { error: options.error } : {}),\n\t\t})\n\t\tthis.#url = options.url\n\t\tthis.#timeout = options.timeout ?? BROWSER_DEFAULT_TIMEOUT_MS\n\t}\n\n\tget emitter(): EmitterInterface<CDPTransportEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tasync start(): Promise<void> {\n\t\tconst closing = this.#closing.pending\n\t\tif (closing !== undefined) await closing\n\t\tif (this.#socket?.readyState === WebSocket.OPEN) return\n\t\tconst active = this.#starting.pending\n\t\tif (active !== undefined) {\n\t\t\tawait active\n\t\t\treturn\n\t\t}\n\t\tawait this.#starting.execute(this.#start.bind(this))\n\t}\n\n\tasync send(data: string): Promise<void> {\n\t\tconst socket = this.#socket\n\t\tif (socket === undefined || socket.readyState !== WebSocket.OPEN) {\n\t\t\tthrow new BrowserConnectionError('Socket CDP transport is not open', { url: this.#url })\n\t\t}\n\t\tsocket.send(data)\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this.#closing.execute(this.#close.bind(this))\n\t}\n\n\tasync #start(): Promise<void> {\n\t\tconst parsed = attempt(() => new URL(this.#url))\n\t\tif (!parsed.success) {\n\t\t\tthrow new BrowserConnectionError(`Socket CDP URL is invalid: ${this.#url}`, {\n\t\t\t\turl: this.#url,\n\t\t\t\terror: parsed.error,\n\t\t\t})\n\t\t}\n\t\tif (parsed.value.protocol !== 'ws:' && parsed.value.protocol !== 'wss:') {\n\t\t\tthrow new BrowserConnectionError(\n\t\t\t\t`Socket CDP connection requires a ws: or wss: URL: ${this.#url}`,\n\t\t\t\t{ url: this.#url },\n\t\t\t)\n\t\t}\n\t\tconst created = attempt(() => new WebSocket(this.#url))\n\t\tif (!created.success) {\n\t\t\tthrow new BrowserConnectionError(`Socket CDP connection to ${this.#url} could not open`, {\n\t\t\t\turl: this.#url,\n\t\t\t\terror: created.error,\n\t\t\t})\n\t\t}\n\t\tconst socket = created.value\n\t\tthis.#socket = socket\n\t\tconst opened = Promise.withResolvers<void>()\n\t\tthis.#opening = opened\n\t\tconst release = new AbortController()\n\t\tconst options = { signal: release.signal }\n\t\tsocket.addEventListener('open', () => opened.resolve(), options)\n\t\tsocket.addEventListener('error', () => opened.reject(this.#refuse('failed')), options)\n\t\tsocket.addEventListener(\n\t\t\t'close',\n\t\t\t() => opened.reject(this.#refuse('closed before it opened')),\n\t\t\toptions,\n\t\t)\n\t\tconst timer = setTimeout(() => {\n\t\t\topened.reject(this.#refuse(`timed out after ${this.#timeout}ms`))\n\t\t}, this.#timeout)\n\t\ttry {\n\t\t\tawait opened.promise\n\t\t} catch (error) {\n\t\t\tif (this.#socket === socket) this.#socket = undefined\n\t\t\tsocket.close()\n\t\t\tthrow error\n\t\t} finally {\n\t\t\tif (this.#opening === opened) this.#opening = undefined\n\t\t\tclearTimeout(timer)\n\t\t\trelease.abort()\n\t\t}\n\t\tthis.#bind(socket)\n\t}\n\n\tasync #close(): Promise<void> {\n\t\tthis.#opening?.reject(this.#refuse('was closed before it finished connecting'))\n\t\tconst socket = this.#socket\n\t\tthis.#socket = undefined\n\t\tif (socket === undefined || socket.readyState === WebSocket.CLOSED) {\n\t\t\tawait this.#starting.pending?.catch(() => undefined)\n\t\t\treturn\n\t\t}\n\t\tconst closed = Promise.withResolvers<void>()\n\t\tsocket.addEventListener('close', () => closed.resolve(), { once: true })\n\t\tsocket.close()\n\t\tawait this.#starting.pending?.catch(() => undefined)\n\t\tawait closed.promise\n\t}\n\n\t#bind(socket: WebSocket): void {\n\t\tsocket.binaryType = 'arraybuffer'\n\t\tsocket.addEventListener('message', (event) => {\n\t\t\tconst data: unknown = event.data\n\t\t\tif (isString(data)) this.#emitter.emit('message', data)\n\t\t\telse if (data instanceof ArrayBuffer)\n\t\t\t\tthis.#emitter.emit('message', new TextDecoder().decode(data))\n\t\t})\n\t\tsocket.addEventListener('close', () => {\n\t\t\tif (this.#socket === socket) this.#socket = undefined\n\t\t\tthis.#emitter.emit('close')\n\t\t})\n\t\tsocket.addEventListener('error', () => {\n\t\t\tthis.#emitter.emit('error', this.#refuse('failed'))\n\t\t})\n\t}\n\n\t#refuse(reason: string): BrowserConnectionError {\n\t\treturn new BrowserConnectionError(`Socket CDP connection to ${this.#url} ${reason}`, {\n\t\t\turl: this.#url,\n\t\t})\n\t}\n}\n","import type { BrowserToolsetInterface, CDPTransportInterface } from '@src/core'\nimport type {\n\tBrowserDOMViewOptions,\n\tBrowserDocumentToolsetOptions,\n\tBrowserDOMViewInterface,\n\tSocketCDPTransportOptions,\n} from './types.js'\nimport { BrowserToolset } from '@src/core'\nimport { BrowserDOMView } from './BrowserDOMView.js'\nimport { SocketCDPTransport } from './transports/SocketCDPTransport.js'\n\n/**\n * Creates a view that reads and drives a DOM document without trusted input.\n *\n * @param options - The driven document, and `own` to admit the realm's own document\n * @returns A {@link BrowserDOMViewInterface} over the document's window\n * @throws Thrown when `document` is not a document attached to a window, with the code\n * `BROWSER_DOCUMENT`, and when it is `globalThis.document` without `own: true`, with the code\n * `BROWSER_DOCUMENT_OWN`.\n *\n * @example\n * ```ts\n * const frame = document.createElement('iframe')\n * document.body.append(frame)\n * const view = createBrowserDOMView({ document: frame.contentDocument })\n * await view.elements.outline() // { text: 'page \"\" about:blank\\n(0 of 0 elements)', … }\n * ```\n */\nexport function createBrowserDOMView(options: BrowserDOMViewOptions): BrowserDOMViewInterface {\n\treturn new BrowserDOMView(options)\n}\n\n/**\n * Creates a `BrowserToolsetInterface` that publishes the five view tools over a DOM document and\n * adopts a source's page tools beside them.\n *\n * @remarks\n * The toolset runs over a view {@link createBrowserDOMView} creates for `document`, so it\n * advertises `look`, `read`, `plain`, `click`, `type`, and `wait`, and a click or type receipt ends with\n * ` (untrusted event)`. `source` supplies page tools, which the toolset adopts during `start()`\n * and again on every `change`; `toolset.native` never includes them, so publishing it to a\n * registry leaves that registry's own tools alone. The view belongs to the toolset: `destroy()`\n * removes the toolset's tools, then destroys the view, which releases its listeners and fails\n * its pending waits, and a construction that throws destroys the view before it rethrows.\n * `journeys` adds `record`, `save`, `journeys`, `edit`, and `replay` at construction; a replay\n * runs the steps the document placement executes.\n *\n * @param options - The driven document, `own`, the page-tool source, the manager, the bound, the\n * journey stores, and the emitter hooks\n * @returns A {@link BrowserToolsetInterface} whose `view` drives the document\n * @throws Thrown when `document` is not a document attached to a window, with the code\n * `BROWSER_DOCUMENT`, when it is `globalThis.document` without `own: true`, with the code\n * `BROWSER_DOCUMENT_OWN`, and when `limit` is not a positive integer.\n *\n * @example\n * ```ts\n * const toolset = createDocumentToolset({ document: frame.contentDocument, source: bridge })\n * await toolset.start()\n * await toolset.tools.execute({ id: '1', name: 'look', arguments: { search: 'form' } })\n * ```\n */\nexport function createDocumentToolset(\n\toptions: BrowserDocumentToolsetOptions,\n): BrowserToolsetInterface {\n\tconst view = createBrowserDOMView({\n\t\tdocument: options.document,\n\t\t...(options.own === undefined ? {} : { own: options.own }),\n\t})\n\ttry {\n\t\treturn new BrowserToolset(view, {\n\t\t\t...(options.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options.error === undefined ? {} : { error: options.error }),\n\t\t\t...(options.tools === undefined ? {} : { tools: options.tools }),\n\t\t\t...(options.source === undefined ? {} : { source: options.source }),\n\t\t\t...(options.limit === undefined ? {} : { limit: options.limit }),\n\t\t\t...(options.journeys === undefined ? {} : { journeys: options.journeys }),\n\t\t\trelease: view.destroy.bind(view),\n\t\t})\n\t} catch (error) {\n\t\tview.destroy()\n\t\tthrow error\n\t}\n}\n\n/**\n * Creates a CDP transport over the browser's native `WebSocket`.\n *\n * @param options - The CDP WebSocket debugger URL, the opening deadline, and emitter hooks\n * @returns A {@link CDPTransportInterface} a `CDPClient` sends and receives frames over\n *\n * @example\n * ```ts\n * const client = createCDPClient({\n * \ttransport: createSocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' }),\n * })\n * await client.connect()\n * ```\n */\nexport function createSocketCDPTransport(\n\toptions: SocketCDPTransportOptions,\n): CDPTransportInterface {\n\treturn new SocketCDPTransport(options)\n}\n"],"mappings":"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"}