@miragon/modeler-shell 0.1.0 → 0.2.1

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.
Files changed (98) hide show
  1. package/API.md +1051 -84
  2. package/README.md +162 -31
  3. package/dist/appearance-BBaM_4bD.d.ts +323 -0
  4. package/dist/appearance-XX3JC3pI.d.cts +323 -0
  5. package/dist/{chunk-6LQOFACK.js → chunk-A4YGKH4Y.js} +1252 -31
  6. package/dist/chunk-A4YGKH4Y.js.map +1 -0
  7. package/dist/{chunk-RJRFR6N3.js → chunk-KYDG5DMX.js} +2 -2
  8. package/dist/{chunk-5JSZ4VGA.js → chunk-OADW3GPA.js} +240 -6
  9. package/dist/chunk-OADW3GPA.js.map +1 -0
  10. package/dist/core.cjs +260 -6
  11. package/dist/core.cjs.map +1 -1
  12. package/dist/core.d.cts +81 -6
  13. package/dist/core.d.ts +81 -6
  14. package/dist/core.js +43 -3
  15. package/dist/diagram-js.cjs +34 -2
  16. package/dist/diagram-js.cjs.map +1 -1
  17. package/dist/diagram-js.d.cts +10 -3
  18. package/dist/diagram-js.d.ts +10 -3
  19. package/dist/diagram-js.js +14 -2
  20. package/dist/diagram-js.js.map +1 -1
  21. package/dist/index.cjs +1658 -196
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +18 -9
  24. package/dist/index.d.ts +18 -9
  25. package/dist/index.js +44 -4
  26. package/dist/shell.css +692 -3
  27. package/dist/testing-vscode-stub.js +2 -2
  28. package/dist/testing.cjs +2849 -550
  29. package/dist/testing.cjs.map +1 -1
  30. package/dist/testing.d.cts +75 -9
  31. package/dist/testing.d.ts +75 -9
  32. package/dist/testing.js +2744 -558
  33. package/dist/testing.js.map +1 -1
  34. package/dist/toasts-Bp0REqdq.d.cts +142 -0
  35. package/dist/toasts-Bp0REqdq.d.ts +142 -0
  36. package/dist/{types-OuFlqZp0.d.cts → types-CnRrINRs.d.cts} +170 -9
  37. package/dist/{types-DnZn9CPw.d.ts → types-PuDZczzy.d.ts} +170 -9
  38. package/dist/vscode-extension.js +2 -2
  39. package/dist/vscode-webview.cjs +1546 -178
  40. package/dist/vscode-webview.cjs.map +1 -1
  41. package/dist/vscode-webview.d.cts +6 -4
  42. package/dist/vscode-webview.d.ts +6 -4
  43. package/dist/vscode-webview.js +11 -2
  44. package/dist/vscode-webview.js.map +1 -1
  45. package/package.json +2 -2
  46. package/src/core/feedback/appearance.ts +141 -0
  47. package/src/core/feedback/problems.ts +23 -0
  48. package/src/core/feedback/toasts.ts +118 -0
  49. package/src/core/fit.ts +18 -3
  50. package/src/core/index.ts +43 -0
  51. package/src/core/keymap.ts +20 -0
  52. package/src/core/messages.ts +71 -0
  53. package/src/core/types.ts +24 -2
  54. package/src/core/web-chrome/bottom-row.ts +37 -0
  55. package/src/core/web-chrome/drop.ts +78 -0
  56. package/src/core/web-chrome/top-row.ts +66 -0
  57. package/src/diagram-js/service.ts +4 -1
  58. package/src/diagram-js/viewport.ts +19 -0
  59. package/src/dom/buttons.css +124 -0
  60. package/src/dom/feedback/appearance.ts +184 -0
  61. package/src/dom/feedback/feedback.css +435 -0
  62. package/src/dom/feedback/problems-popover.ts +287 -0
  63. package/src/dom/feedback/toasts.ts +431 -0
  64. package/src/dom/index.ts +13 -0
  65. package/src/dom/keys.ts +8 -0
  66. package/src/dom/menu.ts +28 -17
  67. package/src/dom/mount.ts +290 -20
  68. package/src/dom/problems.ts +5 -4
  69. package/src/dom/shell-dom.css +7 -4
  70. package/src/dom/tooltip.ts +10 -0
  71. package/src/dom/types.ts +188 -6
  72. package/src/dom/web/drop-zone.ts +181 -0
  73. package/src/dom/web/empty-state.ts +144 -0
  74. package/src/dom/web/legal.ts +75 -0
  75. package/src/dom/web/menu-groups.ts +69 -0
  76. package/src/dom/web/primary.ts +124 -0
  77. package/src/dom/web/web.css +386 -0
  78. package/src/shell.css +3 -0
  79. package/src/testing/case-tools.ts +164 -0
  80. package/src/testing/cases.ts +209 -144
  81. package/src/testing/checks.ts +51 -15
  82. package/src/testing/facts.ts +56 -2
  83. package/src/testing/geometry.ts +206 -26
  84. package/src/testing/harness.ts +56 -7
  85. package/src/testing/index.ts +4 -0
  86. package/src/testing/page-tools.ts +24 -1
  87. package/src/testing/page.ts +10 -0
  88. package/src/testing/web-cases.ts +913 -0
  89. package/src/testing/web-checks.ts +1049 -0
  90. package/src/testing/web-facts.ts +713 -0
  91. package/src/vscode/webview/mount.ts +13 -1
  92. package/dist/chunk-5JSZ4VGA.js.map +0 -1
  93. package/dist/chunk-6LQOFACK.js.map +0 -1
  94. package/dist/keymap-CObQE6q6.d.cts +0 -151
  95. package/dist/keymap-DORzHnK-.d.ts +0 -151
  96. package/dist/types-B6NfkiUG.d.cts +0 -66
  97. package/dist/types-B6NfkiUG.d.ts +0 -66
  98. /package/dist/{chunk-RJRFR6N3.js.map → chunk-KYDG5DMX.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/page-tools.ts","../src/testing/geometry.ts","../src/testing/facts.ts","../src/testing/checks.ts","../src/testing/cases.ts","../src/testing/harness.ts"],"sourcesContent":["import type { Size } from \"../core/index.js\";\nimport type { PageLike } from \"./page.js\";\n\n/*\n * Everything here that is handed to `page.evaluate` runs in the browser: Playwright serializes the\n * function source, so these functions must not reference anything outside their own body. They\n * only collect facts; every judgement happens in Node (`checks.ts`, `geometry.ts`), where it is\n * unit-tested. `installPageTools` puts the shared helpers and the recorders under one page global.\n */\n\n/** A box relative to the shell root's padding box (where `position: absolute` islands anchor). */\nexport interface RelativeBox {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/** A `keydown` that reached the kit's listener on `window` (bubble phase), where VS Code's host page listens. */\nexport interface RecordedKey {\n key: string;\n code: string;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n defaultPrevented: boolean;\n}\n\n/** The facts the kit reads about one element. */\nexport interface ElementFacts {\n tag: string;\n description: string;\n attributes: Record<string, string>;\n text: string;\n visible: boolean;\n /** The native `disabled` property (a disabled `<button>` loses focus, `aria-disabled` keeps it). */\n disabled: boolean;\n}\n\n/** The helpers and recorders `installPageTools` keeps under the page global. */\nexport interface PageTools {\n /** `keydown`s that reached `window`, where VS Code's host page listens. */\n keys: RecordedKey[];\n /**\n * `keydown`s seen on `document` after every listener registered before the kit's (the shell's,\n * the modeler's), so `defaultPrevented` is final even where the shell stops the key.\n */\n documentKeys: RecordedKey[];\n errors: string[];\n injected: Element[];\n cleanups: Array<() => void>;\n armedRoot?: HTMLElement;\n frame(): Promise<void>;\n settle(): Promise<void>;\n visible(element: Element): boolean;\n container(root: HTMLElement): Size;\n box(element: Element, root: HTMLElement): RelativeBox;\n describe(element: Element): string;\n facts(element: Element): ElementFacts;\n}\n\nexport type ToolWindow = Window & { __modelerShellConformance?: PageTools };\n\n/** Installs the in-page helpers once per document (idempotent; a navigation drops them). */\nexport const installPageTools = (_: null): void => {\n const scope = window as ToolWindow;\n if (scope.__modelerShellConformance) return;\n const modifierKeys = [\"Control\", \"Meta\", \"Shift\", \"Alt\", \"AltGraph\", \"CapsLock\", \"Fn\"];\n const frame = () => new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n const borders = (element: Element) => {\n const style = getComputedStyle(element);\n return {\n left: parseFloat(style.borderLeftWidth) || 0,\n top: parseFloat(style.borderTopWidth) || 0,\n right: parseFloat(style.borderRightWidth) || 0,\n bottom: parseFloat(style.borderBottomWidth) || 0,\n };\n };\n const visible = (element: Element): boolean => {\n if (!element.isConnected) return false;\n if (typeof element.checkVisibility === \"function\") {\n if (!element.checkVisibility({ visibilityProperty: true })) return false;\n } else {\n if (element.closest(\"[hidden]\")) return false;\n for (let node: Element | null = element; node; node = node.parentElement) {\n if (getComputedStyle(node).display === \"none\") return false;\n }\n if (getComputedStyle(element).visibility === \"hidden\") return false;\n }\n const rect = element.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n };\n const describe = (element: Element): string => {\n const id = element.id ? `#${element.id}` : \"\";\n const classes = [...element.classList]\n .slice(0, 3)\n .map((name) => `.${name}`)\n .join(\"\");\n const chrome = element.getAttribute(\"data-chrome\");\n return `${element.tagName.toLowerCase()}${id}${classes}${chrome ? `[data-chrome=\"${chrome}\"]` : \"\"}`;\n };\n const tools: PageTools = {\n keys: [],\n documentKeys: [],\n errors: [],\n injected: [],\n cleanups: [],\n frame,\n async settle() {\n await frame();\n await frame();\n const running =\n typeof document.getAnimations === \"function\"\n ? document.getAnimations().filter((animation) => {\n const end = animation.effect?.getComputedTiming().endTime;\n return animation.playState === \"running\" && typeof end === \"number\" && Number.isFinite(end);\n })\n : [];\n if (running.length > 0) {\n await Promise.race([\n Promise.allSettled(running.map((animation) => animation.finished)),\n new Promise((resolve) => setTimeout(resolve, 2000)),\n ]);\n }\n await frame();\n },\n visible,\n container(root) {\n const rect = root.getBoundingClientRect();\n const border = borders(root);\n return {\n width: rect.width - border.left - border.right,\n height: rect.height - border.top - border.bottom,\n };\n },\n box(element, root) {\n const rect = element.getBoundingClientRect();\n const origin = root.getBoundingClientRect();\n const border = borders(root);\n return {\n left: rect.left - origin.left - border.left,\n top: rect.top - origin.top - border.top,\n width: rect.width,\n height: rect.height,\n };\n },\n describe,\n facts(element) {\n const attributes: Record<string, string> = {};\n for (const name of element.getAttributeNames()) attributes[name] = element.getAttribute(name) ?? \"\";\n return {\n tag: element.tagName.toLowerCase(),\n description: describe(element),\n attributes,\n text: (element.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n visible: visible(element),\n disabled: Boolean((element as HTMLButtonElement).disabled),\n };\n },\n };\n const recorder = (into: RecordedKey[]) => (event: KeyboardEvent) => {\n if (modifierKeys.includes(event.key)) return;\n into.push({\n key: event.key,\n code: event.code,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n defaultPrevented: event.defaultPrevented,\n });\n };\n document.addEventListener(\"keydown\", recorder(tools.documentKeys));\n window.addEventListener(\"keydown\", recorder(tools.keys));\n window.addEventListener(\"error\", (event) => {\n tools.errors.push(event.message || String(event.error));\n });\n window.addEventListener(\"unhandledrejection\", (event) => {\n tools.errors.push(`unhandled rejection: ${String(event.reason)}`);\n });\n scope.__modelerShellConformance = tools;\n};\n\n/** Runs `pageFunction` in the page after making sure the helpers are installed. */\nexport async function inPage<Arg, Result>(\n page: PageLike,\n pageFunction: (arg: Arg) => Result | Promise<Result>,\n arg: Arg,\n): Promise<Result> {\n await page.evaluate(installPageTools, null);\n return page.evaluate(pageFunction, arg);\n}\n\n/** Two frames plus every finite running animation (pop-ins, slide-ins), capped at 2s. */\nexport const settleInPage = (_: null): Promise<void> =>\n (window as ToolWindow).__modelerShellConformance!.settle();\n\nexport function settle(page: PageLike): Promise<void> {\n return inPage(page, settleInPage, null);\n}\n\n/** The controls the kit hovers, clicks or focuses, found inside the shell root. */\nexport type ChromeTarget =\n | \"menu\"\n | \"palette-entry\"\n | \"palette-tab-stop\"\n | \"zoom-out\"\n | \"zoom-actual\"\n | \"zoom-in\"\n | \"zoom-fit\"\n | \"canvas\";\n\nexport const CHROME_TARGET_SELECTORS: Readonly<Record<ChromeTarget, string>> = {\n menu: '[data-chrome=\"menu\"]',\n \"palette-entry\": '[data-chrome=\"palette\"] [data-action]',\n \"palette-tab-stop\": '[data-chrome=\"palette\"] [data-action][tabindex=\"0\"]',\n \"zoom-out\": '[data-chrome=\"zoom\"] [data-zoom=\"out\"]',\n \"zoom-actual\": '[data-chrome=\"zoom\"] [data-zoom=\"actual\"]',\n \"zoom-in\": '[data-chrome=\"zoom\"] [data-zoom=\"in\"]',\n \"zoom-fit\": '[data-chrome=\"zoom\"] [data-zoom=\"fit\"]',\n canvas: \".djs-container > svg\",\n};\n\nexport interface TargetFacts {\n /** Viewport coordinates of the centre, for `page.mouse`. */\n client: { x: number; y: number };\n box: RelativeBox;\n /** `aria-label`, else the text. */\n label: string;\n}\n\n/** The first visible match of `selector` inside the root; `null` when there is none. */\nexport const targetProbe = ({ root, selector }: { root: string; selector: string }): TargetFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const element = [...rootElement.querySelectorAll(selector)].find((candidate) => tools.visible(candidate));\n if (!element) return null;\n const rect = element.getBoundingClientRect();\n return {\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n box: tools.box(element, rootElement),\n label: (element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n };\n};\n\nexport async function findTarget(\n page: PageLike,\n root: string,\n target: ChromeTarget,\n): Promise<TargetFacts | null> {\n return inPage(page, targetProbe, { root, selector: CHROME_TARGET_SELECTORS[target] });\n}\n\n/** Focuses the first match of `selector` inside the root; the description of the focused element. */\nexport const focusProbe = ({ root, selector }: { root: string; selector: string }): string | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const element = document.querySelector(root)?.querySelector<HTMLElement | SVGElement>(selector);\n if (!element) return null;\n element.focus();\n return document.activeElement === element ? tools.describe(element) : null;\n};\n\nexport async function focusTarget(\n page: PageLike,\n root: string,\n target: ChromeTarget,\n): Promise<string | null> {\n return inPage(page, focusProbe, { root, selector: CHROME_TARGET_SELECTORS[target] });\n}\n\n/** A visible popup with `role` inside the root (the dropdown, the chrome tooltip). */\nexport interface OverlayFacts {\n box: RelativeBox;\n text: string;\n /** How many visible elements carry the role. */\n count: number;\n id: string;\n}\n\nexport const overlayProbe = ({ root, role }: { root: string; role: string }): OverlayFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const shown = [...rootElement.querySelectorAll(`[role=\"${role}\"]`)].filter((element) =>\n tools.visible(element),\n );\n const first = shown[0];\n if (!first) return null;\n return {\n box: tools.box(first, rootElement),\n text: (first.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n count: shown.length,\n id: first.id,\n };\n};\n\nexport async function findOverlay(\n page: PageLike,\n root: string,\n role: \"menu\" | \"tooltip\",\n): Promise<OverlayFacts | null> {\n return inPage(page, overlayProbe, { root, role });\n}\n\nexport interface PressFacts {\n /** The readout as a whole percentage; `null` without a readout. */\n zoom: number | null;\n keys: RecordedKey[];\n documentKeys: RecordedKey[];\n}\n\n/** After a key press: settles, then reads the readout and takes the keys `window` and `document` saw. */\nexport const afterPressProbe = async ({ root }: { root: string }): Promise<PressFacts> => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n await tools.settle();\n const readout = document\n .querySelector(root)\n ?.querySelector('[data-chrome=\"zoom\"] [data-zoom=\"actual\"]')?.textContent;\n const digits = (readout ?? \"\").replace(/[^0-9]/g, \"\");\n return {\n zoom: digits ? Number(digits) : null,\n keys: tools.keys.splice(0),\n documentKeys: tools.documentKeys.splice(0),\n };\n};\n\n/** Drops what `window` saw so far. */\nexport const clearKeysProbe = (_: null): void => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n tools.keys.splice(0);\n tools.documentKeys.splice(0);\n};\n\nexport type InjectedKind = \"input\" | \"textarea\" | \"contenteditable\" | \"modal\" | \"popover\" | \"focus-target\";\n\n/**\n * Adds a stand-in for what modelers render inside the shell (text fields: an input, a textarea, an\n * editable label; a modal dialog, a popover, a plain focus target), inside the root or, once it is\n * gone, the body; focuses it.\n */\nexport const injectProbe = ({ root, kind }: { root: string; kind: InjectedKind }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const parent = document.querySelector(root) ?? tools.armedRoot ?? document.body;\n const host = parent.isConnected ? parent : document.body;\n const element =\n kind === \"input\" || kind === \"textarea\"\n ? document.createElement(kind)\n : (document.createElement(\"div\") as HTMLElement);\n element.setAttribute(\"data-modeler-shell-conformance\", kind);\n element.style.cssText = \"position:absolute;left:0;top:0;width:40px;height:20px;\";\n if (kind === \"modal\" || kind === \"popover\") {\n element.setAttribute(\"role\", \"dialog\");\n element.setAttribute(\"aria-label\", \"Conformance stand-in\");\n if (kind === \"modal\") element.setAttribute(\"aria-modal\", \"true\");\n }\n if (kind === \"contenteditable\") element.setAttribute(\"contenteditable\", \"true\");\n else if (kind !== \"input\" && kind !== \"textarea\") element.tabIndex = -1;\n host.append(element);\n tools.injected.push(element);\n element.focus();\n return document.activeElement === element;\n};\n\nexport const removeInjectedProbe = (_: null): void => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n for (const element of tools.injected.splice(0)) element.remove();\n for (const cleanup of tools.cleanups.splice(0)) cleanup();\n};\n\n/** Makes the canvas `<svg>` handle `key` (`preventDefault`), as a modeler's own canvas binding would. */\nexport const canvasHandlesProbe = ({ root, key }: { root: string; key: string }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const svg = document.querySelector(root)?.querySelector(\".djs-container > svg\");\n if (!svg) return false;\n const listener = (event: Event) => {\n if ((event as KeyboardEvent).key === key) event.preventDefault();\n };\n svg.addEventListener(\"keydown\", listener);\n tools.cleanups.push(() => svg.removeEventListener(\"keydown\", listener));\n return true;\n};\n\n/** Remembers the root right before `destroy` (its class is gone afterwards) and clears the recorders. */\nexport const armCleanupProbe = ({ root }: { root: string }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (rootElement) tools.armedRoot = rootElement;\n tools.errors.splice(0);\n tools.keys.splice(0);\n tools.documentKeys.splice(0);\n return Boolean(rootElement);\n};\n\n/** What the shell left behind after `destroy`. */\nexport interface LeftoverFacts {\n /** Elements (other than `<html>`) with a `cd-shell*` class. */\n classedElements: string[];\n /** `cd-shell*` classes on `<html>`. */\n documentClasses: string[];\n /** Elements still carrying `data-chrome`. */\n chromeElements: string[];\n /** The remembered root's `class` and attributes. */\n rootClasses: string[];\n rootAttributes: string[];\n errors: string[];\n}\n\nexport const leftoverProbe = (_: null): LeftoverFacts => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const ours = (element: Element) => element.hasAttribute(\"data-modeler-shell-conformance\");\n const shellClass = (name: string) => name.startsWith(\"cd-shell\");\n const root = tools.armedRoot;\n return {\n classedElements: [...document.querySelectorAll(\"[class]\")]\n .filter((element) => element !== document.documentElement && !ours(element))\n .filter((element) => [...element.classList].some(shellClass))\n .map((element) => tools.describe(element)),\n documentClasses: [...document.documentElement.classList].filter(shellClass),\n chromeElements: [...document.querySelectorAll(\"[data-chrome]\")].map((element) => tools.describe(element)),\n rootClasses: root ? [...root.classList].filter(shellClass) : [],\n rootAttributes: root ? root.getAttributeNames() : [],\n errors: [...tools.errors],\n };\n};\n\n/** Puts a foreign page's `<html>` in a mode, as a themed host page around an embedded modeler. */\nexport const hostPageModeProbe = ({ theme, kontrast }: { theme: string; kontrast: string | null }): void => {\n const html = document.documentElement;\n html.setAttribute(\"data-cd-theme\", theme);\n if (kontrast) html.setAttribute(\"data-cd-kontrast\", kontrast);\n else html.removeAttribute(\"data-cd-kontrast\");\n};\n","import {\n CHROME_ISLANDS,\n PALETTE_CLEARANCE,\n SHELL,\n type ChromeIsland,\n type Insets,\n type PaletteRow,\n type ShellHost,\n type Size,\n} from \"../core/index.js\";\nimport type { PageLike } from \"./page.js\";\nimport { inPage, type RelativeBox, type ToolWindow } from \"./page-tools.js\";\n\n/** Every island box must match within this many pixels (guide §13.4). */\nexport const GEOMETRY_TOLERANCE_PX = 1;\n\n/**\n * `getBoundingClientRect()` relative to the shell root's padding box, where its absolutely\n * positioned islands anchor (a border on the root, as in a framed foreign page, does not count).\n */\nexport interface IslandBox {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport interface ChromeMeasurement {\n container: Size;\n /** From the root's `data-palette` attribute. */\n paletteRow: PaletteRow;\n /** The visible islands, found by `[data-chrome]`. */\n islands: Partial<Record<ChromeIsland, IslandBox>>;\n /** `[data-legend=\"open\"]`, `[data-inspector=\"open\"]`, `[data-problems=\"shown\"]` on the root. */\n open: { legend: boolean; inspector: boolean; problems: boolean };\n}\n\n/** Constraints of one island; every given field must hold within `GEOMETRY_TOLERANCE_PX`. */\nexport interface ExpectedBox {\n left?: number;\n top?: number;\n right?: number;\n bottom?: number;\n width?: number;\n height?: number;\n /** Horizontal centre relative to the root. */\n centerX?: number;\n}\n\nexport const DEFAULT_ROOT = \".cd-shell\";\n\n/** `[−] [NN%] [+] | [Fit]` with a 56px readout (guide §5.1, §5.8): 1+3+32+2+56+2+32+2+5+2+32+3+1. */\nexport const ZOOM_PANEL_WIDTH = 173;\n\n/** Height of the web app's legal line under the bottom-left stack (guide §5.10). */\nconst LEGAL_LINE = 20;\n\n/** Minimum width of the legend card (guide §5.10). */\nconst LEGEND_MIN_WIDTH = 184;\n\nconst STATUS_MAX_WIDTH = 560;\nconst DROPDOWN_MAX_WIDTH = 320;\nconst TOOLTIP_MAX_WIDTH = 280;\nconst SHEET_MAX_HEIGHT_SHARE = 0.45;\n\ntype MeasureResult = { error: string } | (ChromeMeasurement & { duplicates: string[] });\n\nconst measureProbe = ({ root, islands }: { root: string; islands: readonly string[] }): MeasureResult => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return { error: `no element matches the shell root selector \"${root}\"` };\n const boxes: Partial<Record<string, RelativeBox>> = {};\n const duplicates: string[] = [];\n for (const element of rootElement.querySelectorAll(\"[data-chrome]\")) {\n const name = element.getAttribute(\"data-chrome\") ?? \"\";\n if (!islands.includes(name) || !tools.visible(element)) continue;\n if (boxes[name]) {\n duplicates.push(name);\n continue;\n }\n boxes[name] = tools.box(element, rootElement);\n }\n return {\n container: tools.container(rootElement),\n paletteRow: rootElement.getAttribute(\"data-palette\") === \"second-row\" ? \"second-row\" : \"top\",\n islands: boxes,\n open: {\n legend: rootElement.getAttribute(\"data-legend\") === \"open\",\n inspector: rootElement.getAttribute(\"data-inspector\") === \"open\",\n problems: rootElement.getAttribute(\"data-problems\") === \"shown\",\n },\n duplicates,\n };\n};\n\n/** Measures the islands of the shell under `root` (default `.cd-shell`) in the page. */\nexport async function measureChrome(page: PageLike, root: string = DEFAULT_ROOT): Promise<ChromeMeasurement> {\n const result = await inPage(page, measureProbe, { root, islands: CHROME_ISLANDS });\n if (\"error\" in result) throw new Error(`@miragon/modeler-shell conformance: ${result.error}`);\n if (result.duplicates.length > 0) {\n const names = [...new Set(result.duplicates)].map((name) => `[data-chrome=\"${name}\"]`).join(\", \");\n throw new Error(`@miragon/modeler-shell conformance: more than one visible ${names}`);\n }\n return {\n container: result.container,\n paletteRow: result.paletteRow,\n islands: result.islands,\n open: result.open,\n };\n}\n\n/** Upper and lower limits the guide gives as \"at least\" and \"at most\" (guide §5.4 to §5.15). */\nexport interface BoxLimits {\n minWidth?: number;\n maxWidth?: number;\n maxHeight?: number;\n minLeft?: number;\n minRight?: number;\n minBottom?: number;\n}\n\n/** What the guide expects of the chrome in a measured state. */\nexport interface ChromeExpectations {\n boxes: Partial<Record<ChromeIsland, ExpectedBox>>;\n limits: Partial<Record<ChromeIsland, BoxLimits>>;\n /** Islands that must be visible. */\n required: ChromeIsland[];\n /** Islands that must not be visible, with the rule that hides them. */\n hidden: Partial<Record<ChromeIsland, string>>;\n}\n\nfunction isNarrow(container: Size): boolean {\n return container.width <= SHELL.narrow;\n}\n\nfunction isVeryNarrow(container: Size): boolean {\n return container.width <= SHELL.veryNarrow;\n}\n\n/** The open inspector is a bottom sheet up to `SHELL.narrow` (guide §5.11). */\nfunction sheetOpen(measurement: ChromeMeasurement): boolean {\n return measurement.open.inspector && isNarrow(measurement.container);\n}\n\n/** The anchors and limits of guide §5.2 to §5.15 for `measurement` in `host`. */\nexport function chromeExpectations(measurement: ChromeMeasurement, host: ShellHost): ChromeExpectations {\n const { container, islands, open, paletteRow } = measurement;\n const { edge, gap, row, free, inspectorWidth } = SHELL;\n const web = host === \"web\";\n const secondRow = paletteRow === \"second-row\";\n const sheet = sheetOpen(measurement);\n const sideInspector = open.inspector && !isNarrow(container);\n const boxes: Partial<Record<ChromeIsland, ExpectedBox>> = {};\n const limits: Partial<Record<ChromeIsland, BoxLimits>> = {};\n const hidden: Partial<Record<ChromeIsland, string>> = {};\n const required: ChromeIsland[] = [\"menu\", \"palette\"];\n\n boxes.menu = { left: edge, top: edge, width: row, height: row };\n\n boxes.palette = { top: secondRow ? free : edge, height: row, centerX: container.width / 2 };\n const menu = islands.menu;\n limits.palette = secondRow\n ? { maxWidth: container.width - 2 * edge }\n : menu\n ? { minLeft: menu.left + menu.width + PALETTE_CLEARANCE }\n : {};\n\n if (sheet) {\n const reason = \"hidden while the inspector is a bottom sheet (guide §5.11)\";\n hidden.zoom = reason;\n hidden.problems = reason;\n hidden.legend = reason;\n } else {\n required.push(\"zoom\");\n boxes.zoom = { right: edge, bottom: edge, width: ZOOM_PANEL_WIDTH, height: row };\n const stackBase = web ? edge + LEGAL_LINE + gap : edge;\n if (islands.problems) boxes.problems = { left: edge, bottom: stackBase, height: row };\n if (islands.legend) {\n const besidePill = open.problems ? stackBase + row + gap : stackBase;\n const bottom = isVeryNarrow(container) ? Math.max(besidePill, edge + row + gap) : besidePill;\n boxes.legend = { left: edge, bottom };\n limits.legend = { minWidth: LEGEND_MIN_WIDTH };\n }\n }\n\n if (islands.inspector) {\n if (sheet) {\n boxes.inspector = { left: edge, right: edge, bottom: edge };\n limits.inspector = { maxHeight: container.height * SHEET_MAX_HEIGHT_SHARE };\n } else {\n boxes.inspector = { top: free, right: edge, width: inspectorWidth };\n limits.inspector = { minBottom: free };\n }\n }\n\n if (islands.status) {\n const strip = sideInspector ? container.width - edge - inspectorWidth : container.width;\n boxes.status = { top: secondRow ? free + row + edge : free, centerX: strip / 2 };\n limits.status = {\n minLeft: edge,\n maxWidth: Math.min(STATUS_MAX_WIDTH, container.width - 2 * edge),\n };\n }\n\n if (web) {\n if (islands.primary) boxes.primary = { top: edge, right: edge, height: row };\n } else {\n hidden.primary = \"the top right stays empty in IDE and embedded hosts (guide §5.7)\";\n }\n\n return { boxes, limits, required, hidden };\n}\n\n/** The boxes guide §5.2–§5.12 expects for what was measured (anchors per host and breakpoint). */\nexport function expectedChromeBoxes(\n measurement: ChromeMeasurement,\n host: ShellHost,\n): Partial<Record<ChromeIsland, ExpectedBox>> {\n return chromeExpectations(measurement, host).boxes;\n}\n\nconst round = (value: number): number => Math.round(value * 10) / 10;\n\nfunction sides(box: IslandBox, container: Size): Required<ExpectedBox> {\n return {\n left: box.left,\n top: box.top,\n right: container.width - box.left - box.width,\n bottom: container.height - box.top - box.height,\n width: box.width,\n height: box.height,\n centerX: box.left + box.width / 2,\n };\n}\n\n/** Every field of `expected` that `box` misses by more than `tolerance`, as readable problems. */\nexport function boxMismatches(\n name: string,\n box: IslandBox,\n expected: ExpectedBox,\n container: Size,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const actual = sides(box, container);\n return (Object.keys(expected) as Array<keyof ExpectedBox>).flatMap((field) => {\n const want = expected[field];\n if (want === undefined) return [];\n const have = actual[field];\n return Math.abs(have - want) > tolerance + 1e-6\n ? [`${name}: ${field} is ${round(have)}px, expected ${round(want)}px (±${tolerance}px)`]\n : [];\n });\n}\n\n/** Every limit `box` breaks by more than `tolerance`. */\nexport function limitViolations(\n name: string,\n box: IslandBox,\n limits: BoxLimits,\n container: Size,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const actual = sides(box, container);\n const problems: string[] = [];\n const atLeast = (field: string, have: number, limit: number | undefined) => {\n if (limit !== undefined && have < limit - tolerance - 1e-6) {\n problems.push(`${name}: ${field} is ${round(have)}px, at least ${round(limit)}px expected`);\n }\n };\n const atMost = (field: string, have: number, limit: number | undefined) => {\n if (limit !== undefined && have > limit + tolerance + 1e-6) {\n problems.push(`${name}: ${field} is ${round(have)}px, at most ${round(limit)}px expected`);\n }\n };\n atLeast(\"width\", actual.width, limits.minWidth);\n atMost(\"width\", actual.width, limits.maxWidth);\n atMost(\"height\", actual.height, limits.maxHeight);\n atLeast(\"left\", actual.left, limits.minLeft);\n atLeast(\"right\", actual.right, limits.minRight);\n atLeast(\"bottom\", actual.bottom, limits.minBottom);\n return problems;\n}\n\n/**\n * Every deviation of a measured state from guide §5.2 to §5.15: missing and unexpected islands,\n * boxes and limits, the palette row decision and the root's state attributes.\n */\nexport function geometryProblems(\n measurement: ChromeMeasurement,\n host: ShellHost,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const { container, islands, open, paletteRow } = measurement;\n const expectations = chromeExpectations(measurement, host);\n const problems: string[] = [];\n const sheet = sheetOpen(measurement);\n\n for (const name of expectations.required) {\n if (!islands[name]) problems.push(`${name}: [data-chrome=\"${name}\"] is missing or not visible`);\n }\n for (const name of CHROME_ISLANDS) {\n const box = islands[name];\n if (!box) continue;\n const expected = expectations.boxes[name];\n if (!expected) {\n const reason = expectations.hidden[name] ?? \"no anchor of the guide applies\";\n problems.push(`${name}: visible, but ${reason}`);\n continue;\n }\n problems.push(...boxMismatches(name, box, expected, container, tolerance));\n const limits = expectations.limits[name];\n if (limits) problems.push(...limitViolations(name, box, limits, container, tolerance));\n }\n\n if (isNarrow(container) && paletteRow !== \"second-row\") {\n problems.push(\n `palette: data-palette=\"${paletteRow}\" in a ${round(container.width)}px wide container; up to ${SHELL.narrow}px it is \"second-row\" (guide §5.15)`,\n );\n }\n const palette = islands.palette;\n const menu = islands.menu;\n if (paletteRow === \"second-row\" && !isNarrow(container) && palette && menu) {\n const clipped = palette.width >= container.width - 2 * SHELL.edge - tolerance;\n const topRowLeft = (container.width - palette.width) / 2;\n if (!clipped && topRowLeft >= menu.left + menu.width + PALETTE_CLEARANCE + tolerance) {\n problems.push(\n `palette: in the second row although the top row keeps ${round(topRowLeft - menu.left - menu.width)}px to the menu trigger (at least ${PALETTE_CLEARANCE}px suffice, guide §5.15)`,\n );\n }\n }\n\n const state = (island: ChromeIsland, flag: boolean, attribute: string, hiddenBySheet: boolean) => {\n const shown = Boolean(islands[island]);\n if (flag && !shown && !hiddenBySheet) {\n problems.push(`${island}: the root carries ${attribute}, but the island is not visible`);\n }\n if (!flag && shown) problems.push(`${island}: visible, but the root lacks ${attribute}`);\n };\n state(\"problems\", open.problems, 'data-problems=\"shown\"', sheet);\n state(\"legend\", open.legend, 'data-legend=\"open\"', sheet);\n state(\"inspector\", open.inspector, 'data-inspector=\"open\"', false);\n\n return problems;\n}\n\n/**\n * The fit insets of guide §5.9 for what was measured, recomputed from the guide's table: top 88\n * (second row 140), sides 24, bottom 64 (web app with the pill 92); right 12 + 288 + 24 with a side\n * inspector; left 12 + legend width + 24 with an open legend in a container wider than 440px; with\n * a bottom sheet the bottom is the distance to its top edge plus 12, and the legend does not count.\n */\nexport function expectedFitInsets(measurement: ChromeMeasurement, host: ShellHost): Insets {\n const { container, islands, open, paletteRow } = measurement;\n const insets: Insets = {\n top: paletteRow === \"second-row\" ? SHELL.fitInsetTopSecondRow : SHELL.fitInsetTop,\n right: SHELL.fitInsetSide,\n bottom: host === \"web\" && open.problems ? SHELL.fitInsetBottomWeb : SHELL.fitInsetBottom,\n left: SHELL.fitInsetSide,\n };\n if (sheetOpen(measurement)) {\n const sheet = islands.inspector;\n insets.bottom = sheet ? container.height - sheet.top + SHELL.edge : SHELL.fitInsetBottom;\n return insets;\n }\n if (open.inspector) insets.right = SHELL.edge + SHELL.inspectorWidth + SHELL.fitInsetSide;\n const legend = islands.legend;\n if (open.legend && legend && legend.width > 0 && container.width > SHELL.veryNarrow) {\n insets.left = SHELL.edge + legend.width + SHELL.fitInsetSide;\n }\n return insets;\n}\n\n/** A rectangle relative to the shell root's padding box, by its edges. */\nexport interface Rectangle {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/**\n * The free rectangle of guide §5.9: the container minus `expectedFitInsets`. Where the insets\n * leave no room on an axis, that axis spans the whole container (as the fit centres there).\n */\nexport function freeRectangle(measurement: ChromeMeasurement, host: ShellHost): Rectangle {\n const { container } = measurement;\n const insets = expectedFitInsets(measurement, host);\n const horizontal = container.width - insets.left - insets.right > 0;\n const vertical = container.height - insets.top - insets.bottom > 0;\n return {\n left: horizontal ? insets.left : 0,\n top: vertical ? insets.top : 0,\n right: horizontal ? container.width - insets.right : container.width,\n bottom: vertical ? container.height - insets.bottom : container.height,\n };\n}\n\n/** Where the dropdown opens (guide §5.4): under the trigger, at least 248px, inside the container. */\nexport function dropdownProblems(\n box: IslandBox,\n container: Size,\n tolerance = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const { edge, gap, row, menuMinWidth } = SHELL;\n return [\n ...boxMismatches(\"dropdown\", box, { top: edge + row + gap, left: edge }, container, tolerance),\n ...limitViolations(\n \"dropdown\",\n box,\n {\n minWidth: menuMinWidth,\n maxWidth: Math.min(DROPDOWN_MAX_WIDTH, container.width - 2 * edge),\n minBottom: edge,\n },\n container,\n tolerance,\n ),\n ];\n}\n\n/** Which island a tooltip belongs to decides its row (guide §5.6). */\nexport type TooltipRow = \"top\" | \"second-row\" | \"bottom\";\n\n/**\n * Where the chrome tooltip of a control stands (guide §5.6): 8px below the top row (`top: 60px`)\n * or the second row (`top: 112px`), 8px above the bottom row (`bottom: 60px`); centred on its\n * control and shifted to keep 12px to the sides.\n */\nexport function tooltipProblems(\n tooltip: IslandBox,\n anchor: IslandBox,\n row: TooltipRow,\n container: Size,\n tolerance = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const { edge, gap, row: rowHeight, free } = SHELL;\n const clamp = (centred: number) =>\n Math.max(edge, Math.min(centred, container.width - edge - tooltip.width));\n const expectedAt = (left: number): ExpectedBox =>\n row === \"bottom\"\n ? { left, bottom: edge + rowHeight + gap }\n : { left, top: (row === \"top\" ? edge : free) + rowHeight + gap };\n let mismatches = boxMismatches(\n \"tooltip\",\n tooltip,\n expectedAt(clamp(anchor.left + anchor.width / 2 - tooltip.width / 2)),\n container,\n tolerance,\n );\n // Guide §5.15 reads \"mittig im Container\" for the second row; until the guide settles whether\n // that means the container or the entry, either centre conforms.\n if (row === \"second-row\" && mismatches.length > 0) {\n const inContainer = boxMismatches(\n \"tooltip\",\n tooltip,\n expectedAt(clamp(container.width / 2 - tooltip.width / 2)),\n container,\n tolerance,\n );\n if (inContainer.length === 0) mismatches = inContainer;\n }\n return [\n ...mismatches,\n ...limitViolations(\n \"tooltip\",\n tooltip,\n { minLeft: edge, minRight: edge, maxWidth: Math.min(TOOLTIP_MAX_WIDTH, container.width - 2 * edge) },\n container,\n tolerance,\n ),\n ];\n}\n","import type { ElementFacts, RelativeBox, ToolWindow } from \"./page-tools.js\";\n\n/*\n * Snapshots the cases judge in Node (`checks.ts`). Each probe runs in the page and must stay\n * self-contained (see page-tools.ts).\n */\n\nexport type ZoomButton = \"out\" | \"actual\" | \"in\" | \"fit\";\n\n/** The chrome parts in the DOM (and tab) order of guide §5.14. */\nexport const DOM_ORDER = [\n \"menu\",\n \"primary\",\n \"palette\",\n \"canvas\",\n \"status\",\n \"hint\",\n \"inspector\",\n \"problems\",\n \"legend\",\n \"zoom\",\n] as const;\n\nexport type OrderedPart = (typeof DOM_ORDER)[number];\n\nexport interface PaletteEntryFacts extends ElementFacts {\n group: string | null;\n}\n\nexport interface AriaFacts {\n platform: \"mac\" | \"other\";\n documentLang: string;\n rootLang: string | null;\n trigger: ElementFacts | null;\n /** The element the trigger's `aria-controls` names. */\n controlled: ElementFacts | null;\n palette: ElementFacts | null;\n toolbar: ElementFacts | null;\n /** The focusable canvas `<svg>` (`.djs-container > svg`). */\n canvas: ElementFacts | null;\n entries: PaletteEntryFacts[];\n zoom: ElementFacts | null;\n zoomButtons: Partial<Record<ZoomButton, ElementFacts>>;\n /** The parts that exist, in DOM order. */\n order: OrderedPart[];\n /** Elements inside the root with a positive `tabindex`. */\n positiveTabindex: string[];\n /** Chrome controls with a native `title` tooltip. */\n titled: string[];\n problems: ElementFacts | null;\n status: ElementFacts | null;\n legend: ElementFacts | null;\n /** Text of the legend's `aria-labelledby` targets. */\n legendTitle: string | null;\n legendClose: ElementFacts | null;\n inspector: ElementFacts | null;\n}\n\nexport const ariaProbe = ({ root }: { root: string }): AriaFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const find = (selector: string) => rootElement.querySelector(selector);\n const factsOf = (element: Element | null | undefined) => (element ? tools.facts(element) : null);\n const navigatorLike = navigator as Navigator & { userAgentData?: { platform?: string } };\n const trigger = find('[data-chrome=\"menu\"]');\n const controlsId = trigger?.getAttribute(\"aria-controls\");\n const palette = find('[data-chrome=\"palette\"]');\n const toolbar =\n palette?.querySelector('[role=\"toolbar\"]') ?? palette?.querySelector(\".djs-palette-entries\");\n const zoom = find('[data-chrome=\"zoom\"]');\n const zoomButtons: Partial<Record<ZoomButton, ElementFacts>> = {};\n for (const name of [\"out\", \"actual\", \"in\", \"fit\"] as const) {\n const button = zoom?.querySelector(`[data-zoom=\"${name}\"]`);\n if (button) zoomButtons[name] = tools.facts(button);\n }\n const legend = find('[data-chrome=\"legend\"]');\n const labelledBy = legend?.getAttribute(\"aria-labelledby\");\n const parts: Array<[string, Element | null]> = [\n [\"menu\", trigger],\n [\"primary\", find('[data-chrome=\"primary\"]')],\n [\"palette\", palette],\n [\"canvas\", find(\".djs-container > svg\")],\n [\"status\", find('[data-chrome=\"status\"]')],\n [\"hint\", find(\".cd-shell-hint\")],\n [\"inspector\", find('[data-chrome=\"inspector\"]')],\n [\"problems\", find('[data-chrome=\"problems\"]')],\n [\"legend\", legend],\n [\"zoom\", zoom],\n ];\n const present = parts.filter((part): part is [string, Element] => part[1] !== null);\n present.sort(([, a], [, b]) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n const titledSelector = [\n '[data-chrome=\"menu\"][title]',\n '[data-chrome=\"palette\"] [data-action][title]',\n '[data-chrome=\"zoom\"] [title]',\n '[data-chrome=\"problems\"][title]',\n ].join(\", \");\n return {\n platform: /mac/i.test(navigatorLike.userAgentData?.platform ?? navigatorLike.platform ?? \"\")\n ? \"mac\"\n : \"other\",\n documentLang: document.documentElement.lang,\n rootLang: rootElement.getAttribute(\"lang\"),\n trigger: factsOf(trigger),\n controlled: factsOf(controlsId ? document.getElementById(controlsId) : null),\n palette: factsOf(palette),\n toolbar: factsOf(toolbar),\n canvas: factsOf(find(\".djs-container > svg\")),\n entries: [...(palette?.querySelectorAll(\"[data-action]\") ?? [])].map((entry) => ({\n ...tools.facts(entry),\n group: entry.closest(\"[data-group]\")?.getAttribute(\"data-group\") ?? null,\n })),\n zoom: factsOf(zoom),\n zoomButtons,\n order: present.map(([name]) => name) as OrderedPart[],\n positiveTabindex: [...rootElement.querySelectorAll(\"[tabindex]\")]\n .filter((element) => Number(element.getAttribute(\"tabindex\")) > 0)\n .map((element) => `${tools.describe(element)} (tabindex=\"${element.getAttribute(\"tabindex\")}\")`),\n titled: [...rootElement.querySelectorAll(titledSelector)].map((element) => tools.describe(element)),\n problems: factsOf(find('[data-chrome=\"problems\"]')),\n status: factsOf(find('[data-chrome=\"status\"]')),\n legend: factsOf(legend),\n legendTitle: labelledBy\n ? labelledBy\n .split(/\\s+/)\n .map((id) => document.getElementById(id)?.textContent?.trim() ?? \"\")\n .join(\" \")\n .trim()\n : null,\n legendClose: factsOf(legend?.querySelector(\"button\")),\n inspector: factsOf(find('[data-chrome=\"inspector\"]')),\n };\n};\n\nexport interface MenuItemFacts {\n role: string;\n name: string;\n checked: string | null;\n disabled: string | null;\n haspopup: string | null;\n /** `aria-label` of the enclosing `role=\"group\"`; `null` outside a group. */\n group: string | null;\n}\n\nexport interface MenuFacts {\n /** The trigger's `aria-expanded` and `aria-controls`. */\n expanded: string | null;\n controls: string | null;\n /** The visible `role=\"menu\"` inside the root. */\n menu: ElementFacts | null;\n items: MenuItemFacts[];\n /** Index of the focused item; -1 when the focus is elsewhere. */\n active: number;\n activeIsTrigger: boolean;\n}\n\nexport const menuProbe = ({ root }: { root: string }): MenuFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const trigger = rootElement.querySelector('[data-chrome=\"menu\"]');\n const menu =\n [...rootElement.querySelectorAll('[role=\"menu\"]')].find((element) => tools.visible(element)) ?? null;\n const items = menu\n ? [\n ...menu.querySelectorAll('[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]'),\n ].filter((item) => tools.visible(item))\n : [];\n return {\n expanded: trigger?.getAttribute(\"aria-expanded\") ?? null,\n controls: trigger?.getAttribute(\"aria-controls\") ?? null,\n menu: menu ? tools.facts(menu) : null,\n items: items.map((item) => {\n const group = item.closest('[role=\"group\"]');\n return {\n role: item.getAttribute(\"role\") ?? \"\",\n name: (item.getAttribute(\"aria-label\") ?? item.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n checked: item.getAttribute(\"aria-checked\"),\n disabled: item.getAttribute(\"aria-disabled\"),\n haspopup: item.getAttribute(\"aria-haspopup\"),\n group: group && menu?.contains(group) ? (group.getAttribute(\"aria-label\") ?? \"\") : null,\n };\n }),\n active: items.findIndex((item) => item === document.activeElement),\n activeIsTrigger: Boolean(trigger) && document.activeElement === trigger,\n };\n};\n\nexport interface PaletteFocusFacts {\n /** `data-action` of every entry, in order. */\n entries: string[];\n /** Entries with `tabindex=\"0\"`. */\n tabStops: string[];\n /** `data-action` of the focused entry; `null` when the focus is elsewhere. */\n active: string | null;\n}\n\nexport const paletteFocusProbe = ({ root }: { root: string }): PaletteFocusFacts | null => {\n const palette = document.querySelector(root)?.querySelector('[data-chrome=\"palette\"]');\n if (!palette) return null;\n const entries = [...palette.querySelectorAll(\"[data-action]\")];\n const active = document.activeElement;\n return {\n entries: entries.map((entry) => entry.getAttribute(\"data-action\") ?? \"\"),\n tabStops: entries\n .filter((entry) => entry.getAttribute(\"tabindex\") === \"0\")\n .map((entry) => entry.getAttribute(\"data-action\") ?? \"\"),\n active: active && entries.includes(active) ? active.getAttribute(\"data-action\") : null,\n };\n};\n\nexport const zoomButtonsProbe = ({ root }: { root: string }): Partial<Record<ZoomButton, ElementFacts>> => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const zoom = document.querySelector(root)?.querySelector('[data-chrome=\"zoom\"]');\n const buttons: Partial<Record<ZoomButton, ElementFacts>> = {};\n for (const name of [\"out\", \"actual\", \"in\", \"fit\"] as const) {\n const button = zoom?.querySelector(`[data-zoom=\"${name}\"]`);\n if (button) buttons[name] = tools.facts(button);\n }\n return buttons;\n};\n\n/** The design-system roles whose resolved values must agree on every part (no half-dark). */\nexport const MODE_ROLES = [\"--cd-ui-grund\", \"--cd-ui-text\", \"--cd-ui-flaeche-hoch\", \"--cd-ui-linie\"] as const;\n\nexport interface ModeFacts {\n name: string;\n description: string;\n colorScheme: string;\n roles: Record<string, string>;\n}\n\nexport interface ThemedElementFacts {\n description: string;\n isDocument: boolean;\n /** Where it sits relative to the shell root. */\n relation: \"self\" | \"ancestor\" | \"descendant\" | \"elsewhere\";\n theme: string | null;\n kontrast: string | null;\n}\n\nexport interface AppearanceFacts {\n documentClasses: string[];\n /** Every element with `data-cd-theme` or `data-cd-kontrast`. */\n themed: ThemedElementFacts[];\n /** Root, canvas, every visible island, the open dropdown and the visible tooltip. */\n parts: ModeFacts[];\n}\n\nexport const appearanceProbe = ({\n root,\n roles,\n}: {\n root: string;\n roles: readonly string[];\n}): AppearanceFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const mode = (name: string, element: Element) => {\n const style = getComputedStyle(element);\n const resolved: Record<string, string> = {};\n for (const role of roles) resolved[role] = style.getPropertyValue(role).trim();\n return { name, description: tools.describe(element), colorScheme: style.colorScheme, roles: resolved };\n };\n const parts = [mode(\"root\", rootElement)];\n const canvas = rootElement.querySelector(\".djs-container\");\n if (canvas) parts.push(mode(\"canvas\", canvas));\n for (const island of rootElement.querySelectorAll(\"[data-chrome]\")) {\n if (tools.visible(island)) parts.push(mode(island.getAttribute(\"data-chrome\") ?? \"island\", island));\n }\n for (const [name, role] of [\n [\"dropdown\", \"menu\"],\n [\"tooltip\", \"tooltip\"],\n ] as const) {\n const popup = [...rootElement.querySelectorAll(`[role=\"${role}\"]`)].find((element) =>\n tools.visible(element),\n );\n if (popup) parts.push(mode(name, popup));\n }\n return {\n documentClasses: [...document.documentElement.classList],\n themed: [...document.querySelectorAll(\"[data-cd-theme], [data-cd-kontrast]\")].map((element) => ({\n description: tools.describe(element),\n isDocument: element === document.documentElement,\n relation:\n element === rootElement\n ? \"self\"\n : element.contains(rootElement)\n ? \"ancestor\"\n : rootElement.contains(element)\n ? \"descendant\"\n : \"elsewhere\",\n theme: element.getAttribute(\"data-cd-theme\"),\n kontrast: element.getAttribute(\"data-cd-kontrast\"),\n })),\n parts,\n };\n};\n\n/** The element with the focus, classified for the tab-sequence check. */\nexport const activeStopProbe = ({ root }: { root: string }): { description: string; kind: string } => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const active = document.activeElement;\n const rootElement = document.querySelector(root);\n if (!active || active === document.body || !rootElement) return { description: \"<body>\", kind: \"other\" };\n const description = tools.describe(active);\n if (!rootElement.contains(active))\n return { description: `${description} outside the shell root`, kind: \"other\" };\n if (active.matches('[data-chrome=\"palette\"] [data-action]')) return { description, kind: \"palette\" };\n if (active.matches(\".djs-container > svg\")) return { description, kind: \"canvas\" };\n if (active.closest('[data-chrome=\"primary\"]')) return { description, kind: \"primary\" };\n const tabindex = active.getAttribute(\"tabindex\");\n return {\n description: tabindex === null ? description : `${description}[tabindex=\"${tabindex}\"]`,\n kind: \"other\",\n };\n};\n\n/** The focused palette entry, its `aria-keyshortcuts` and the chip of the visible tooltip. */\nexport const paletteShortcutProbe = ({\n root,\n}: {\n root: string;\n}): { action: string; chip: string; keyShortcuts: string | null } | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector(root);\n const active = document.activeElement;\n if (!rootElement || !active?.matches('[data-chrome=\"palette\"] [data-action]')) return null;\n const tooltip = [...rootElement.querySelectorAll('[role=\"tooltip\"]')].find((element) =>\n tools.visible(element),\n );\n const chip = tooltip\n ? [...tooltip.querySelectorAll(\"kbd\")].find((element) => tools.visible(element))\n : undefined;\n return {\n action: active.getAttribute(\"data-action\") ?? \"\",\n chip: (chip?.textContent ?? \"\").trim(),\n keyShortcuts: active.getAttribute(\"aria-keyshortcuts\"),\n };\n};\n\n/** The canvas surround (guide §10.1) and the role it must show. */\nexport interface SurroundFacts {\n /** Whether the root holds a `.djs-container`. */\n container: boolean;\n /** The first element from `.djs-container` out to the root that paints a background colour. */\n painted: { description: string; color: string } | null;\n /** `--cd-ui-grund` resolved to a computed colour inside the root. */\n grund: string;\n}\n\nexport const surroundProbe = ({ root }: { root: string }): SurroundFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const transparent = (color: string): boolean => {\n if (color === \"\" || color === \"transparent\") return true;\n const legacy = /^rgba\\([^)]*,\\s*([\\d.]+)\\)$/.exec(color);\n if (legacy) return Number(legacy[1]) === 0;\n const modern = /\\/\\s*([\\d.]+)%?\\s*\\)$/.exec(color);\n return modern ? Number(modern[1]) === 0 : false;\n };\n const start = rootElement.querySelector(\".djs-container\");\n let painted: SurroundFacts[\"painted\"] = null;\n for (let node: Element | null = start; node && !painted; node = node.parentElement) {\n const color = getComputedStyle(node).backgroundColor;\n if (!transparent(color)) painted = { description: tools.describe(node), color };\n if (node === rootElement) break;\n }\n const probe = document.createElement(\"span\");\n probe.setAttribute(\"data-modeler-shell-conformance\", \"role-probe\");\n probe.style.cssText = \"position:absolute;visibility:hidden;background-color:var(--cd-ui-grund);\";\n rootElement.append(probe);\n const grund = getComputedStyle(probe).backgroundColor;\n probe.remove();\n return { container: start !== null, painted, grund };\n};\n\n/** One visible palette entry, as the keyboard walk and the read-only lock read it. */\nexport interface PaletteEntryState {\n action: string;\n /** `data-group` of the enclosing `.group`; `null` outside one. */\n group: string | null;\n pressed: boolean;\n disabled: boolean;\n /** Viewport coordinates of the centre, for `page.mouse`. */\n client: { x: number; y: number };\n}\n\nexport const paletteEntriesProbe = ({ root }: { root: string }): PaletteEntryState[] => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const palette = document.querySelector(root)?.querySelector('[data-chrome=\"palette\"]');\n if (!palette) return [];\n return [...palette.querySelectorAll(\"[data-action]\")]\n .filter((entry) => tools.visible(entry))\n .map((entry) => {\n const rect = entry.getBoundingClientRect();\n return {\n action: entry.getAttribute(\"data-action\") ?? \"\",\n group: entry.closest(\"[data-group]\")?.getAttribute(\"data-group\") ?? null,\n pressed: entry.getAttribute(\"aria-pressed\") === \"true\",\n disabled: entry.getAttribute(\"aria-disabled\") === \"true\",\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n };\n });\n};\n\n/** The computed colours of one visible palette entry and of its icon. */\nexport interface PaletteColorEntry extends Omit<PaletteEntryState, \"client\"> {\n hovered: boolean;\n color: string;\n /** The entry's `<svg>`, else its `::before` when that has content; `null` for an image or a text entry. */\n icon: { kind: \"svg\" | \"::before\"; color: string } | null;\n}\n\nexport interface PaletteColorFacts {\n /** The roles of guide §5.5 and §13.5, resolved to computed colours inside the palette. */\n roles: { text: string; interaktion: string; textLeise: string };\n entries: PaletteColorEntry[];\n}\n\nexport const paletteColorProbe = ({ root }: { root: string }): PaletteColorFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const palette = document.querySelector(root)?.querySelector('[data-chrome=\"palette\"]');\n if (!palette) return null;\n const resolve = (role: string): string => {\n const probe = document.createElement(\"span\");\n probe.setAttribute(\"data-modeler-shell-conformance\", \"role-probe\");\n probe.style.cssText = `position:absolute;visibility:hidden;color:var(${role});`;\n palette.append(probe);\n const color = getComputedStyle(probe).color;\n probe.remove();\n return color;\n };\n const iconOf = (entry: Element): PaletteColorEntry[\"icon\"] => {\n const svg = entry.querySelector(\"svg\");\n if (svg) return { kind: \"svg\", color: getComputedStyle(svg).color };\n const before = getComputedStyle(entry, \"::before\");\n if (before.content && before.content !== \"none\" && before.content !== \"normal\") {\n return { kind: \"::before\", color: before.color };\n }\n return null;\n };\n return {\n roles: {\n text: resolve(\"--cd-ui-text\"),\n interaktion: resolve(\"--cd-ui-interaktion\"),\n textLeise: resolve(\"--cd-ui-text-leise\"),\n },\n entries: [...palette.querySelectorAll(\"[data-action]\")]\n .filter((entry) => tools.visible(entry))\n .map((entry) => ({\n action: entry.getAttribute(\"data-action\") ?? \"\",\n group: entry.closest(\"[data-group]\")?.getAttribute(\"data-group\") ?? null,\n pressed: entry.getAttribute(\"aria-pressed\") === \"true\",\n disabled: entry.getAttribute(\"aria-disabled\") === \"true\",\n hovered: entry.matches(\":hover\"),\n color: getComputedStyle(entry).color,\n icon: iconOf(entry),\n })),\n };\n};\n\n/** One diagram-js shape on the canvas (`.djs-shape[data-element-id]`). */\nexport interface ShapeFacts {\n id: string;\n /** diagram-js's selection marker on the shape's `<g>`. */\n selected: boolean;\n /** The `<g>`'s `transform` (its position in the diagram, unaffected by panning). */\n transform: string;\n /** Size of its `.djs-visual` in diagram units. */\n size: { width: number; height: number };\n /** Its `.djs-visual` relative to the root's padding box. */\n box: RelativeBox;\n /** Viewport coordinates of the centre, for `page.mouse`. */\n client: { x: number; y: number };\n /** Whether a pointer at the centre reaches the shape and not chrome above it. */\n hit: boolean;\n}\n\nexport const shapesProbe = ({ root }: { root: string }): ShapeFacts[] => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return [];\n return [...rootElement.querySelectorAll<SVGGraphicsElement>(\".djs-container .djs-shape[data-element-id]\")]\n .filter((shape) => tools.visible(shape))\n .map((shape) => {\n const visual = shape.querySelector<SVGGraphicsElement>(\".djs-visual\") ?? shape;\n const rect = visual.getBoundingClientRect();\n const client = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };\n const local = typeof visual.getBBox === \"function\" ? visual.getBBox() : rect;\n const hitElement = document.elementFromPoint(client.x, client.y);\n return {\n id: shape.getAttribute(\"data-element-id\") ?? \"\",\n selected: shape.classList.contains(\"selected\"),\n transform: shape.getAttribute(\"transform\") ?? \"\",\n size: { width: local.width, height: local.height },\n box: tools.box(visual, rootElement),\n client,\n hit: hitElement !== null && shape.contains(hitElement),\n };\n });\n};\n\n/** What the canvas offers at the moment: focus, context pad, open text fields. */\nexport interface CanvasStateFacts {\n /** The focus is inside `.djs-container` (the `<svg>` or a label editor). */\n focusInCanvas: boolean;\n focused: string;\n /** Visible entries of a diagram-js context pad. */\n contextPadEntries: string[];\n /** Visible text fields inside `.djs-container` (a label editor), the kit's stand-ins aside. */\n textFields: string[];\n}\n\nexport const canvasStateProbe = ({ root }: { root: string }): CanvasStateFacts => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const container = document.querySelector(root)?.querySelector(\".djs-container\");\n const active = document.activeElement;\n const ours = (element: Element) => element.closest(\"[data-modeler-shell-conformance]\") !== null;\n const visibleIn = (selector: string) =>\n container\n ? [...container.querySelectorAll(selector)].filter(\n (element) => !ours(element) && tools.visible(element),\n )\n : [];\n return {\n focusInCanvas: Boolean(container && active && container.contains(active)),\n focused: !active || active === document.body ? \"<body>\" : tools.describe(active),\n contextPadEntries: visibleIn(\".djs-context-pad .entry\").map(\n (entry) => entry.getAttribute(\"data-action\") ?? tools.describe(entry),\n ),\n textFields: visibleIn('input, textarea, [contenteditable]:not([contenteditable=\"false\"])').map((field) =>\n tools.describe(field),\n ),\n };\n};\n\n/** The read-only marks of the root and the status box (guide §5.12, §13.5). */\nexport interface ReadOnlyStateFacts {\n readOnly: boolean;\n status: ElementFacts | null;\n}\n\nexport const readOnlyStateProbe = ({ root }: { root: string }): ReadOnlyStateFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector(root);\n if (!rootElement) return null;\n const status = rootElement.querySelector('[data-chrome=\"status\"]');\n return { readOnly: rootElement.hasAttribute(\"data-readonly\"), status: status ? tools.facts(status) : null };\n};\n\n/** One item of the open menu with the group it stands in, counted by the separators. */\nexport interface MenuEntryFacts {\n name: string;\n role: string;\n /** `data-menu-id` of the item or its radio group. */\n menuId: string | null;\n disabled: boolean;\n /** `data-menu-group` of the item or its radio group: the shell's `model`, `export` or `help`. */\n group: string | null;\n}\n\nexport const menuEntriesProbe = ({ root }: { root: string }): MenuEntryFacts[] | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector(root);\n const menu = rootElement\n ? [...rootElement.querySelectorAll('[role=\"menu\"]')].find((element) => tools.visible(element))\n : undefined;\n if (!menu) return null;\n const entries: MenuEntryFacts[] = [];\n const selector = '[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]';\n for (const element of menu.querySelectorAll(selector)) {\n const role = element.getAttribute(\"role\") ?? \"\";\n if (!tools.visible(element)) continue;\n entries.push({\n name: (element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n role,\n menuId: element.closest(\"[data-menu-id]\")?.getAttribute(\"data-menu-id\") ?? null,\n disabled: element.getAttribute(\"aria-disabled\") === \"true\",\n group: element.closest(\"[data-menu-group]\")?.getAttribute(\"data-menu-group\") ?? null,\n });\n }\n return entries;\n};\n","import { INVALID_STATUS_DELAY_MS, type Appearance, type ShellHost, type Theme } from \"../core/index.js\";\nimport {\n DOM_ORDER,\n type AppearanceFacts,\n type AriaFacts,\n type CanvasStateFacts,\n type MenuEntryFacts,\n type MenuFacts,\n type PaletteColorEntry,\n type PaletteColorFacts,\n type PaletteEntryState,\n type ReadOnlyStateFacts,\n type ShapeFacts,\n type SurroundFacts,\n type ZoomButton,\n} from \"./facts.js\";\nimport { GEOMETRY_TOLERANCE_PX, type Rectangle } from \"./geometry.js\";\nimport type { ShellConformanceHarness, ShowHook } from \"./harness.js\";\nimport type { ElementFacts, LeftoverFacts, RecordedKey } from \"./page-tools.js\";\nimport type { PageLike } from \"./page.js\";\n\n/*\n * The judgements of the cases, as pure functions of what the probes saw. Each returns readable\n * problems (empty = conforming), so a case can report all of them at once.\n */\n\nconst normalize = (text: string): string => text.replace(/\\s+/g, \" \").trim();\n\nconst name = (element: ElementFacts): string => normalize(element.attributes[\"aria-label\"] ?? element.text);\n\nconst attribute = (element: ElementFacts, key: string): string | undefined => element.attributes[key];\n\n/** `aria-keyshortcuts` of the zoom panel (guide §5.6, WAI-ARIA key names). */\nexport function expectedKeyShortcuts(platform: \"mac\" | \"other\"): Record<ZoomButton, string> {\n const modifier = platform === \"mac\" ? \"Meta\" : \"Control\";\n return {\n in: `${modifier}+= ${modifier}+Plus`,\n out: `${modifier}+-`,\n actual: `${modifier}+0`,\n fit: \"Shift+1\",\n };\n}\n\n/** Roles, names, states, DOM order and tab stops of guide §5.4 to §5.14 and §12. */\nexport function ariaProblems(facts: AriaFacts, host: ShellHost): string[] {\n const problems: string[] = [];\n\n if (host === \"embedded\") {\n if (!facts.rootLang)\n problems.push(\"root: an embedded shell root carries the tool's lang itself (guide §2, §12)\");\n } else if (!facts.documentLang) {\n problems.push(\"<html> has no lang (guide §2)\");\n }\n\n const trigger = facts.trigger;\n if (!trigger) {\n problems.push('menu: no [data-chrome=\"menu\"] trigger');\n } else {\n if (trigger.tag !== \"button\")\n problems.push(`menu: the trigger is a <${trigger.tag}>, expected a <button>`);\n if (!attribute(trigger, \"aria-label\")) problems.push(\"menu: the icon-only trigger has no aria-label\");\n if (attribute(trigger, \"aria-haspopup\") !== \"menu\") {\n problems.push(`menu: aria-haspopup is \"${attribute(trigger, \"aria-haspopup\") ?? \"\"}\", expected \"menu\"`);\n }\n if (attribute(trigger, \"aria-expanded\") !== \"false\") {\n problems.push(\n `menu: aria-expanded is \"${attribute(trigger, \"aria-expanded\") ?? \"\"}\" while closed, expected \"false\"`,\n );\n }\n if (!attribute(trigger, \"aria-controls\")) {\n problems.push(\"menu: the trigger has no aria-controls\");\n } else if (!facts.controlled) {\n problems.push(`menu: aria-controls=\"${attribute(trigger, \"aria-controls\")}\" names no element`);\n } else if (attribute(facts.controlled, \"role\") !== \"menu\") {\n problems.push(\n `menu: aria-controls names a ${facts.controlled.description} with role \"${attribute(facts.controlled, \"role\") ?? \"\"}\", expected \"menu\"`,\n );\n }\n }\n\n if (!facts.palette) {\n problems.push('palette: no [data-chrome=\"palette\"]');\n } else {\n const toolbar = facts.toolbar;\n if (!toolbar || attribute(toolbar, \"role\") !== \"toolbar\") {\n problems.push('palette: .djs-palette-entries has no role=\"toolbar\"');\n } else if (!attribute(toolbar, \"aria-label\")) {\n problems.push(\"palette: the toolbar has no aria-label\");\n }\n for (const entry of facts.entries) {\n const action = attribute(entry, \"data-action\") ?? entry.description;\n if (attribute(entry, \"role\") !== \"button\")\n problems.push(`palette: entry \"${action}\" has no role=\"button\"`);\n if (!attribute(entry, \"aria-label\"))\n problems.push(`palette: entry \"${action}\" has no aria-label (title)`);\n const tabindex = attribute(entry, \"tabindex\");\n if (tabindex !== \"0\" && tabindex !== \"-1\") {\n problems.push(`palette: entry \"${action}\" has tabindex \"${tabindex ?? \"\"}\", expected roving 0/-1`);\n }\n }\n const stops = facts.entries.filter((entry) => attribute(entry, \"tabindex\") === \"0\");\n if (facts.entries.length > 0 && stops.length !== 1) {\n problems.push(\n `palette: ${stops.length} entries with tabindex=\"0\", expected exactly one (roving tabindex)`,\n );\n }\n const tools = facts.entries.filter(\n (entry) => entry.group === \"tools\" && (attribute(entry, \"data-action\") ?? \"\").endsWith(\"-tool\"),\n );\n for (const tool of tools) {\n const pressed = attribute(tool, \"aria-pressed\");\n if (pressed !== \"true\" && pressed !== \"false\") {\n problems.push(`palette: tool \"${attribute(tool, \"data-action\")}\" has no aria-pressed`);\n }\n }\n const pressed = tools.filter((tool) => attribute(tool, \"aria-pressed\") === \"true\");\n if (pressed.length > 1) problems.push(`palette: ${pressed.length} tools are aria-pressed at once`);\n }\n\n const zoom = facts.zoom;\n if (!zoom) {\n problems.push('zoom: no [data-chrome=\"zoom\"]');\n } else {\n if (attribute(zoom, \"role\") !== \"group\") problems.push('zoom: the panel has no role=\"group\"');\n if (!attribute(zoom, \"aria-label\")) problems.push(\"zoom: the panel has no aria-label\");\n const shortcuts = expectedKeyShortcuts(facts.platform);\n for (const button of [\"out\", \"actual\", \"in\", \"fit\"] as const) {\n const control = facts.zoomButtons[button];\n if (!control) {\n problems.push(`zoom: no [data-zoom=\"${button}\"] button`);\n continue;\n }\n if (control.tag !== \"button\") problems.push(`zoom: [data-zoom=\"${button}\"] is a <${control.tag}>`);\n if (!name(control)) problems.push(`zoom: [data-zoom=\"${button}\"] has no accessible name`);\n if (attribute(control, \"aria-keyshortcuts\") !== shortcuts[button]) {\n problems.push(\n `zoom: [data-zoom=\"${button}\"] aria-keyshortcuts is \"${attribute(control, \"aria-keyshortcuts\") ?? \"\"}\", expected \"${shortcuts[button]}\" (${facts.platform})`,\n );\n }\n if (control.disabled) {\n problems.push(\n `zoom: [data-zoom=\"${button}\"] is natively disabled; aria-disabled keeps the focus (guide §5.8)`,\n );\n }\n }\n const readout = facts.zoomButtons.actual;\n if (readout) {\n if (!/\\d/.test(readout.text))\n problems.push(`zoom: the readout shows \"${readout.text}\", expected a percentage`);\n const label = normalize(attribute(readout, \"aria-label\") ?? \"\");\n if (!label.includes(readout.text)) {\n problems.push(\n `zoom: the readout's aria-label \"${label}\" does not name the current zoom \"${readout.text}\"`,\n );\n }\n if (attribute(readout, \"aria-disabled\") === \"true\")\n problems.push(\"zoom: the readout is never disabled\");\n }\n }\n\n const present = new Set(facts.order);\n const expectedOrder = DOM_ORDER.filter((part) => present.has(part));\n if (facts.order.join() !== expectedOrder.join()) {\n problems.push(\n `DOM order is ${facts.order.join(\", \")}; expected ${expectedOrder.join(\", \")} (guide §5.14)`,\n );\n }\n if (!present.has(\"canvas\")) problems.push(\"canvas: no diagram-js <svg> (.djs-container > svg) in the root\");\n const canvas = facts.canvas;\n if (canvas && !normalize(attribute(canvas, \"aria-label\") ?? \"\") && !attribute(canvas, \"aria-labelledby\")) {\n problems.push(\n 'canvas: the focusable <svg> has no accessible name (WCAG 4.1.2); shellModule names it role=\"application\" with messages.canvas',\n );\n }\n for (const element of facts.positiveTabindex)\n problems.push(`positive tabindex on ${element} (guide §5.14)`);\n for (const element of facts.titled) {\n problems.push(`${element} has a native title; the chrome tooltip replaces it (guide §5.6)`);\n }\n return problems;\n}\n\n/** The optional islands once the harness showed them. */\nexport function optionalIslandProblems(facts: AriaFacts, shown: ReadonlySet<string>): string[] {\n const problems: string[] = [];\n if (shown.has(\"problems\")) {\n const pill = facts.problems;\n if (!pill?.visible) {\n problems.push(\"problems: the pill is not visible after show.problems\");\n } else {\n if (pill.tag !== \"button\") problems.push(`problems: the pill is a <${pill.tag}>, expected a <button>`);\n const label = normalize(attribute(pill, \"aria-label\") ?? \"\");\n if (!label) problems.push(\"problems: the pill has no aria-label (count and errors)\");\n else if (!label.includes(pill.text)) {\n problems.push(`problems: the aria-label \"${label}\" does not contain the visible text \"${pill.text}\"`);\n }\n }\n }\n if (shown.has(\"status\")) {\n const status = facts.status;\n if (!status?.visible) {\n problems.push(\"status: the status box is not visible after show.status\");\n } else {\n const role = attribute(status, \"role\");\n const severity = attribute(status, \"data-severity\");\n const expected = severity === \"danger\" ? \"alert\" : \"status\";\n if (role !== expected) {\n problems.push(\n `status: role is \"${role ?? \"\"}\" for data-severity=\"${severity ?? \"\"}\", expected \"${expected}\"`,\n );\n }\n }\n }\n if (shown.has(\"legend\")) {\n const legend = facts.legend;\n if (!legend?.visible) {\n problems.push(\"legend: the legend is not visible after show.legend\");\n } else {\n if (!facts.legendTitle)\n problems.push(\"legend: the card is not labelled by its title (aria-labelledby)\");\n if (!facts.legendClose || !attribute(facts.legendClose, \"aria-label\")) {\n problems.push(\"legend: the close button has no aria-label\");\n }\n }\n }\n if (shown.has(\"inspector\")) {\n const inspector = facts.inspector;\n if (!inspector?.visible) {\n problems.push(\"inspector: the inspector is not visible after show.inspector\");\n } else {\n if (inspector.tag !== \"aside\") problems.push(`inspector: a <${inspector.tag}>, expected an <aside>`);\n if (!attribute(inspector, \"aria-label\")) problems.push(\"inspector: the <aside> has no aria-label\");\n }\n }\n return problems;\n}\n\n/** One Tab stop as the kit's tab-sequence probe saw it. */\nexport interface TabStop {\n description: string;\n /** What the stop is: the palette's roving entry, the canvas `<svg>`, the web app's primary action. */\n kind: \"palette\" | \"canvas\" | \"primary\" | \"other\";\n}\n\n/**\n * Tab from the menu trigger (guide §5.14): the primary action (web app), the palette's one tab\n * stop, then the canvas `<svg>`; nothing else in between (a renderer's own `tabindex` on\n * `.djs-container` would be an extra, unnamed stop).\n */\nexport function tabSequenceProblems(stops: readonly TabStop[]): string[] {\n const [first, second, third] = stops;\n const sequence = first?.kind === \"primary\" ? [second, third] : [first, second];\n const [palette, canvas] = sequence;\n const problems: string[] = [];\n if (palette?.kind !== \"palette\") {\n problems.push(\n `tab order: Tab from the menu trigger lands on ${palette?.description ?? \"nothing\"}, expected the palette's roving entry (guide §5.14)`,\n );\n } else if (canvas?.kind !== \"canvas\") {\n problems.push(\n `tab order: Tab from the palette lands on ${canvas?.description ?? \"nothing\"}, expected the canvas <svg> (an unexpected tab stop, guide §5.14)`,\n );\n }\n return problems;\n}\n\n/** A palette entry with the keyboard focus: its tooltip's chip and what it names for assistive technology. */\nexport interface PaletteShortcutFacts {\n action: string;\n /** Text of the visible tooltip's `kbd` chip; empty without a chip. */\n chip: string;\n keyShortcuts: string | null;\n}\n\n/** Guide §5.6: an entry whose tooltip shows a shortcut carries `aria-keyshortcuts`. */\nexport function paletteShortcutProblems(entries: readonly PaletteShortcutFacts[]): string[] {\n return entries\n .filter((entry) => entry.chip && !entry.keyShortcuts)\n .map(\n (entry) =>\n `palette: entry \"${entry.action}\" shows the shortcut \"${entry.chip}\" in its tooltip but has no aria-keyshortcuts (guide §5.6)`,\n );\n}\n\n/**\n * The keys an open menu consumes (↑ ↓ Home End, a letter) never reach a `keydown` listener on\n * `document`: a modeler's document keyboard would act on them (Event Storming moves the selection\n * on ↑/↓).\n */\nexport function menuKeysAtDocumentProblems(\n pressed: readonly string[],\n documentKeys: readonly RecordedKey[],\n): string[] {\n const reached = new Set(documentKeys.map((key) => key.key));\n return pressed\n .filter((key) => reached.has(key))\n .map(\n (key) =>\n `menu: ${key} in the open menu reached a keydown listener on document; a modeler's document keyboard acts on it (stop it at the menu, guide §5.4)`,\n );\n}\n\n/** An open menu (guide §5.4): expanded trigger, labelled `role=\"menu\"`, named items, focus. */\nexport function menuOpenProblems(facts: MenuFacts, focus?: \"first\" | \"last\"): string[] {\n const problems: string[] = [];\n if (facts.expanded !== \"true\") {\n problems.push(`menu: aria-expanded is \"${facts.expanded ?? \"\"}\" while open, expected \"true\"`);\n }\n const menu = facts.menu;\n if (!menu) return [...problems, 'menu: no visible role=\"menu\" after opening'];\n if (!attribute(menu, \"aria-label\")) problems.push(\"menu: the dropdown has no aria-label\");\n if (facts.controls && attribute(menu, \"id\") !== facts.controls) {\n problems.push(\n `menu: the visible dropdown is #${attribute(menu, \"id\") ?? \"\"}, the trigger controls #${facts.controls}`,\n );\n }\n if (facts.items.length === 0) problems.push(\"menu: the dropdown has no menuitem\");\n facts.items.forEach((item, index) => {\n const label = item.name || `item ${index + 1}`;\n if (!item.name) problems.push(`menu: ${label} has no accessible name`);\n if (item.role !== \"menuitem\" && item.checked !== \"true\" && item.checked !== \"false\") {\n problems.push(`menu: \"${label}\" (${item.role}) has aria-checked \"${item.checked ?? \"\"}\"`);\n }\n if (item.role === \"menuitemradio\" && !item.group) {\n problems.push(`menu: radio \"${label}\" is not in a labelled role=\"group\"`);\n }\n if (item.haspopup === \"dialog\" && !item.name.endsWith(\"…\")) {\n problems.push(`menu: \"${label}\" opens a dialog, so its label ends with \"…\" (U+2026)`);\n }\n });\n if (focus && facts.items.length > 0) {\n const expected = focus === \"first\" ? 0 : facts.items.length - 1;\n if (facts.active !== expected) {\n problems.push(\n `menu: focus is on ${facts.active < 0 ? \"no entry\" : `entry ${facts.active + 1}`}, expected the ${focus} entry`,\n );\n }\n }\n return problems;\n}\n\nexport function menuClosedProblems(facts: MenuFacts, focusOnTrigger: boolean): string[] {\n const problems: string[] = [];\n if (facts.expanded !== \"false\")\n problems.push(`menu: aria-expanded is \"${facts.expanded ?? \"\"}\" after closing`);\n if (facts.menu) problems.push(\"menu: the dropdown is still visible after Escape\");\n if (focusOnTrigger && !facts.activeIsTrigger)\n problems.push(\"menu: Escape did not return the focus to the trigger\");\n return problems;\n}\n\n/**\n * How a key press must arrive at a `keydown` listener on `window` (guide §5.8, §13.5):\n * - `handled`: the shell executes it; IDE: stopped, else it arrives prevented;\n * - `blocked`: recognized but not executed (text field, modal, Escape with a dialog); IDE: stopped,\n * else it arrives unprevented (the browser, the field or the dialog acts);\n * - `canvas`: the canvas handled it (`defaultPrevented`); IDE: stopped, else it arrives prevented;\n * - `free`: nobody may handle it; it arrives unprevented in every host.\n * In the IDE host a stopped key never reaches `window`, so `prevented` is read on `document`.\n */\nexport type KeyReach = \"handled\" | \"blocked\" | \"canvas\" | \"free\";\n\nexport interface SeenKeys {\n /** What a listener on `window` saw. */\n keys: readonly RecordedKey[];\n /** What a listener on `document`, registered after the shell's, saw. */\n documentKeys?: readonly RecordedKey[];\n}\n\nexport function keyReachProblem(\n press: string,\n reach: KeyReach,\n host: ShellHost,\n seen: SeenKeys,\n): string | undefined {\n const shouldPrevent = reach === \"handled\" || reach === \"canvas\";\n if (host === \"ide\" && reach !== \"free\") {\n if (seen.keys.length > 0) {\n return `${press} reached a keydown listener on window; in the IDE host the shell stops it on document, or VS Code runs it again (guide §13.5)`;\n }\n const atDocument = seen.documentKeys ?? [];\n const prevented = atDocument.length === 1 ? atDocument[0]?.defaultPrevented : undefined;\n if (prevented === true && !shouldPrevent) {\n return `${press} was prevented; the shell only stops it, so the field, dialog or browser still acts (guide §13.5)`;\n }\n if (prevented === false && shouldPrevent) {\n return `${press} was stopped but not prevented; a handled key also calls preventDefault`;\n }\n return undefined;\n }\n if (seen.keys.length === 0) {\n return host === \"ide\"\n ? `${press} never reached window; keys the webview does not handle must go on to VS Code (guide §13.5)`\n : `${press} never reached window; outside the IDE host the shell never stops propagation`;\n }\n if (seen.keys.length > 1) return `${press} reached window ${seen.keys.length} times`;\n const prevented = seen.keys[0]?.defaultPrevented ?? false;\n if (prevented && !shouldPrevent) {\n return `${press} arrived prevented; ${reach === \"free\" ? \"nothing may handle it\" : \"the browser, the field or the dialog must act\"}`;\n }\n if (!prevented && shouldPrevent) {\n return `${press} arrived unprevented; a handled key calls preventDefault (the browser would zoom the page)`;\n }\n return undefined;\n}\n\n/** The decision of guide §13.5, computed independently of the shell under test. */\nexport function expectedAppearance(requested: Appearance, themes: readonly Theme[]): Appearance {\n const fallback = themes[0];\n if (fallback === undefined) throw new Error(\"@miragon/modeler-shell conformance: harness.themes is empty\");\n const theme = themes.includes(requested.theme) ? requested.theme : fallback;\n return requested.kontrast ? { theme, kontrast: requested.kontrast } : { theme };\n}\n\nconst describeAppearance = (appearance: Appearance): string =>\n appearance.kontrast ? `${appearance.theme} + ${appearance.kontrast}` : appearance.theme;\n\nexport interface AppearanceVerdict {\n problems: string[];\n}\n\n/**\n * What an embedded root must show (guide §13.3): until the contract's `appearance` surface there\n * is no channel to ask it for a mode, so it stays in its first one whatever the page shows, and\n * takes the page's high contrast over from the nearest mode carrier above it.\n */\nexport function expectedEmbeddedAppearance(facts: AppearanceFacts, themes: readonly Theme[]): Appearance {\n const fallback = themes[0];\n if (fallback === undefined) throw new Error(\"@miragon/modeler-shell conformance: harness.themes is empty\");\n const host = facts.themed.filter((element) => element.relation === \"ancestor\").at(-1);\n return host?.kontrast === \"hoch\" ? { theme: fallback, kontrast: \"hoch\" } : { theme: fallback };\n}\n\n/** No half-dark (guide §13.3, §13.5): one mode on `<html>` (own document) or the root (embedded). */\nexport function appearanceProblems(\n facts: AppearanceFacts,\n host: ShellHost,\n requested: Appearance,\n themes: readonly Theme[],\n): AppearanceVerdict {\n const ownDocument = host !== \"embedded\";\n const expected = ownDocument\n ? expectedAppearance(requested, themes)\n : expectedEmbeddedAppearance(facts, themes);\n const problems: string[] = [];\n const label = ownDocument\n ? `requested ${describeAppearance(requested)}, expected ${describeAppearance(expected)}`\n : `host page ${describeAppearance(requested)}, expected ${describeAppearance(expected)}`;\n\n const carrier = ownDocument\n ? facts.themed.find((element) => element.isDocument && element.theme !== null)\n : facts.themed.find((element) => element.relation === \"self\" && element.theme !== null);\n if (!carrier) {\n problems.push(\n ownDocument\n ? `<html> has no data-cd-theme (${label}); the host always writes it, also \"light\" (guide §13.3)`\n : `the embedded root has no data-cd-theme (${label}): it takes the host page's mode instead of its own (guide §13.3)`,\n );\n } else {\n if (carrier.theme !== expected.theme) {\n problems.push(`${carrier.description} has data-cd-theme=\"${carrier.theme}\" (${label})`);\n }\n if ((carrier.kontrast ?? undefined) !== expected.kontrast) {\n problems.push(\n `${carrier.description} has ${carrier.kontrast ? `data-cd-kontrast=\"${carrier.kontrast}\"` : \"no data-cd-kontrast\"} (${label})`,\n );\n }\n }\n for (const element of facts.themed) {\n if (element === carrier) continue;\n const stray = ownDocument\n ? !element.isDocument || element.theme === null\n : element.relation === \"descendant\" || element.relation === \"self\";\n if (!stray) continue;\n const values = [\n element.theme !== null ? `data-cd-theme=\"${element.theme}\"` : \"\",\n element.kontrast !== null ? `data-cd-kontrast=\"${element.kontrast}\"` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n const sameMode =\n carrier !== undefined && element.theme === carrier.theme && element.kontrast === carrier.kontrast;\n problems.push(\n element.theme === null\n ? `${element.description} carries ${values} without data-cd-theme on the same element (guide §13.3)`\n : sameMode\n ? `${element.description} repeats ${values}: in an own document the attributes stand only on <html> (guide §13.5)`\n : `${element.description} carries ${values}: a second mode inside the modeler is half-dark (guide §13.5)`,\n );\n }\n\n if (ownDocument && !facts.documentClasses.includes(\"cd-shell-document\")) {\n problems.push(\n \"<html> lacks cd-shell-document in an own document (the reset of the webview's host styles)\",\n );\n }\n if (!ownDocument && facts.documentClasses.includes(\"cd-shell-document\")) {\n problems.push(\n \"<html> of a foreign page carries cd-shell-document: the own-document reset restyles the host page\",\n );\n }\n\n const reference = facts.parts[0];\n if (reference && !reference.roles[\"--cd-ui-text\"]) {\n problems.push(\n \"--cd-ui-text is empty at the shell root: the vendored cd-tokens.generated.css is not loaded\",\n );\n }\n for (const part of facts.parts) {\n const schemes = part.colorScheme.split(/\\s+/);\n const dark = schemes.includes(\"dark\");\n const light = schemes.includes(\"light\");\n if (expected.theme === \"light\" && (dark || (carrier && !light))) {\n problems.push(`${part.name}: color-scheme is \"${part.colorScheme}\" (${label})`);\n }\n if (expected.theme === \"dark\" && (!dark || light)) {\n problems.push(`${part.name}: color-scheme is \"${part.colorScheme}\" (${label})`);\n }\n if (reference && part !== reference) {\n for (const [role, value] of Object.entries(part.roles)) {\n if (value !== reference.roles[role]) {\n problems.push(\n `${part.name}: ${role} resolves to \"${value}\", the root to \"${reference.roles[role] ?? \"\"}\" (half-dark)`,\n );\n }\n }\n }\n }\n for (const required of [\"dropdown\", \"tooltip\"]) {\n if (!facts.parts.some((part) => part.name === required)) {\n problems.push(`${required}: not visible when the kit opened it, so its mode was not checked`);\n }\n }\n return { problems };\n}\n\n/** The root attributes the shell writes (API.md, DOM). */\nconst SHELL_ROOT_ATTRIBUTES = [\n \"data-cd-shell-host\",\n \"data-palette\",\n \"data-legend\",\n \"data-inspector\",\n \"data-problems\",\n \"data-readonly\",\n];\n\n/** What an embedded root carries on top (its own mode). */\nconst EMBEDDED_ROOT_ATTRIBUTES = [\"data-cd-theme\", \"data-cd-kontrast\"];\n\n/** Messages of benign browser reports that are no shell error. */\nconst BENIGN_ERRORS = /ResizeObserver loop/;\n\n/** Nothing of the shell remains after `destroy` (API.md, `destroy()`). */\nexport function leftoverProblems(facts: LeftoverFacts, host: ShellHost): string[] {\n const problems: string[] = [];\n for (const element of facts.classedElements) problems.push(`${element} is left after destroy`);\n const ownDocument = host !== \"embedded\";\n for (const name of facts.documentClasses) {\n if (ownDocument && name === \"cd-shell-document\") continue;\n problems.push(`<html> keeps the class ${name} after destroy`);\n }\n for (const element of facts.chromeElements) problems.push(`${element} is left after destroy`);\n for (const name of facts.rootClasses) problems.push(`the root keeps the class ${name} after destroy`);\n const written = ownDocument\n ? SHELL_ROOT_ATTRIBUTES\n : [...SHELL_ROOT_ATTRIBUTES, ...EMBEDDED_ROOT_ATTRIBUTES];\n for (const name of facts.rootAttributes) {\n if (written.includes(name)) problems.push(`the root keeps ${name} after destroy`);\n }\n for (const error of facts.errors) {\n if (!BENIGN_ERRORS.test(error)) problems.push(`the page reported an error after destroy: ${error}`);\n }\n return problems;\n}\n\n/** After `destroy` no listener of the shell may act on a chrome key any more. */\nexport function afterDestroyKeyProblem(press: string, recorded: readonly RecordedKey[]): string | undefined {\n if (recorded.length === 0)\n return `${press} after destroy never reached window: a shell listener still stops it`;\n if (recorded.some((key) => key.defaultPrevented)) {\n return `${press} after destroy arrived prevented: a shell listener is still installed`;\n }\n return undefined;\n}\n\n/** The islands a harness may list as `absent`, as far as `geometry` and `aria` see them. */\nexport type AbsentIsland = Extract<ShowHook, \"legend\" | \"inspector\" | \"problems\" | \"status\">;\n\nconst ABSENT_ISLANDS: readonly AbsentIsland[] = [\"legend\", \"inspector\", \"problems\", \"status\"];\n\n/** The islands of `absent` (its state `invalid` has no island). */\nexport function absentIslands(absent: readonly ShowHook[] | undefined): AbsentIsland[] {\n return ABSENT_ISLANDS.filter((island) => absent?.includes(island));\n}\n\n/** An island the harness declares absent must never show. */\nexport function absentIslandProblems(\n visible: ReadonlySet<string>,\n absent: readonly ShowHook[] | undefined,\n): string[] {\n return absentIslands(absent)\n .filter((island) => visible.has(island))\n .map((island) => `${island}: visible, but harness.absent says the modeler has no ${island}`);\n}\n\n/** A hook the harness both gives and lists as absent is a contradiction in the harness itself. */\nexport function harnessHookProblems<P extends PageLike>(\n harness: ShellConformanceHarness<P>,\n hooks: readonly ShowHook[],\n): string[] {\n return hooks\n .filter((hook) => harness.absent?.includes(hook) && harness.show?.[hook])\n .map((hook) => `harness: absent lists \"${hook}\", but show.${hook} is given`);\n}\n\n/** Guide §10.1: the surround of the canvas is a container painted in `--cd-ui-grund`, in both modes. */\nexport function surroundProblems(facts: SurroundFacts): string[] {\n if (!facts.container) return [\"canvas surround: no .djs-container in the root to check\"];\n if (!facts.painted) {\n return [\n \"canvas surround: nothing from .djs-container out to the root paints a background colour; the surround is var(--cd-ui-grund) (guide §10.1)\",\n ];\n }\n if (facts.painted.color === facts.grund) return [];\n return [\n `canvas surround: ${facts.painted.description} paints ${facts.painted.color}, but --cd-ui-grund resolves to ${facts.grund}; the surround follows the mode (guide §10.1)`,\n ];\n}\n\n/** Lasso, Hand and the other tools of the `tools` group; every other entry is a notation preview. */\nexport function isToolEntry(entry: Pick<PaletteEntryState, \"action\" | \"group\">): boolean {\n return entry.group === \"tools\" || entry.action.endsWith(\"-tool\");\n}\n\nfunction paletteEntryState(entry: PaletteColorEntry): string {\n if (entry.disabled) return \"aria-disabled\";\n if (entry.hovered) return entry.pressed ? \"pressed and hovered\" : \"hovered\";\n return entry.pressed ? \"pressed\" : \"at rest\";\n}\n\n/**\n * Guide §5.5 and §13.5: a tool entry and its icon (`currentColor`) show `--cd-ui-text` at rest and\n * while pressed, `--cd-ui-interaktion` while hovered and `--cd-ui-text-leise` while aria-disabled.\n * Notation previews keep their own colours and are exempt.\n */\nexport function paletteColorProblems(facts: PaletteColorFacts): string[] {\n const problems: string[] = [];\n for (const entry of facts.entries) {\n if (!isToolEntry(entry)) continue;\n const [role, value] = entry.disabled\n ? ([\"--cd-ui-text-leise\", facts.roles.textLeise] as const)\n : entry.hovered\n ? ([\"--cd-ui-interaktion\", facts.roles.interaktion] as const)\n : ([\"--cd-ui-text\", facts.roles.text] as const);\n const state = paletteEntryState(entry);\n if (entry.color !== value) {\n problems.push(\n `palette: tool \"${entry.action}\" ${state} has color ${entry.color}, expected ${role} (${value}) (guide §5.5)`,\n );\n }\n if (entry.icon && entry.icon.color !== value) {\n const icon = entry.icon.kind === \"svg\" ? \"<svg> icon\" : \"::before icon\";\n problems.push(\n `palette: the ${icon} of tool \"${entry.action}\" ${state} has color ${entry.icon.color}, expected ${role} (${value}); a renderer rule overrides the skin (guide §5.5)`,\n );\n }\n }\n return problems;\n}\n\nexport interface CreateFacts {\n /** `data-action` of the entry the kit pressed Enter on. */\n entry: string;\n before: readonly ShapeFacts[];\n after: readonly ShapeFacts[];\n canvas: CanvasStateFacts;\n /** The free rectangle when Enter was pressed (guide §5.9). */\n free: Rectangle;\n}\n\nconst round = (value: number): number => Math.round(value * 10) / 10;\n\n/**\n * Guide §5.5: Enter on a creating entry places exactly one element in the centre of the free\n * rectangle, selects it and puts the focus on the canvas (its `<svg>` or the label editor).\n */\nexport function createProblems(facts: CreateFacts): string[] {\n const known = new Set(facts.before.map((shape) => shape.id));\n const added = facts.after.filter((shape) => !known.has(shape.id));\n const pressed = `Enter on palette entry \"${facts.entry}\"`;\n if (added.length === 0) {\n return [\n `create: ${pressed} added no element; Enter on a creating entry places it in the centre of the free rectangle (guide §5.5)`,\n ];\n }\n if (added.length > 1) {\n return [\n `create: ${pressed} added ${added.length} elements (${added.map((shape) => shape.id).join(\", \")}), expected exactly one`,\n ];\n }\n const [shape] = added as [ShapeFacts];\n const problems: string[] = [];\n if (!shape.selected) problems.push(`create: the new element \"${shape.id}\" is not selected (guide §5.5)`);\n if (!facts.canvas.focusInCanvas) {\n problems.push(\n `create: after ${pressed} the focus is on ${facts.canvas.focused}, expected the canvas (its <svg> or the label editor, guide §5.5)`,\n );\n }\n const centre = { x: shape.box.left + shape.box.width / 2, y: shape.box.top + shape.box.height / 2 };\n const { free } = facts;\n const tolerance = GEOMETRY_TOLERANCE_PX + 1e-6;\n const inside =\n centre.x >= free.left - tolerance &&\n centre.x <= free.right + tolerance &&\n centre.y >= free.top - tolerance &&\n centre.y <= free.bottom + tolerance;\n if (!inside) {\n problems.push(\n `create: the new element \"${shape.id}\" is centred at (${round(centre.x)}, ${round(centre.y)})px, outside the free rectangle ${round(free.left)}–${round(free.right)} × ${round(free.top)}–${round(free.bottom)}px (guide §5.5, §5.9)`,\n );\n }\n return problems;\n}\n\n/** The read-only marks once the invalid-file state shows (guide §5.12, §13.5). */\nexport function readOnlyStateProblems(facts: ReadOnlyStateFacts): string[] {\n const problems: string[] = [];\n const after = `${INVALID_STATUS_DELAY_MS}ms after show.invalid`;\n if (!facts.readOnly) problems.push(`read-only: the root has no data-readonly ${after}`);\n const status = facts.status;\n if (!status?.visible) {\n problems.push(`read-only: the status box is not visible ${after} (guide §5.12)`);\n } else if (status.attributes.role !== \"alert\") {\n problems.push(\n `read-only: the status box of an invalid file has role \"${status.attributes.role ?? \"\"}\", expected \"alert\" (guide §13.5)`,\n );\n }\n return problems;\n}\n\n/** The palette entries that stay active on a read-only canvas (guide §13.5), named independently of the shell. */\nexport const READ_ONLY_PALETTE_ACTIONS: readonly string[] = [\"lasso-tool\", \"hand-tool\"];\n\n/** Guide §13.5: every palette entry that changes something is aria-disabled, Lasso and Hand stay active. */\nexport function readOnlyPaletteProblems(entries: readonly PaletteEntryState[]): string[] {\n return entries.flatMap((entry) => {\n const staysActive = READ_ONLY_PALETTE_ACTIONS.includes(entry.action);\n if (staysActive && entry.disabled) {\n return [\n `palette: \"${entry.action}\" is aria-disabled on the read-only canvas; Lasso and Hand stay active (guide §13.5)`,\n ];\n }\n if (!staysActive && !entry.disabled) {\n return [`palette: \"${entry.action}\" is not aria-disabled on the read-only canvas (guide §13.5)`];\n }\n return [];\n });\n}\n\n/** The shell's own Legend toggle in the Model group. */\nconst LEGEND_MENU_ID = \"legend\";\n\n/**\n * Guide §13.5 and the product decision on view toggles: on a read-only canvas the Legend toggle,\n * export and help stay usable. The shell renders its `MenuGroups` as Model, Export, Help, empty\n * groups left out, so only the first group can be Model: an entry in a later one that read-only\n * newly disabled is a problem.\n */\nexport function readOnlyMenuProblems(\n before: readonly MenuEntryFacts[],\n after: readonly MenuEntryFacts[],\n): string[] {\n const problems: string[] = [];\n const key = (entry: MenuEntryFacts) => `${entry.menuId ?? \"\"}\\u0000${entry.name}`;\n const enabledBefore = new Set(before.filter((entry) => !entry.disabled).map(key));\n for (const entry of after) {\n if (!entry.disabled) continue;\n if (entry.menuId === LEGEND_MENU_ID && entry.role === \"menuitemcheckbox\") {\n problems.push(\n \"menu: the Legend toggle is aria-disabled on the read-only canvas; a view-only toggle stays usable (guide §13.5)\",\n );\n } else if (entry.group !== \"model\" && enabledBefore.has(key(entry))) {\n problems.push(\n `menu: \"${entry.name}\" is aria-disabled on the read-only canvas; export and help stay usable (guide §13.5)`,\n );\n }\n }\n return problems;\n}\n\n/** What the read-only lock must keep from a shape (guide §13.5): no context pad, move, resize, delete or label editor. */\nexport interface LockedShapeFacts {\n /** Context-pad entries visible after clicking the shape. */\n contextPadEntries: readonly string[];\n /** The shape before and after a 40px drag (`undefined`: gone). */\n dragged: { before: ShapeFacts; after: ShapeFacts | undefined };\n /** Text fields inside `.djs-container` after a double-click on the shape. */\n textFields: readonly string[];\n /** Whether the shape is still there after Delete, then after Backspace. */\n kept: { Delete: boolean; Backspace: boolean };\n}\n\nexport function lockedShapeProblems(facts: LockedShapeFacts): string[] {\n const problems: string[] = [];\n const { before, after } = facts.dragged;\n if (facts.contextPadEntries.length > 0) {\n problems.push(\n `read-only: selecting \"${before.id}\" shows the context pad (${facts.contextPadEntries.join(\", \")}) (guide §13.5)`,\n );\n }\n if (!after) {\n problems.push(`read-only: a 40px drag removed \"${before.id}\" from the canvas (guide §13.5)`);\n } else if (\n after.transform !== before.transform ||\n Math.abs(after.size.width - before.size.width) > 0.5 ||\n Math.abs(after.size.height - before.size.height) > 0.5\n ) {\n problems.push(\n `read-only: a 40px drag changed \"${before.id}\" (transform \"${before.transform}\" → \"${after.transform}\", ${round(before.size.width)} × ${round(before.size.height)} → ${round(after.size.width)} × ${round(after.size.height)}) (guide §13.5)`,\n );\n }\n if (facts.textFields.length > 0) {\n problems.push(\n `read-only: a double-click on \"${before.id}\" opens a text field (${facts.textFields.join(\", \")}) (guide §13.5)`,\n );\n }\n for (const key of [\"Delete\", \"Backspace\"] as const) {\n if (!facts.kept[key])\n problems.push(`read-only: ${key} on the canvas deleted \"${before.id}\" (guide §13.5)`);\n }\n return problems;\n}\n","import {\n INVALID_STATUS_DELAY_MS,\n TOOLTIP_DELAY_MS,\n type Appearance,\n type ShellHost,\n type Size,\n} from \"../core/index.js\";\nimport {\n absentIslandProblems,\n afterDestroyKeyProblem,\n appearanceProblems,\n ariaProblems,\n createProblems,\n harnessHookProblems,\n isToolEntry,\n keyReachProblem,\n leftoverProblems,\n lockedShapeProblems,\n menuClosedProblems,\n menuKeysAtDocumentProblems,\n menuOpenProblems,\n optionalIslandProblems,\n paletteColorProblems,\n paletteShortcutProblems,\n readOnlyMenuProblems,\n readOnlyPaletteProblems,\n readOnlyStateProblems,\n surroundProblems,\n tabSequenceProblems,\n type KeyReach,\n type PaletteShortcutFacts,\n type TabStop,\n} from \"./checks.js\";\nimport {\n MODE_ROLES,\n activeStopProbe,\n appearanceProbe,\n ariaProbe,\n canvasStateProbe,\n menuEntriesProbe,\n menuProbe,\n paletteColorProbe,\n paletteEntriesProbe,\n paletteFocusProbe,\n paletteShortcutProbe,\n readOnlyStateProbe,\n shapesProbe,\n surroundProbe,\n zoomButtonsProbe,\n type AppearanceFacts,\n type AriaFacts,\n type MenuEntryFacts,\n type MenuFacts,\n type PaletteEntryState,\n type ShapeFacts,\n} from \"./facts.js\";\nimport {\n DEFAULT_ROOT,\n dropdownProblems,\n freeRectangle,\n geometryProblems,\n measureChrome,\n tooltipProblems,\n type ChromeMeasurement,\n type TooltipRow,\n} from \"./geometry.js\";\nimport type {\n ShellCaseOutcome,\n ShellConformanceCase,\n ShellConformanceHarness,\n ShellSkip,\n ShowHook,\n ShowHooks,\n} from \"./harness.js\";\nimport type { PageLike } from \"./page.js\";\nimport {\n afterPressProbe,\n armCleanupProbe,\n canvasHandlesProbe,\n clearKeysProbe,\n findOverlay,\n findTarget,\n focusTarget,\n hostPageModeProbe,\n inPage,\n injectProbe,\n leftoverProbe,\n removeInjectedProbe,\n settle,\n type ChromeTarget,\n type InjectedKind,\n type TargetFacts,\n} from \"./page-tools.js\";\n\n/** Wide, narrow and very narrow (guide §5.15); 900 is above, 700 below the low breakpoint. */\nexport const DEFAULT_SIZES: readonly Size[] = [\n { width: 1280, height: 900 },\n { width: 720, height: 700 },\n { width: 420, height: 700 },\n];\n\nconst LIGHT: Appearance = { theme: \"light\" };\n\n/** Shown in this order, so the legend is measured without and then with the pill. */\nconst SHOWN_ISLANDS = [\"legend\", \"problems\", \"status\", \"inspector\"] as const satisfies ReadonlyArray<\n keyof ShowHooks\n>;\n\n/** How far the read-only case drags a shape (guide §13.5: no move). */\nconst LOCKED_DRAG_PX = 40;\n\n/** Room for a modeler that places, selects or re-renders a frame or two after Enter. */\nconst CREATE_WAIT_MS = 1000;\n\n/** Room after `INVALID_STATUS_DELAY_MS` for the read-only marks and the status box to show. */\nconst READ_ONLY_WAIT_MS = 1000;\n\n/** Room for the palette's 150ms colour transition (`--cd-motion-fast`) and a frame on either side. */\nconst COLOR_WAIT_MS = 600;\n\nconst POLL_MS = 50;\n\n/** Requested from the modeler by the appearance case (VS Code Dark, High Contrast, High Contrast Light). */\nconst REQUESTED_APPEARANCES: readonly Appearance[] = [\n { theme: \"dark\" },\n { theme: \"dark\", kontrast: \"hoch\" },\n { theme: \"light\", kontrast: \"hoch\" },\n];\n\n/** Room for the chrome tooltip's own fade after its 300ms hover delay. */\nconst HOVER_MARGIN_MS = 200;\n\n/** A spot without chrome: the root's top-left corner lies outside every island (12px edge). */\nconst PARK = { x: 1, y: 1 } as const;\n\n/** Every kind of text field a modeler renders: inspector and dialog fields, the label editor. */\nconst TEXT_FIELDS: ReadonlyArray<readonly [InjectedKind, string]> = [\n [\"input\", \"a text field\"],\n [\"textarea\", \"a textarea\"],\n [\"contenteditable\", \"an editable label\"],\n];\n\nconst UNDO_REDO_PRESSES = [\n \"Control+KeyZ\",\n \"Meta+KeyZ\",\n \"Control+Shift+KeyZ\",\n \"Meta+Shift+KeyZ\",\n \"Control+KeyY\",\n] as const;\n\nconst ONE_STEP_UP = 135;\nconst TWO_STEPS_UP = 182;\nconst ZOOM_LIMIT_MAX = 400;\nconst ZOOM_LIMIT_MIN = 20;\n\nfunction sizeLabel(size: Size): string {\n return `${size.width} × ${size.height}`;\n}\n\nfunction appearanceLabel(appearance: Appearance): string {\n return appearance.kontrast ? `${appearance.theme} + ${appearance.kontrast}` : appearance.theme;\n}\n\nfunction fail(caseName: string, host: ShellHost, problems: readonly string[]): never {\n const unique = [...new Set(problems)];\n throw new Error(\n `@miragon/modeler-shell conformance: ${caseName} (${host} host)\\n${unique.map((problem) => `- ${problem}`).join(\"\\n\")}`,\n );\n}\n\nfunction finish(\n caseName: string,\n host: ShellHost,\n problems: readonly string[],\n skipped: Iterable<ShellSkip>,\n): ShellCaseOutcome | void {\n if (problems.length > 0) fail(caseName, host, problems);\n const seen = new Set<string>();\n const unique = [...skipped].filter((skip) => !seen.has(skip.reason) && seen.add(skip.reason));\n return unique.length > 0 ? { skipped: unique } : undefined;\n}\n\n/** A harness that gives a hook it also declares absent contradicts itself: fail before opening anything. */\nfunction assertHooksConsistent<P extends PageLike>(\n caseName: string,\n harness: ShellConformanceHarness<P>,\n hooks: readonly ShowHook[],\n): void {\n const problems = harnessHookProblems(harness, hooks);\n if (problems.length > 0) fail(caseName, harness.host, problems);\n}\n\n/** A hook that is neither given nor declared absent. */\nfunction unfed<P extends PageLike>(harness: ShellConformanceHarness<P>, hook: ShowHook): boolean {\n return !harness.show?.[hook] && !harness.absent?.includes(hook);\n}\n\nfunction missingHooks<P extends PageLike>(harness: ShellConformanceHarness<P>, what: string): ShellSkip[] {\n return SHOWN_ISLANDS.filter((island) => unfed(harness, island)).map((island) => ({\n hook: island,\n reason: `show.${island} is undefined: ${what} of the ${island} island not verified`,\n }));\n}\n\n/** Reads until `done` holds or `timeoutMs` passed; the last value either way. */\nasync function pollUntil<T>(\n page: PageLike,\n read: () => Promise<T>,\n done: (value: T) => boolean,\n timeoutMs: number,\n): Promise<T> {\n let value = await read();\n for (let waited = 0; !done(value) && waited < timeoutMs; waited += POLL_MS) {\n await page.waitForTimeout(POLL_MS);\n value = await read();\n }\n return value;\n}\n\n/** The visible islands of an ARIA snapshot that a harness may declare absent. */\nfunction visibleIslands(facts: AriaFacts): Set<string> {\n const islands = new Set<string>();\n for (const island of SHOWN_ISLANDS) if (facts[island]?.visible) islands.add(island);\n return islands;\n}\n\n/** Hovers `target` long enough for its chrome tooltip; the hovered control, `null` when there is none. */\nasync function hover(page: PageLike, root: string, target: ChromeTarget): Promise<TargetFacts | null> {\n const anchor = await findTarget(page, root, target);\n if (!anchor) return null;\n await page.mouse.move(PARK.x, PARK.y);\n await page.mouse.move(anchor.client.x, anchor.client.y);\n await page.waitForTimeout(TOOLTIP_DELAY_MS + HOVER_MARGIN_MS);\n await settle(page);\n return anchor;\n}\n\nasync function openMenuByClick(page: PageLike, root: string): Promise<boolean> {\n const trigger = await findTarget(page, root, \"menu\");\n if (!trigger) return false;\n await page.mouse.click(trigger.client.x, trigger.client.y);\n await settle(page);\n return true;\n}\n\nasync function closeByEscape(page: PageLike): Promise<void> {\n await page.keyboard.press(\"Escape\");\n await settle(page);\n}\n\n/** Dropdown and tooltips of one measured state (guide §5.4, §5.6). */\nasync function popupGeometry(\n page: PageLike,\n root: string,\n measurement: ChromeMeasurement,\n): Promise<string[]> {\n const problems: string[] = [];\n if (!(await openMenuByClick(page, root))) return [\"dropdown: no visible menu trigger to open it\"];\n const dropdown = await findOverlay(page, root, \"menu\");\n if (!dropdown) problems.push('dropdown: no visible role=\"menu\" after clicking the trigger');\n else problems.push(...dropdownProblems(dropdown.box, measurement.container));\n await closeByEscape(page);\n\n const rows: Array<[ChromeTarget, TooltipRow]> = [\n [\"menu\", \"top\"],\n [\"palette-entry\", measurement.paletteRow === \"second-row\" ? \"second-row\" : \"top\"],\n [\"zoom-in\", \"bottom\"],\n ];\n for (const [target, row] of rows) {\n const anchor = await hover(page, root, target);\n if (!anchor) {\n problems.push(`tooltip: no visible ${target} to hover`);\n continue;\n }\n const tooltip = await findOverlay(page, root, \"tooltip\");\n if (!tooltip) {\n problems.push(`tooltip: none visible ${TOOLTIP_DELAY_MS + HOVER_MARGIN_MS}ms after hovering ${target}`);\n continue;\n }\n if (tooltip.count > 1) problems.push(`tooltip: ${tooltip.count} tooltips visible at once`);\n if (anchor.label && !tooltip.text.startsWith(anchor.label)) {\n problems.push(`tooltip: hovering ${target} (\"${anchor.label}\") shows \"${tooltip.text}\"`);\n }\n problems.push(\n ...tooltipProblems(tooltip.box, anchor.box, row, measurement.container).map(\n (problem) => `${problem} (on ${target})`,\n ),\n );\n }\n await page.mouse.move(PARK.x, PARK.y);\n return problems;\n}\n\nconst geometryCase: ShellConformanceCase = {\n name: \"geometry\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"geometry\", harness, SHOWN_ISLANDS);\n const root = harness.root ?? DEFAULT_ROOT;\n const problems: string[] = [];\n for (const size of harness.sizes ?? DEFAULT_SIZES) {\n const at = sizeLabel(size);\n await harness.open(page, { size, requested: LIGHT });\n await settle(page);\n const check = async (state: string): Promise<ChromeMeasurement> => {\n const measurement = await measureChrome(page, root);\n problems.push(\n ...[\n ...geometryProblems(measurement, harness.host),\n ...absentIslandProblems(new Set(Object.keys(measurement.islands)), harness.absent),\n ].map((problem) => `[${at}, ${state}] ${problem}`),\n );\n return measurement;\n };\n const opened = await check(\"as opened\");\n problems.push(...(await popupGeometry(page, root, opened)).map((problem) => `[${at}] ${problem}`));\n for (const island of SHOWN_ISLANDS) {\n const show = harness.show?.[island];\n if (!show) continue;\n await show(page);\n await settle(page);\n await check(`after show.${island}`);\n }\n }\n return finish(\"geometry\", harness.host, problems, missingHooks(harness, \"the geometry\"));\n },\n};\n\nasync function menuState(page: PageLike, root: string): Promise<MenuFacts> {\n const facts = await inPage(page, menuProbe, { root });\n if (!facts) throw new Error(`@miragon/modeler-shell conformance: no element matches \"${root}\"`);\n return facts;\n}\n\n/** Keyboard model of the menu (guide §5.4): Enter/↓ open on the first entry, ↑ on the last, wrap, Escape. */\nasync function menuKeyboardProblems(page: PageLike, root: string): Promise<string[]> {\n const problems: string[] = [];\n const openWith = async (key: string, focus: \"first\" | \"last\"): Promise<MenuFacts | undefined> => {\n if (!(await focusTarget(page, root, \"menu\"))) {\n problems.push(\"menu: the trigger cannot take focus\");\n return undefined;\n }\n await page.keyboard.press(key);\n await settle(page);\n const opened = await menuState(page, root);\n problems.push(...menuOpenProblems(opened, focus).map((problem) => `${key} on the trigger: ${problem}`));\n return opened;\n };\n const close = async (key: string) => {\n await closeByEscape(page);\n problems.push(\n ...menuClosedProblems(await menuState(page, root), true).map(\n (problem) => `${key}, then Escape: ${problem}`,\n ),\n );\n };\n\n const opened = await openWith(\"Enter\", \"first\");\n if (opened && opened.items.length > 1) {\n const moves: Array<[string, (count: number) => number]> = [\n [\"ArrowUp\", (count) => count - 1],\n [\"ArrowDown\", () => 0],\n [\"End\", (count) => count - 1],\n [\"Home\", () => 0],\n ];\n await inPage(page, clearKeysProbe, null);\n for (const [key, target] of moves) {\n await page.keyboard.press(key);\n const moved = await menuState(page, root);\n const expected = target(moved.items.length);\n if (moved.active !== expected) {\n problems.push(\n `menu: ${key} moves the focus to entry ${moved.active + 1}, expected entry ${expected + 1} of ${moved.items.length}`,\n );\n }\n }\n const { documentKeys } = await inPage(page, afterPressProbe, { root });\n problems.push(\n ...menuKeysAtDocumentProblems(\n moves.map(([key]) => key),\n documentKeys,\n ),\n );\n }\n if (opened) await close(\"Enter\");\n if (await openWith(\"ArrowDown\", \"first\")) await close(\"ArrowDown\");\n if (await openWith(\"ArrowUp\", \"last\")) await close(\"ArrowUp\");\n return problems;\n}\n\n/** Roving tabindex of the palette toolbar (guide §5.5): ← → Home End. */\nasync function paletteKeyboardProblems(page: PageLike, root: string): Promise<string[]> {\n const before = await inPage(page, paletteFocusProbe, { root });\n if (!before || before.entries.length < 2) return [];\n if (!(await focusTarget(page, root, \"palette-tab-stop\"))) {\n return ['palette: no entry with tabindex=\"0\" takes the focus'];\n }\n const problems: string[] = [];\n const start = before.entries.indexOf(before.tabStops[0] ?? \"\");\n const step = start < before.entries.length - 1 ? 1 : -1;\n const moves: Array<[string, number]> = [\n [step === 1 ? \"ArrowRight\" : \"ArrowLeft\", start + step],\n [\"End\", before.entries.length - 1],\n [\"Home\", 0],\n ];\n for (const [key, index] of moves) {\n await page.keyboard.press(key);\n const after = await inPage(page, paletteFocusProbe, { root });\n const expected = before.entries[index];\n if (!after || after.active !== expected) {\n problems.push(`palette: ${key} focuses \"${after?.active ?? \"nothing\"}\", expected \"${expected}\"`);\n } else if (after.tabStops.length !== 1 || after.tabStops[0] !== expected) {\n problems.push(\n `palette: after ${key} tabindex=\"0\" is on ${after.tabStops.join(\", \") || \"no entry\"}, expected \"${expected}\"`,\n );\n }\n }\n return problems;\n}\n\n/** Every palette entry by keyboard: a shortcut its tooltip shows is named in `aria-keyshortcuts`. */\nasync function paletteShortcutWalk(page: PageLike, root: string): Promise<string[]> {\n const before = await inPage(page, paletteFocusProbe, { root });\n if (!before || before.entries.length === 0) return [];\n if (!(await focusTarget(page, root, \"palette-tab-stop\"))) return [];\n if (before.entries.length > 1) await page.keyboard.press(\"End\");\n await page.keyboard.press(\"Home\");\n const seen: PaletteShortcutFacts[] = [];\n for (let index = 0; index < before.entries.length; index++) {\n const facts = await inPage(page, paletteShortcutProbe, { root });\n if (facts) seen.push(facts);\n await page.keyboard.press(\"ArrowRight\");\n }\n return paletteShortcutProblems(seen);\n}\n\n/** Tab from the menu trigger: the palette's one stop, then the canvas (guide §5.14). */\nasync function tabSequenceFromMenu(page: PageLike, root: string): Promise<string[]> {\n if (!(await focusTarget(page, root, \"menu\"))) return [];\n const stops: TabStop[] = [];\n for (let step = 0; step < 3; step++) {\n await page.keyboard.press(\"Tab\");\n const stop = await inPage(page, activeStopProbe, { root });\n stops.push({ description: stop.description, kind: stop.kind as TabStop[\"kind\"] });\n }\n return tabSequenceProblems(stops);\n}\n\n/** `aria-disabled` at 400 % and 20 % (guide §5.8), reached by clicking the buttons. */\nasync function zoomLimitProblems(page: PageLike, root: string): Promise<string[]> {\n const problems: string[] = [];\n const limits: Array<[\"in\" | \"out\", ChromeTarget, number, number, \"in\" | \"out\"]> = [\n [\"in\", \"zoom-in\", ZOOM_LIMIT_MAX, 12, \"out\"],\n [\"out\", \"zoom-out\", ZOOM_LIMIT_MIN, 16, \"in\"],\n ];\n for (const [button, target, limit, maxClicks, other] of limits) {\n const control = await findTarget(page, root, target);\n if (!control) continue;\n let buttons = await inPage(page, zoomButtonsProbe, { root });\n for (\n let click = 0;\n click < maxClicks && buttons[button]?.attributes[\"aria-disabled\"] !== \"true\";\n click++\n ) {\n await page.mouse.click(control.client.x, control.client.y);\n await settle(page);\n buttons = await inPage(page, zoomButtonsProbe, { root });\n }\n const { zoom } = await inPage(page, afterPressProbe, { root });\n const reached = buttons[button];\n if (reached?.attributes[\"aria-disabled\"] !== \"true\") {\n problems.push(\n `zoom: [data-zoom=\"${button}\"] is not aria-disabled after ${maxClicks} clicks (readout ${zoom ?? \"?\"}%)`,\n );\n } else {\n if (zoom !== limit) {\n problems.push(`zoom: [data-zoom=\"${button}\"] is disabled at ${zoom ?? \"?\"}%, expected at ${limit}%`);\n }\n if (reached.disabled) problems.push(`zoom: [data-zoom=\"${button}\"] is natively disabled at the limit`);\n }\n if (buttons[other]?.attributes[\"aria-disabled\"] === \"true\") {\n problems.push(`zoom: [data-zoom=\"${other}\"] is aria-disabled at ${zoom ?? \"?\"}%`);\n }\n if (buttons.actual?.attributes[\"aria-disabled\"] === \"true\") {\n problems.push(\"zoom: the readout is disabled at a limit\");\n }\n }\n await page.mouse.move(PARK.x, PARK.y);\n return problems;\n}\n\nconst ariaCase: ShellConformanceCase = {\n name: \"aria\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"aria\", harness, SHOWN_ISLANDS);\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await harness.open(page, { size, requested: LIGHT });\n await settle(page);\n const facts = await inPage(page, ariaProbe, { root });\n if (!facts) fail(\"aria\", harness.host, [`no element matches the shell root selector \"${root}\"`]);\n const problems = ariaProblems(facts, harness.host);\n problems.push(...(await menuKeyboardProblems(page, root)));\n problems.push(...(await paletteKeyboardProblems(page, root)));\n problems.push(...(await paletteShortcutWalk(page, root)));\n problems.push(...(await tabSequenceFromMenu(page, root)));\n problems.push(...(await zoomLimitProblems(page, root)));\n\n const shown = new Set<string>();\n for (const island of SHOWN_ISLANDS) {\n const show = harness.show?.[island];\n if (!show) continue;\n await show(page);\n shown.add(island);\n }\n let final: AriaFacts = facts;\n if (shown.size > 0) {\n await settle(page);\n const withIslands = await inPage(page, ariaProbe, { root });\n if (withIslands) {\n final = withIslands;\n problems.push(...optionalIslandProblems(withIslands, shown));\n const known = new Set(problems);\n problems.push(\n ...ariaProblems(withIslands, harness.host)\n .filter((problem) => !known.has(problem))\n .map((problem) => `with every island shown: ${problem}`),\n );\n }\n }\n problems.push(...absentIslandProblems(visibleIslands(final), harness.absent));\n return finish(\"aria\", harness.host, problems, missingHooks(harness, \"the roles and names\"));\n },\n};\n\nconst keysCase: ShellConformanceCase = {\n name: \"keys\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const host = harness.host;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await harness.open(page, { size, requested: LIGHT });\n await settle(page);\n const problems: string[] = [];\n\n if (!(await focusTarget(page, root, \"canvas\"))) {\n fail(\"keys\", host, [\"canvas: the diagram-js <svg> (.djs-container > svg) cannot take focus\"]);\n }\n await inPage(page, clearKeysProbe, null);\n let current = (await inPage(page, afterPressProbe, { root })).zoom;\n if (current === null) fail(\"keys\", host, ['zoom: no readout [data-zoom=\"actual\"] showing a percentage']);\n\n const press = async (\n key: string,\n reach: KeyReach | undefined,\n zoom: number | \"unchanged\" | undefined,\n context = \"on the canvas\",\n ) => {\n const before = current;\n await page.keyboard.press(key);\n let after = await inPage(page, afterPressProbe, { root });\n const where = `${key} ${context}`;\n if (reach) {\n const problem = keyReachProblem(where, reach, host, after);\n if (problem) problems.push(problem);\n }\n if (zoom === undefined) return;\n const expected = zoom === \"unchanged\" ? before : zoom;\n // a readout that has not moved yet may still be waiting for its frame; a wrong one stays wrong\n for (let poll = 0; after.zoom === before && expected !== before && poll < 10; poll++) {\n await page.waitForTimeout(50);\n after = await inPage(page, afterPressProbe, { root });\n }\n if (after.zoom !== expected) {\n problems.push(\n zoom === \"unchanged\"\n ? `${where} changed the zoom from ${before}% to ${after.zoom ?? \"?\"}%; it must not act`\n : `${where} zoomed to ${after.zoom ?? \"?\"}% from ${before}%, expected ${expected}% (exactly one step)`,\n );\n }\n current = after.zoom ?? current;\n };\n const inside = async (kind: InjectedKind, context: string, steps: () => Promise<void>) => {\n if (await inPage(page, injectProbe, { root, kind })) await steps();\n else problems.push(`cannot focus ${context} stand-in inside the root`);\n await inPage(page, removeInjectedProbe, null);\n };\n\n await press(\"Control+Digit0\", \"handled\", 100);\n const pairs: Array<[string, string]> = [\n [\"Control+Equal\", \"Control+Minus\"],\n [\"Control+Shift+Equal\", \"Control+Shift+Minus\"],\n [\"Meta+Equal\", \"Meta+Minus\"],\n [\"Meta+Shift+Equal\", \"Meta+Shift+Minus\"],\n [\"Control+NumpadAdd\", \"Control+NumpadSubtract\"],\n [\"Meta+NumpadAdd\", \"Meta+NumpadSubtract\"],\n ];\n for (const [zoomIn, zoomOut] of pairs) {\n await press(zoomIn, \"handled\", ONE_STEP_UP);\n await press(zoomOut, \"handled\", 100);\n }\n for (const zoomToActual of [\"Meta+Digit0\", \"Control+Numpad0\"]) {\n await press(\"Control+Equal\", \"handled\", ONE_STEP_UP);\n await press(zoomToActual, \"handled\", 100);\n }\n for (const key of [\"Equal\", \"Minus\", \"Shift+Equal\", \"Shift+Minus\", \"NumpadAdd\", \"NumpadSubtract\"]) {\n await press(key, \"free\", \"unchanged\", \"on the canvas without Cmd/Ctrl\");\n }\n for (const key of [\"Digit0\", \"Control+Alt+Equal\", \"Control+Alt+Minus\", \"Control+Shift+Digit1\"]) {\n await press(key, undefined, \"unchanged\");\n }\n await press(\"F1\", \"free\", undefined);\n await press(\"Escape\", \"free\", undefined, \"on the canvas without a menu or dialog\");\n if (await inPage(page, canvasHandlesProbe, { root, key: \"F9\" })) {\n await press(\"F9\", \"canvas\", undefined, \"handled by the canvas\");\n }\n await inPage(page, removeInjectedProbe, null);\n if (host === \"ide\") {\n // Guide §13.5: on the canvas, undo and redo use the document's history, never the canvas's.\n for (const key of UNDO_REDO_PRESSES) {\n await press(key, \"free\", undefined, \"on the canvas (undo and redo belong to the VS Code document)\");\n }\n }\n // Guide §13.5: keys the canvas uses act on the canvas only, select all included; in VS Code an\n // unhandled Cmd/Ctrl+A would select the webview's text instead.\n for (const key of [\"Control+KeyA\", \"Meta+KeyA\"]) {\n await press(key, \"canvas\", undefined, \"on the canvas (select all acts on the canvas only)\");\n }\n\n await press(\"Control+Equal\", \"handled\", ONE_STEP_UP);\n for (const [kind, field] of TEXT_FIELDS) {\n await inside(kind, field, async () => {\n await press(\"Control+Equal\", \"blocked\", \"unchanged\", `in ${field}`);\n await press(\"Control+Minus\", \"blocked\", \"unchanged\", `in ${field}`);\n await press(\"Shift+Digit1\", \"free\", \"unchanged\", `in ${field}`);\n await press(\"Control+KeyZ\", \"blocked\", undefined, `in ${field}`);\n await press(\"Meta+Shift+KeyZ\", \"blocked\", undefined, `in ${field}`);\n await press(\"Control+KeyY\", \"blocked\", undefined, `in ${field}`);\n });\n }\n await inside(\"modal\", \"a modal dialog\", async () => {\n await press(\"Control+Equal\", \"blocked\", \"unchanged\", \"with a modal dialog open\");\n await press(\"Shift+Digit1\", \"free\", \"unchanged\", \"with a modal dialog open\");\n await press(\"Escape\", \"blocked\", undefined, \"with a modal dialog open\");\n });\n await inside(\"popover\", \"a popover\", async () => {\n await press(\"Control+Minus\", \"handled\", 100, \"in a popover\");\n await press(\"Control+Equal\", \"handled\", ONE_STEP_UP, \"in a popover\");\n await press(\"Escape\", \"blocked\", undefined, \"with a popover open\");\n });\n\n if (await openMenuByClick(page, root)) {\n await inPage(page, clearKeysProbe, null);\n await press(\"Escape\", \"handled\", undefined, \"with the menu open\");\n if (await findOverlay(page, root, \"menu\")) problems.push(\"Escape with the menu open did not close it\");\n }\n\n await focusTarget(page, root, \"canvas\");\n await press(\"Control+Equal\", \"handled\", TWO_STEPS_UP);\n await page.keyboard.press(\"Shift+Digit1\");\n let fitted = await inPage(page, afterPressProbe, { root });\n const reachProblem = keyReachProblem(\"Shift+Digit1 on the canvas\", \"handled\", host, fitted);\n if (reachProblem) problems.push(reachProblem);\n for (let poll = 0; (fitted.zoom === null || fitted.zoom > 100) && poll < 20; poll++) {\n await page.waitForTimeout(50);\n fitted = await inPage(page, afterPressProbe, { root });\n }\n if (fitted.zoom === null || fitted.zoom > 100) {\n problems.push(\n `Shift+Digit1 on the canvas left the zoom at ${fitted.zoom ?? \"?\"}%, expected a fit (at most 100%)`,\n );\n }\n return finish(\"keys\", host, problems, []);\n },\n};\n\nasync function appearanceFacts(page: PageLike, root: string): Promise<AppearanceFacts | null> {\n const probe = () => inPage(page, appearanceProbe, { root, roles: MODE_ROLES });\n await hover(page, root, \"zoom-in\");\n const withTooltip = await probe();\n const opened = await openMenuByClick(page, root);\n const withMenu = await probe();\n if (opened) await closeByEscape(page);\n await page.mouse.move(PARK.x, PARK.y);\n if (!withTooltip || !withMenu) return withTooltip ?? withMenu;\n const names = new Set(withTooltip.parts.map((part) => part.name));\n return {\n ...withMenu,\n parts: [...withTooltip.parts, ...withMenu.parts.filter((part) => !names.has(part.name))],\n };\n}\n\n/** The palette's tool colours in the current state, read until a running colour transition is done. */\nasync function paletteColors(page: PageLike, root: string): Promise<string[]> {\n const read = async () => {\n const facts = await inPage(page, paletteColorProbe, { root });\n return facts ? paletteColorProblems(facts) : [];\n };\n return pollUntil(page, read, (problems) => problems.length === 0, COLOR_WAIT_MS);\n}\n\n/**\n * Guide §5.5: every tool entry at rest, hovered in turn, and the first tool armed by a click\n * (pressed and hovered, then pressed with the pointer away), Escape afterwards.\n */\nasync function paletteColorWalk(page: PageLike, root: string): Promise<string[]> {\n const problems: string[] = [];\n await page.mouse.move(PARK.x, PARK.y);\n problems.push(...(await paletteColors(page, root)));\n const tools = (await inPage(page, paletteEntriesProbe, { root })).filter(\n (entry) => isToolEntry(entry) && !entry.disabled,\n );\n for (const tool of tools) {\n await page.mouse.move(tool.client.x, tool.client.y);\n problems.push(...(await paletteColors(page, root)));\n await page.mouse.move(PARK.x, PARK.y);\n }\n const armed =\n tools.find((tool) => tool.action === \"lasso-tool\") ?? tools.find((tool) => tool.action.endsWith(\"-tool\"));\n if (armed) {\n await page.mouse.click(armed.client.x, armed.client.y);\n await settle(page);\n const pressed = (await inPage(page, paletteEntriesProbe, { root })).find(\n (entry) => entry.action === armed.action,\n );\n if (!pressed?.pressed) {\n problems.push(`palette: clicking tool \"${armed.action}\" does not set aria-pressed=\"true\" (guide §5.5)`);\n }\n problems.push(...(await paletteColors(page, root)));\n await page.mouse.move(PARK.x, PARK.y);\n problems.push(...(await paletteColors(page, root)));\n await closeByEscape(page);\n }\n return [...new Set(problems)];\n}\n\nconst appearanceCase: ShellConformanceCase = {\n name: \"appearance\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n const problems: string[] = [];\n for (const requested of REQUESTED_APPEARANCES) {\n const at = `[requested ${appearanceLabel(requested)}]`;\n await harness.open(page, { size, requested });\n if (harness.host === \"embedded\") {\n // The foreign page itself in that mode: a themed page around the modeler (guide §13.3).\n await inPage(page, hostPageModeProbe, {\n theme: requested.theme,\n kontrast: requested.kontrast ?? null,\n });\n }\n await settle(page);\n const facts = await appearanceFacts(page, root);\n if (!facts) {\n problems.push(`${at} no element matches the shell root selector \"${root}\"`);\n continue;\n }\n const verdict = appearanceProblems(facts, harness.host, requested, harness.themes);\n problems.push(...verdict.problems.map((problem) => `${at} ${problem}`));\n const surround = await inPage(page, surroundProbe, { root });\n if (surround) problems.push(...surroundProblems(surround).map((problem) => `${at} ${problem}`));\n problems.push(...(await paletteColorWalk(page, root)).map((problem) => `${at} ${problem}`));\n }\n return finish(\"appearance\", harness.host, problems, []);\n },\n};\n\n/** The visible shapes on the canvas. */\nfunction shapes(page: PageLike, root: string): Promise<ShapeFacts[]> {\n return inPage(page, shapesProbe, { root });\n}\n\n/** Moves the palette's roving focus by keyboard to `action`; `false` when it cannot get there. */\nasync function focusPaletteEntry(page: PageLike, root: string, action: string): Promise<boolean> {\n const before = await inPage(page, paletteFocusProbe, { root });\n if (!before || !before.entries.includes(action)) return false;\n if (!(await focusTarget(page, root, \"palette-tab-stop\"))) return false;\n await page.keyboard.press(\"Home\");\n for (let step = 0; step <= before.entries.length; step++) {\n if ((await inPage(page, paletteFocusProbe, { root }))?.active === action) return true;\n await page.keyboard.press(\"ArrowRight\");\n }\n return false;\n}\n\n/** The first entry that creates something: outside the tools group and not a tool. */\nfunction firstCreatingEntry(entries: readonly PaletteEntryState[]): PaletteEntryState | undefined {\n return entries.find((entry) => !isToolEntry(entry));\n}\n\n/** Enter on `entry`; the shapes once a new one appeared or `CREATE_WAIT_MS` passed. */\nasync function enterOnEntry(\n page: PageLike,\n root: string,\n entry: string,\n before: readonly ShapeFacts[],\n): Promise<ShapeFacts[] | undefined> {\n if (!(await focusPaletteEntry(page, root, entry))) return undefined;\n await page.keyboard.press(\"Enter\");\n await settle(page);\n const known = new Set(before.map((shape) => shape.id));\n return pollUntil(\n page,\n () => shapes(page, root),\n (after) => after.some((shape) => !known.has(shape.id)),\n CREATE_WAIT_MS,\n );\n}\n\nconst createCase: ShellConformanceCase = {\n name: \"create\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await harness.open(page, { size, requested: LIGHT });\n await settle(page);\n const entry = firstCreatingEntry(await inPage(page, paletteEntriesProbe, { root }));\n // A notation whose palette only switches tools has nothing to place.\n if (!entry) return undefined;\n await page.mouse.move(PARK.x, PARK.y);\n const free = freeRectangle(await measureChrome(page, root), harness.host);\n const before = await shapes(page, root);\n const after = await enterOnEntry(page, root, entry.action, before);\n if (!after) {\n fail(\"create\", harness.host, [`create: the palette's roving focus does not reach \"${entry.action}\"`]);\n }\n const canvas = await inPage(page, canvasStateProbe, { root });\n const problems = createProblems({ entry: entry.action, before, after, canvas, free });\n await closeByEscape(page);\n return finish(\"create\", harness.host, problems, []);\n },\n};\n\n/** The open menu's entries, opened by a click and closed again by Escape. */\nasync function menuEntries(page: PageLike, root: string): Promise<MenuEntryFacts[]> {\n if (!(await openMenuByClick(page, root))) return [];\n const entries = (await inPage(page, menuEntriesProbe, { root })) ?? [];\n await closeByEscape(page);\n return entries;\n}\n\n/** A shape whose centre a pointer reaches (no chrome above it), found again by its id. */\nasync function reachableShape(page: PageLike, root: string, id?: string): Promise<ShapeFacts | undefined> {\n const all = await shapes(page, root);\n return id === undefined ? all.find((shape) => shape.hit) : all.find((shape) => shape.id === id);\n}\n\n/** Guide §13.5, \"Was der Schreibschutz sperrt\", on one shape: select, drag, double-click, delete. */\nasync function lockedShapeChecks(page: PageLike, root: string, shape: ShapeFacts): Promise<string[]> {\n await page.mouse.click(shape.client.x, shape.client.y);\n await settle(page);\n const selected = await inPage(page, canvasStateProbe, { root });\n\n const before = (await reachableShape(page, root, shape.id)) ?? shape;\n await page.mouse.move(before.client.x, before.client.y);\n await page.mouse.down();\n for (let step = 1; step <= 4; step++) {\n await page.mouse.move(before.client.x + (LOCKED_DRAG_PX * step) / 4, before.client.y);\n }\n await page.mouse.up();\n await settle(page);\n const dragged = await reachableShape(page, root, shape.id);\n\n const target = dragged ?? before;\n await page.mouse.dblclick(target.client.x, target.client.y);\n await settle(page);\n const { textFields } = await inPage(page, canvasStateProbe, { root });\n await closeByEscape(page);\n\n const kept = { Delete: true, Backspace: true };\n for (const key of [\"Delete\", \"Backspace\"] as const) {\n const current = await reachableShape(page, root, shape.id);\n if (!current) break;\n // a key that deletes the selection must not miss it; a click on a selected shape deselects it\n if (!current.selected) await page.mouse.click(current.client.x, current.client.y);\n await focusTarget(page, root, \"canvas\");\n await page.keyboard.press(key);\n await settle(page);\n kept[key] = (await reachableShape(page, root, shape.id)) !== undefined;\n }\n await page.mouse.move(PARK.x, PARK.y);\n return lockedShapeProblems({\n contextPadEntries: selected.contextPadEntries,\n dragged: { before, after: dragged },\n textFields,\n kept,\n });\n}\n\nconst readOnlyCase: ShellConformanceCase = {\n name: \"readOnly\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"readOnly\", harness, [\"invalid\"]);\n const invalid = harness.show?.invalid;\n if (!invalid) {\n if (harness.absent?.includes(\"invalid\")) return undefined;\n return {\n skipped: [\n {\n hook: \"invalid\",\n reason: \"show.invalid is undefined: the read-only canvas of an invalid file was not verified\",\n },\n ],\n };\n }\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n const problems: string[] = [];\n const skipped: ShellSkip[] = [];\n await harness.open(page, { size, requested: LIGHT });\n await settle(page);\n const menuBefore = await menuEntries(page, root);\n\n await invalid(page);\n await page.waitForTimeout(INVALID_STATUS_DELAY_MS);\n const state = await pollUntil(\n page,\n () => inPage(page, readOnlyStateProbe, { root }),\n (facts) => facts === null || readOnlyStateProblems(facts).length === 0,\n READ_ONLY_WAIT_MS,\n );\n if (!state) fail(\"readOnly\", harness.host, [`no element matches the shell root selector \"${root}\"`]);\n await settle(page);\n problems.push(...readOnlyStateProblems(state));\n\n const entries = await inPage(page, paletteEntriesProbe, { root });\n problems.push(...readOnlyPaletteProblems(entries));\n problems.push(...(await paletteColors(page, root)));\n const creating = firstCreatingEntry(entries);\n if (creating) {\n const before = await shapes(page, root);\n const after = await enterOnEntry(page, root, creating.action, before);\n const known = new Set(before.map((shape) => shape.id));\n const added = (after ?? []).filter((shape) => !known.has(shape.id));\n if (added.length > 0) {\n problems.push(\n `read-only: Enter on palette entry \"${creating.action}\" added ${added.map((shape) => `\"${shape.id}\"`).join(\", \")} (guide §13.5)`,\n );\n }\n await closeByEscape(page);\n }\n\n problems.push(...readOnlyMenuProblems(menuBefore, await menuEntries(page, root)));\n\n const shape = await reachableShape(page, root);\n if (shape) {\n problems.push(...(await lockedShapeChecks(page, root, shape)));\n } else {\n skipped.push({\n hook: \"open\",\n reason:\n \"the opened document shows no shape a pointer reaches: context pad, move, delete and label editor of the read-only canvas not verified\",\n });\n }\n return finish(\"readOnly\", harness.host, problems, skipped);\n },\n};\n\nconst cleanupCase: ShellConformanceCase = {\n name: \"cleanup\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n if (!harness.destroy) {\n return {\n skipped: [\n {\n hook: \"destroy\",\n reason: \"harness.destroy is undefined: the cleanup after destroy was not verified\",\n },\n ],\n };\n }\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await harness.open(page, { size, requested: LIGHT });\n await settle(page);\n const armed = await inPage(page, armCleanupProbe, { root });\n if (!armed) fail(\"cleanup\", harness.host, [`no element matches the shell root selector \"${root}\"`]);\n const problems: string[] = [];\n\n // A hover leaves the tooltip timer pending, so a timer that outlives destroy shows up below.\n const zoomIn = await findTarget(page, root, \"zoom-in\");\n if (zoomIn) {\n await page.mouse.move(PARK.x, PARK.y);\n await page.mouse.move(zoomIn.client.x, zoomIn.client.y);\n }\n try {\n await harness.destroy(page);\n } catch (error) {\n problems.push(`destroy threw: ${error instanceof Error ? error.message : String(error)}`);\n }\n await page.waitForTimeout(Math.max(INVALID_STATUS_DELAY_MS, TOOLTIP_DELAY_MS) + HOVER_MARGIN_MS);\n await page.mouse.move(PARK.x, PARK.y);\n await page.setViewportSize({ width: size.width - 40, height: size.height - 40 });\n await settle(page);\n\n await inPage(page, injectProbe, { root, kind: \"focus-target\" });\n await inPage(page, clearKeysProbe, null);\n for (const key of [\"Control+Equal\", \"Control+Minus\", \"Control+Digit0\", \"Shift+Digit1\"]) {\n await page.keyboard.press(key);\n const { keys } = await inPage(page, afterPressProbe, { root });\n const problem = afterDestroyKeyProblem(key, keys);\n if (problem) problems.push(problem);\n }\n await inPage(page, removeInjectedProbe, null);\n problems.push(...leftoverProblems(await inPage(page, leftoverProbe, null), harness.host));\n return finish(\"cleanup\", harness.host, problems, []);\n },\n};\n\nexport function createCases(): ShellConformanceCase[] {\n return [geometryCase, ariaCase, keysCase, createCase, readOnlyCase, appearanceCase, cleanupCase];\n}\n","import type { Appearance, ColorThemeSetting, ShellHost, Size, Theme } from \"../core/index.js\";\nimport { createCases } from \"./cases.js\";\nimport type { PageLike } from \"./page.js\";\n\nexport interface OpenContext {\n /** The page's viewport, which is the modeler's container in an own document. */\n size: Size;\n /**\n * What the host requests before the modeler resolves it: in an IDE host the VS Code color theme\n * (`vsCodeStubSearch` hands it to a page with the VS Code stub). For an embedded host the kit\n * itself puts the foreign page's `<html>` in this mode once `open` resolved.\n */\n requested: Appearance;\n}\n\n/**\n * How the kit makes the optional islands visible (`geometry`, `aria`) and puts the modeler into its\n * invalid-file state (`readOnly`).\n */\nexport interface ShowHooks<P extends PageLike = PageLike> {\n problems?: ((page: P) => Promise<void>) | undefined;\n status?: ((page: P) => Promise<void>) | undefined;\n legend?: ((page: P) => Promise<void>) | undefined;\n inspector?: ((page: P) => Promise<void>) | undefined;\n /**\n * Puts the modeler into its invalid-file state the way its host does (an invalid import): a\n * read-only canvas and the status box. The kit waits `INVALID_STATUS_DELAY_MS` afterwards.\n */\n invalid?: ((page: P) => Promise<void>) | undefined;\n}\n\n/** A show hook by name: the islands `legend`, `inspector`, `problems`, `status` and the state `invalid`. */\nexport type ShowHook = keyof ShowHooks;\n\nexport interface ShellConformanceHarness<P extends PageLike = PageLike> {\n host: ShellHost;\n /** The modes the modeler declares (static); the appearance case requests dark from `[\"light\"]`. */\n themes: readonly Theme[];\n /** Load the modeler with the shell at `size`, as the host would with `requested`; resolve once the first import is done. */\n open(page: P, context: OpenContext): Promise<void>;\n /** Tear modeler and shell down through the page's own path; `undefined` skips the cleanup case. */\n destroy?: ((page: P) => Promise<void>) | undefined;\n /** CSS selector of the shell root; default `.cd-shell`. */\n root?: string | undefined;\n /** Hooks for the islands and states the modeler has; one that is neither given nor `absent` is reported as skipped. */\n show?: ShowHooks<P> | undefined;\n /**\n * The islands and states the modeler does not have. An absent hook is not reported as skipped,\n * and `geometry` and `aria` assert that its island is never visible. Listing a hook that `show`\n * also gives fails every case that uses it.\n */\n absent?: readonly ShowHook[] | undefined;\n /** Container sizes of the geometry case; default wide 1280 × 900, narrow 720 × 700, very narrow 420 × 700. */\n sizes?: readonly Size[] | undefined;\n}\n\n/** One part of a case the harness could not feed. */\nexport interface ShellSkip {\n /**\n * The harness field that would feed it: a show hook, `destroy`, or `open` when the document it\n * opens lacks what the case needs (a shape on the canvas).\n */\n hook: ShowHook | \"destroy\" | \"open\";\n reason: string;\n}\n\nexport interface ShellCaseOutcome {\n /** What the case could not (fully) run, one entry per missing harness field. */\n skipped?: readonly ShellSkip[];\n}\n\nexport interface ShellConformanceCase {\n name: string;\n run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>): Promise<ShellCaseOutcome | void>;\n}\n\n/**\n * The cases: `geometry` (every `data-chrome` island ±1px, per host and breakpoint), `aria`\n * (roles, names, `aria-expanded`/`-controls`/`-keyshortcuts`/`-disabled`, DOM order, no positive\n * tabindex), `keys` (each chrome key acts exactly once; in the IDE host a `keydown` listener on\n * `window` never fires for a handled key; unmodified `+`/`-` never zoom; select all acts on the\n * canvas only), `create` (Enter on the first creating palette entry places one selected element in\n * the free rectangle and focuses the canvas), `readOnly` (the invalid-file lock of guide §13.5),\n * `appearance` (dark requested from a light-only modeler: nothing turns dark, `color-scheme` light\n * everywhere, the canvas surround and the palette's tool colours from the roles) and `cleanup` (after\n * `destroy` no shell element, class, attribute or key handling remains).\n */\nexport function shellConformanceCases(): ShellConformanceCase[] {\n return createCases();\n}\n\n/** Playwright's `test` (or any runner whose body receives `{ page }`). */\nexport type ShellConformanceTest<P extends PageLike = PageLike> = (\n name: string,\n body: (fixtures: { page: P }) => Promise<void>,\n) => unknown;\n\nexport interface RegisterShellConformanceOptions {\n /** Default: `console.warn`, one line per case with its skips joined by \"; \". */\n onSkip?: ((caseName: string, skips: readonly ShellSkip[]) => void) | undefined;\n}\n\n/**\n * The query string for a test page that installs the VS Code stub of\n * `@miragon/modeler-shell/testing/vscode-stub` with `stubOptionsFromSearch(location.search)`:\n * `theme=dark&kontrast=hoch`, plus the `colorTheme` setting and VS Code's reduce motion.\n */\nexport function vsCodeStubSearch(\n requested: Appearance,\n extra: { colorTheme?: ColorThemeSetting | undefined; reduceMotion?: boolean | undefined } = {},\n): string {\n const query = new URLSearchParams({ theme: requested.theme });\n if (requested.kontrast) query.set(\"kontrast\", requested.kontrast);\n if (extra.colorTheme) query.set(\"colorTheme\", extra.colorTheme);\n if (extra.reduceMotion) query.set(\"reduceMotion\", \"\");\n return query.toString();\n}\n\n/** Registers every case as `shell conformance: <name>`. */\nexport function registerShellConformance<P extends PageLike>(\n harness: ShellConformanceHarness<P>,\n test: ShellConformanceTest<P>,\n options: RegisterShellConformanceOptions = {},\n): void {\n const onSkip =\n options.onSkip ??\n ((caseName: string, skips: readonly ShellSkip[]) => {\n console.warn(\n `@miragon/modeler-shell conformance: SKIPPED \"${caseName}\" (${harness.host} host): ${skips.map((skip) => skip.reason).join(\"; \")}`,\n );\n });\n for (const conformanceCase of shellConformanceCases()) {\n test(`shell conformance: ${conformanceCase.name}`, async ({ page }) => {\n const outcome = await conformanceCase.run(page, harness);\n if (outcome?.skipped && outcome.skipped.length > 0) onSkip(conformanceCase.name, outcome.skipped);\n });\n }\n}\n"],"mappings":"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","names":["name","name","attribute","name","pressed","prevented","name","round","shape","opened","shape"]}
1
+ {"version":3,"sources":["../src/testing/page-tools.ts","../src/testing/geometry.ts","../src/testing/facts.ts","../src/testing/web-checks.ts","../src/testing/checks.ts","../src/testing/case-tools.ts","../src/testing/web-facts.ts","../src/testing/web-cases.ts","../src/testing/cases.ts","../src/testing/harness.ts"],"sourcesContent":["import type { Size } from \"../core/index.js\";\nimport type { PageLike } from \"./page.js\";\n\n/*\n * Everything here that is handed to `page.evaluate` runs in the browser: Playwright serializes the\n * function source, so these functions must not reference anything outside their own body. They\n * only collect facts; every judgement happens in Node (`checks.ts`, `geometry.ts`), where it is\n * unit-tested. `installPageTools` puts the shared helpers and the recorders under one page global.\n */\n\n/** A box relative to the shell root's padding box (where `position: absolute` islands anchor). */\nexport interface RelativeBox {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/** A `keydown` that reached the kit's listener on `window` (bubble phase), where VS Code's host page listens. */\nexport interface RecordedKey {\n key: string;\n code: string;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n defaultPrevented: boolean;\n}\n\n/** The facts the kit reads about one element. */\nexport interface ElementFacts {\n tag: string;\n description: string;\n attributes: Record<string, string>;\n text: string;\n visible: boolean;\n /** The native `disabled` property (a disabled `<button>` loses focus, `aria-disabled` keeps it). */\n disabled: boolean;\n}\n\n/** The helpers and recorders `installPageTools` keeps under the page global. */\nexport interface PageTools {\n /** `keydown`s that reached `window`, where VS Code's host page listens. */\n keys: RecordedKey[];\n /**\n * `keydown`s seen on `document` after every listener registered before the kit's (the shell's,\n * the modeler's), so `defaultPrevented` is final even where the shell stops the key.\n */\n documentKeys: RecordedKey[];\n errors: string[];\n injected: Element[];\n cleanups: Array<() => void>;\n armedRoot?: HTMLElement;\n /** Clicks a kit listener counted on a control (the web app's primary action). */\n clicks: number;\n /** Changes of the document's mode the kit records while it switches the web app's appearance. */\n modeWatch?: ModeWatch | undefined;\n /** `newState` of every `beforetoggle` of the web app's toast stack since the kit started listening. */\n toastToggles?: string[] | undefined;\n frame(): Promise<void>;\n settle(): Promise<void>;\n visible(element: Element): boolean;\n container(root: HTMLElement): Size;\n box(element: Element, root: HTMLElement): RelativeBox;\n describe(element: Element): string;\n facts(element: Element): ElementFacts;\n}\n\nexport type ToolWindow = Window & { __modelerShellConformance?: PageTools };\n\n/** One change of `<html>`'s mode or of its meta tags, with the animation frame it landed in. */\nexport interface ModeChange {\n part: \"theme\" | \"kontrast\" | \"color-scheme\" | \"theme-color\" | \"no-transition\";\n value: string | null;\n frame: number;\n}\n\nexport interface ModeWatch {\n changes: ModeChange[];\n stop(): void;\n}\n\n/** Installs the in-page helpers once per document (idempotent; a navigation drops them). */\nexport const installPageTools = (_: null): void => {\n const scope = window as ToolWindow;\n if (scope.__modelerShellConformance) return;\n const modifierKeys = [\"Control\", \"Meta\", \"Shift\", \"Alt\", \"AltGraph\", \"CapsLock\", \"Fn\"];\n const frame = () => new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n const borders = (element: Element) => {\n const style = getComputedStyle(element);\n return {\n left: parseFloat(style.borderLeftWidth) || 0,\n top: parseFloat(style.borderTopWidth) || 0,\n right: parseFloat(style.borderRightWidth) || 0,\n bottom: parseFloat(style.borderBottomWidth) || 0,\n };\n };\n const visible = (element: Element): boolean => {\n if (!element.isConnected) return false;\n if (typeof element.checkVisibility === \"function\") {\n if (!element.checkVisibility({ visibilityProperty: true })) return false;\n } else {\n if (element.closest(\"[hidden]\")) return false;\n for (let node: Element | null = element; node; node = node.parentElement) {\n if (getComputedStyle(node).display === \"none\") return false;\n }\n if (getComputedStyle(element).visibility === \"hidden\") return false;\n }\n const rect = element.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n };\n const describe = (element: Element): string => {\n const id = element.id ? `#${element.id}` : \"\";\n const classes = [...element.classList]\n .slice(0, 3)\n .map((name) => `.${name}`)\n .join(\"\");\n const chrome = element.getAttribute(\"data-chrome\");\n return `${element.tagName.toLowerCase()}${id}${classes}${chrome ? `[data-chrome=\"${chrome}\"]` : \"\"}`;\n };\n const tools: PageTools = {\n keys: [],\n documentKeys: [],\n errors: [],\n injected: [],\n cleanups: [],\n clicks: 0,\n frame,\n async settle() {\n await frame();\n await frame();\n const running =\n typeof document.getAnimations === \"function\"\n ? document.getAnimations().filter((animation) => {\n const end = animation.effect?.getComputedTiming().endTime;\n return animation.playState === \"running\" && typeof end === \"number\" && Number.isFinite(end);\n })\n : [];\n if (running.length > 0) {\n await Promise.race([\n Promise.allSettled(running.map((animation) => animation.finished)),\n new Promise((resolve) => setTimeout(resolve, 2000)),\n ]);\n }\n await frame();\n },\n visible,\n container(root) {\n const rect = root.getBoundingClientRect();\n const border = borders(root);\n return {\n width: rect.width - border.left - border.right,\n height: rect.height - border.top - border.bottom,\n };\n },\n box(element, root) {\n const rect = element.getBoundingClientRect();\n const origin = root.getBoundingClientRect();\n const border = borders(root);\n return {\n left: rect.left - origin.left - border.left,\n top: rect.top - origin.top - border.top,\n width: rect.width,\n height: rect.height,\n };\n },\n describe,\n facts(element) {\n const attributes: Record<string, string> = {};\n for (const name of element.getAttributeNames()) attributes[name] = element.getAttribute(name) ?? \"\";\n return {\n tag: element.tagName.toLowerCase(),\n description: describe(element),\n attributes,\n text: (element.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n visible: visible(element),\n disabled: Boolean((element as HTMLButtonElement).disabled),\n };\n },\n };\n const recorder = (into: RecordedKey[]) => (event: KeyboardEvent) => {\n if (modifierKeys.includes(event.key)) return;\n into.push({\n key: event.key,\n code: event.code,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n defaultPrevented: event.defaultPrevented,\n });\n };\n document.addEventListener(\"keydown\", recorder(tools.documentKeys));\n window.addEventListener(\"keydown\", recorder(tools.keys));\n window.addEventListener(\"error\", (event) => {\n tools.errors.push(event.message || String(event.error));\n });\n window.addEventListener(\"unhandledrejection\", (event) => {\n tools.errors.push(`unhandled rejection: ${String(event.reason)}`);\n });\n scope.__modelerShellConformance = tools;\n};\n\n/** Runs `pageFunction` in the page after making sure the helpers are installed. */\nexport async function inPage<Arg, Result>(\n page: PageLike,\n pageFunction: (arg: Arg) => Result | Promise<Result>,\n arg: Arg,\n): Promise<Result> {\n await page.evaluate(installPageTools, null);\n return page.evaluate(pageFunction, arg);\n}\n\n/** Two frames plus every finite running animation (pop-ins, slide-ins), capped at 2s. */\nexport const settleInPage = (_: null): Promise<void> =>\n (window as ToolWindow).__modelerShellConformance!.settle();\n\nexport function settle(page: PageLike): Promise<void> {\n return inPage(page, settleInPage, null);\n}\n\n/** The controls the kit hovers, clicks or focuses, found inside the shell root. */\nexport type ChromeTarget =\n | \"menu\"\n | \"palette-entry\"\n | \"palette-tab-stop\"\n | \"zoom-out\"\n | \"zoom-actual\"\n | \"zoom-in\"\n | \"zoom-fit\"\n | \"canvas\"\n | \"primary\"\n | \"pill\";\n\nexport const CHROME_TARGET_SELECTORS: Readonly<Record<ChromeTarget, string>> = {\n menu: '[data-chrome=\"menu\"]',\n \"palette-entry\": '[data-chrome=\"palette\"] [data-action]',\n \"palette-tab-stop\": '[data-chrome=\"palette\"] [data-action][tabindex=\"0\"]',\n \"zoom-out\": '[data-chrome=\"zoom\"] [data-zoom=\"out\"]',\n \"zoom-actual\": '[data-chrome=\"zoom\"] [data-zoom=\"actual\"]',\n \"zoom-in\": '[data-chrome=\"zoom\"] [data-zoom=\"in\"]',\n \"zoom-fit\": '[data-chrome=\"zoom\"] [data-zoom=\"fit\"]',\n canvas: \".djs-container > svg\",\n primary: '[data-chrome=\"primary\"]',\n pill: '[data-chrome=\"problems\"]',\n};\n\nexport interface TargetFacts {\n /** Viewport coordinates of the centre, for `page.mouse`. */\n client: { x: number; y: number };\n box: RelativeBox;\n /** `aria-label`, else the text. */\n label: string;\n}\n\n/** The first visible match of `selector` inside the root; `null` when there is none. */\nexport const targetProbe = ({ root, selector }: { root: string; selector: string }): TargetFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const element = [...rootElement.querySelectorAll(selector)].find((candidate) => tools.visible(candidate));\n if (!element) return null;\n const rect = element.getBoundingClientRect();\n return {\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n box: tools.box(element, rootElement),\n label: (element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n };\n};\n\nexport async function findTarget(\n page: PageLike,\n root: string,\n target: ChromeTarget,\n): Promise<TargetFacts | null> {\n return inPage(page, targetProbe, { root, selector: CHROME_TARGET_SELECTORS[target] });\n}\n\n/** Focuses the first match of `selector` inside the root; the description of the focused element. */\nexport const focusProbe = ({ root, selector }: { root: string; selector: string }): string | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const element = document.querySelector(root)?.querySelector<HTMLElement | SVGElement>(selector);\n if (!element) return null;\n element.focus();\n return document.activeElement === element ? tools.describe(element) : null;\n};\n\nexport async function focusTarget(\n page: PageLike,\n root: string,\n target: ChromeTarget,\n): Promise<string | null> {\n return inPage(page, focusProbe, { root, selector: CHROME_TARGET_SELECTORS[target] });\n}\n\n/** A visible popup with `role` inside the root (the dropdown, the chrome tooltip). */\nexport interface OverlayFacts {\n box: RelativeBox;\n text: string;\n /** How many visible elements carry the role. */\n count: number;\n id: string;\n}\n\nexport const overlayProbe = ({ root, role }: { root: string; role: string }): OverlayFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const shown = [...rootElement.querySelectorAll(`[role=\"${role}\"]`)].filter((element) =>\n tools.visible(element),\n );\n const first = shown[0];\n if (!first) return null;\n return {\n box: tools.box(first, rootElement),\n text: (first.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n count: shown.length,\n id: first.id,\n };\n};\n\nexport async function findOverlay(\n page: PageLike,\n root: string,\n role: \"menu\" | \"tooltip\",\n): Promise<OverlayFacts | null> {\n return inPage(page, overlayProbe, { root, role });\n}\n\nexport interface PressFacts {\n /** The readout as a whole percentage; `null` without a readout. */\n zoom: number | null;\n keys: RecordedKey[];\n documentKeys: RecordedKey[];\n}\n\n/** After a key press: settles, then reads the readout and takes the keys `window` and `document` saw. */\nexport const afterPressProbe = async ({ root }: { root: string }): Promise<PressFacts> => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n await tools.settle();\n const readout = document\n .querySelector(root)\n ?.querySelector('[data-chrome=\"zoom\"] [data-zoom=\"actual\"]')?.textContent;\n const digits = (readout ?? \"\").replace(/[^0-9]/g, \"\");\n return {\n zoom: digits ? Number(digits) : null,\n keys: tools.keys.splice(0),\n documentKeys: tools.documentKeys.splice(0),\n };\n};\n\n/** Drops what `window` saw so far. */\nexport const clearKeysProbe = (_: null): void => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n tools.keys.splice(0);\n tools.documentKeys.splice(0);\n};\n\nexport type InjectedKind = \"input\" | \"textarea\" | \"contenteditable\" | \"modal\" | \"popover\" | \"focus-target\";\n\n/**\n * Adds a stand-in for what modelers render inside the shell (text fields: an input, a textarea, an\n * editable label; a modal dialog, a popover, a plain focus target), inside the root or, once it is\n * gone, the body; focuses it.\n */\nexport const injectProbe = ({ root, kind }: { root: string; kind: InjectedKind }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const parent = document.querySelector(root) ?? tools.armedRoot ?? document.body;\n const host = parent.isConnected ? parent : document.body;\n const element =\n kind === \"input\" || kind === \"textarea\"\n ? document.createElement(kind)\n : (document.createElement(\"div\") as HTMLElement);\n element.setAttribute(\"data-modeler-shell-conformance\", kind);\n element.style.cssText = \"position:absolute;left:0;top:0;width:40px;height:20px;\";\n if (kind === \"modal\" || kind === \"popover\") {\n element.setAttribute(\"role\", \"dialog\");\n element.setAttribute(\"aria-label\", \"Conformance stand-in\");\n if (kind === \"modal\") element.setAttribute(\"aria-modal\", \"true\");\n }\n if (kind === \"contenteditable\") element.setAttribute(\"contenteditable\", \"true\");\n else if (kind !== \"input\" && kind !== \"textarea\") element.tabIndex = -1;\n host.append(element);\n tools.injected.push(element);\n element.focus();\n return document.activeElement === element;\n};\n\nexport const removeInjectedProbe = (_: null): void => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n for (const element of tools.injected.splice(0)) element.remove();\n for (const cleanup of tools.cleanups.splice(0)) cleanup();\n};\n\n/** Makes the canvas `<svg>` handle `key` (`preventDefault`), as a modeler's own canvas binding would. */\nexport const canvasHandlesProbe = ({ root, key }: { root: string; key: string }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const svg = document.querySelector(root)?.querySelector(\".djs-container > svg\");\n if (!svg) return false;\n const listener = (event: Event) => {\n if ((event as KeyboardEvent).key === key) event.preventDefault();\n };\n svg.addEventListener(\"keydown\", listener);\n tools.cleanups.push(() => svg.removeEventListener(\"keydown\", listener));\n return true;\n};\n\n/** Remembers the root right before `destroy` (its class is gone afterwards) and clears the recorders. */\nexport const armCleanupProbe = ({ root }: { root: string }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (rootElement) tools.armedRoot = rootElement;\n tools.errors.splice(0);\n tools.keys.splice(0);\n tools.documentKeys.splice(0);\n return Boolean(rootElement);\n};\n\n/** What the shell left behind after `destroy`. */\nexport interface LeftoverFacts {\n /** Elements (other than `<html>`) with a `cd-shell*` class. */\n classedElements: string[];\n /** `cd-shell*` classes on `<html>`. */\n documentClasses: string[];\n /** Elements still carrying `data-chrome`. */\n chromeElements: string[];\n /** The remembered root's `class` and attributes. */\n rootClasses: string[];\n rootAttributes: string[];\n errors: string[];\n}\n\nexport const leftoverProbe = (_: null): LeftoverFacts => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const ours = (element: Element) => element.hasAttribute(\"data-modeler-shell-conformance\");\n const shellClass = (name: string) => name.startsWith(\"cd-shell\");\n const root = tools.armedRoot;\n return {\n classedElements: [...document.querySelectorAll(\"[class]\")]\n .filter((element) => element !== document.documentElement && !ours(element))\n .filter((element) => [...element.classList].some(shellClass))\n .map((element) => tools.describe(element)),\n documentClasses: [...document.documentElement.classList].filter(shellClass),\n chromeElements: [...document.querySelectorAll(\"[data-chrome]\")].map((element) => tools.describe(element)),\n rootClasses: root ? [...root.classList].filter(shellClass) : [],\n rootAttributes: root ? root.getAttributeNames() : [],\n errors: [...tools.errors],\n };\n};\n\n/** Puts a foreign page's `<html>` in a mode, as a themed host page around an embedded modeler. */\nexport const hostPageModeProbe = ({ theme, kontrast }: { theme: string; kontrast: string | null }): void => {\n const html = document.documentElement;\n html.setAttribute(\"data-cd-theme\", theme);\n if (kontrast) html.setAttribute(\"data-cd-kontrast\", kontrast);\n else html.removeAttribute(\"data-cd-kontrast\");\n};\n","import {\n CHROME_ISLANDS,\n LEGAL_LINE_HEIGHT,\n PALETTE_CLEARANCE,\n SHELL,\n legalLineHeight,\n toastStackBottom,\n toastStackWidth,\n zoomRowRaised,\n type BottomObstacle,\n type ChromeIsland,\n type Insets,\n type PaletteRow,\n type ShellHost,\n type Size,\n} from \"../core/index.js\";\nimport type { PageLike } from \"./page.js\";\nimport { inPage, type RelativeBox, type ToolWindow } from \"./page-tools.js\";\n\n/** Every island box must match within this many pixels (guide §13.4). */\nexport const GEOMETRY_TOLERANCE_PX = 1;\n\n/**\n * `getBoundingClientRect()` relative to the shell root's padding box, where its absolutely\n * positioned islands anchor (a border on the root, as in a framed foreign page, does not count).\n */\nexport interface IslandBox {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport interface ChromeMeasurement {\n container: Size;\n /** From the root's `data-palette` attribute. */\n paletteRow: PaletteRow;\n /** The visible islands, found by `[data-chrome]`. */\n islands: Partial<Record<ChromeIsland, IslandBox>>;\n /**\n * State attributes of the root: `[data-legend=\"open\"]`, `[data-inspector=\"open\"]`,\n * `[data-problems=\"shown\"]`, and in the web host `[data-empty-state=\"shown\"]`,\n * `[data-primary=\"collapsed\"]` and `[data-zoom-row=\"raised\"]`.\n */\n open: {\n legend: boolean;\n inspector: boolean;\n problems: boolean;\n emptyState: boolean;\n primaryCollapsed: boolean;\n zoomRaised: boolean;\n };\n /** Width of the widest visible toast card (`[data-status]` in the stack); absent without a toast. */\n toastCardWidth?: number;\n}\n\n/** Constraints of one island; every given field must hold within `GEOMETRY_TOLERANCE_PX`. */\nexport interface ExpectedBox {\n left?: number;\n top?: number;\n right?: number;\n bottom?: number;\n width?: number;\n height?: number;\n /** Horizontal centre relative to the root. */\n centerX?: number;\n /** Vertical centre relative to the root (the web app's empty-state card). */\n centerY?: number;\n}\n\nexport const DEFAULT_ROOT = \".cd-shell\";\n\n/** `[−] [NN%] [+] | [Fit]` with a 56px readout (guide §5.1, §5.8): 1+3+32+2+56+2+32+2+5+2+32+3+1. */\nexport const ZOOM_PANEL_WIDTH = 173;\n\n/** Height of one line of the web app's legal line under the bottom-left stack (guide §5.10). */\nexport const LEGAL_LINE = LEGAL_LINE_HEIGHT;\n\n/** The web app's start screen card: `min(400px, 100% − 24px)` wide (guide §8). */\nconst EMPTY_STATE_MAX_WIDTH = 400;\n\n/** The web app's problems list above the pill: `min(320px, 100% − 24px)` wide, at most 320 high (guide §5.10). */\nconst POPOVER_MAX_WIDTH = 320;\nconst POPOVER_MAX_HEIGHT = 320;\n\n/** Minimum width of the legend card (guide §5.10). */\nconst LEGEND_MIN_WIDTH = 184;\n\nconst STATUS_MAX_WIDTH = 560;\nconst DROPDOWN_MAX_WIDTH = 320;\nconst TOOLTIP_MAX_WIDTH = 280;\nconst SHEET_MAX_HEIGHT_SHARE = 0.45;\n\ntype MeasureResult = { error: string } | (ChromeMeasurement & { duplicates: string[] });\n\nconst measureProbe = ({ root, islands }: { root: string; islands: readonly string[] }): MeasureResult => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return { error: `no element matches the shell root selector \"${root}\"` };\n const boxes: Partial<Record<string, RelativeBox>> = {};\n const duplicates: string[] = [];\n for (const element of rootElement.querySelectorAll(\"[data-chrome]\")) {\n const name = element.getAttribute(\"data-chrome\") ?? \"\";\n if (!islands.includes(name) || !tools.visible(element)) continue;\n if (boxes[name]) {\n duplicates.push(name);\n continue;\n }\n boxes[name] = tools.box(element, rootElement);\n }\n const cardWidths = [...rootElement.querySelectorAll<HTMLElement>('[data-chrome=\"toasts\"] > [data-status]')]\n .filter((card) => tools.visible(card))\n .map((card) => card.getBoundingClientRect().width);\n return {\n ...(cardWidths.length > 0 ? { toastCardWidth: Math.max(...cardWidths) } : {}),\n container: tools.container(rootElement),\n paletteRow: rootElement.getAttribute(\"data-palette\") === \"second-row\" ? \"second-row\" : \"top\",\n islands: boxes,\n open: {\n legend: rootElement.getAttribute(\"data-legend\") === \"open\",\n inspector: rootElement.getAttribute(\"data-inspector\") === \"open\",\n problems: rootElement.getAttribute(\"data-problems\") === \"shown\",\n emptyState: rootElement.getAttribute(\"data-empty-state\") === \"shown\",\n primaryCollapsed: rootElement.getAttribute(\"data-primary\") === \"collapsed\",\n zoomRaised: rootElement.getAttribute(\"data-zoom-row\") === \"raised\",\n },\n duplicates,\n };\n};\n\n/** Measures the islands of the shell under `root` (default `.cd-shell`) in the page. */\nexport async function measureChrome(page: PageLike, root: string = DEFAULT_ROOT): Promise<ChromeMeasurement> {\n const result = await inPage(page, measureProbe, { root, islands: CHROME_ISLANDS });\n if (\"error\" in result) throw new Error(`@miragon/modeler-shell conformance: ${result.error}`);\n if (result.duplicates.length > 0) {\n const names = [...new Set(result.duplicates)].map((name) => `[data-chrome=\"${name}\"]`).join(\", \");\n throw new Error(`@miragon/modeler-shell conformance: more than one visible ${names}`);\n }\n return {\n container: result.container,\n paletteRow: result.paletteRow,\n islands: result.islands,\n open: result.open,\n ...(result.toastCardWidth !== undefined ? { toastCardWidth: result.toastCardWidth } : {}),\n };\n}\n\n/** Upper and lower limits the guide gives as \"at least\" and \"at most\" (guide §5.4 to §5.15). */\nexport interface BoxLimits {\n minWidth?: number;\n maxWidth?: number;\n maxHeight?: number;\n minLeft?: number;\n minRight?: number;\n minBottom?: number;\n}\n\n/** What the guide expects of the chrome in a measured state. */\nexport interface ChromeExpectations {\n boxes: Partial<Record<ChromeIsland, ExpectedBox>>;\n limits: Partial<Record<ChromeIsland, BoxLimits>>;\n /** Islands that must be visible. */\n required: ChromeIsland[];\n /** Islands that must not be visible, with the rule that hides them. */\n hidden: Partial<Record<ChromeIsland, string>>;\n}\n\nfunction isNarrow(container: Size): boolean {\n return container.width <= SHELL.narrow;\n}\n\nfunction isVeryNarrow(container: Size): boolean {\n return container.width <= SHELL.veryNarrow;\n}\n\n/** The open inspector is a bottom sheet up to `SHELL.narrow` (guide §5.11). */\nfunction sheetOpen(measurement: ChromeMeasurement): boolean {\n return measurement.open.inspector && isNarrow(measurement.container);\n}\n\n/** The bottom of an island as `toastStackBottom` sees it (guide §8, the shell's rule for the bottom row). */\nexport function bottomObstacle(box: IslandBox, container: Size): BottomObstacle {\n return { left: box.left, right: box.left + box.width, top: container.height - box.top };\n}\n\n/** Why an island of the web column never shows in the IDE and embedded hosts (guide §5.2). */\nconst WEB_ONLY: Partial<Record<ChromeIsland, string>> = {\n primary: \"the top right stays empty in IDE and embedded hosts (guide §5.7)\",\n legal: \"the legal line belongs to the web app; an IDE or an embedding host carries its own (guide §5.2)\",\n \"empty-state\": \"IDE and embedded hosts have no start screen; they show the empty-file hint (guide §13.5)\",\n \"drop-zone\": \"IDE and embedded hosts have no drop zone; their files belong to the host (guide §5.2)\",\n};\n\n/** The work chrome the web app's start screen hides (guide §8: only the card and the legal line show). */\nexport const WORK_CHROME: readonly ChromeIsland[] = [\n \"menu\",\n \"primary\",\n \"palette\",\n \"zoom\",\n \"problems\",\n \"legend\",\n \"status\",\n \"inspector\",\n];\n\n/** The anchors and limits of guide §5.2 to §5.15 for `measurement` in `host`. */\nexport function chromeExpectations(measurement: ChromeMeasurement, host: ShellHost): ChromeExpectations {\n const { container, islands, open, paletteRow } = measurement;\n const { edge, gap, row, free, inspectorWidth } = SHELL;\n const web = host === \"web\";\n const startScreen = web && open.emptyState;\n const raised = web && open.zoomRaised;\n const secondRow = paletteRow === \"second-row\";\n const sheet = sheetOpen(measurement);\n const sideInspector = open.inspector && !isNarrow(container);\n // A narrow container wraps the legal line; the stack above it stands on its whole lines.\n const legalHeight = legalLineHeight(web ? islands.legal?.height : undefined);\n const boxes: Partial<Record<ChromeIsland, ExpectedBox>> = {};\n const limits: Partial<Record<ChromeIsland, BoxLimits>> = {};\n const hidden: Partial<Record<ChromeIsland, string>> = {};\n // Behind the start screen the work chrome is hidden; where it shows anyway, it still stands at its anchor.\n const required: ChromeIsland[] = startScreen ? [\"empty-state\"] : [\"menu\", \"palette\"];\n if (web) required.push(\"legal\");\n\n boxes.menu = { left: edge, top: edge, width: row, height: row };\n\n boxes.palette = { top: secondRow ? free : edge, height: row, centerX: container.width / 2 };\n const menu = islands.menu;\n const primary = web ? islands.primary : undefined;\n if (secondRow) {\n limits.palette = { maxWidth: container.width - 2 * edge };\n } else {\n limits.palette = {};\n if (menu) limits.palette.minLeft = menu.left + menu.width + PALETTE_CLEARANCE;\n // Guide §5.15: 16px to every island of the top row, the primary action included.\n if (primary) limits.palette.minRight = container.width - primary.left + PALETTE_CLEARANCE;\n }\n\n if (sheet) {\n const reason = \"hidden while the inspector is a bottom sheet (guide §5.11)\";\n hidden.zoom = reason;\n hidden.problems = reason;\n hidden.legend = reason;\n } else {\n if (!startScreen) required.push(\"zoom\");\n const legalStack = edge + legalHeight + gap;\n boxes.zoom = { right: edge, bottom: raised ? legalStack : edge, width: ZOOM_PANEL_WIDTH, height: row };\n const stackBase = web ? legalStack : edge;\n if (islands.problems) boxes.problems = { left: edge, bottom: stackBase, height: row };\n if (islands.legend) {\n const besidePill = open.problems ? stackBase + row + gap : stackBase;\n const aboveBottomRow = (raised ? legalStack : edge) + row + gap;\n const bottom = isVeryNarrow(container) ? Math.max(besidePill, aboveBottomRow) : besidePill;\n boxes.legend = { left: edge, bottom };\n limits.legend = { minWidth: LEGEND_MIN_WIDTH };\n }\n }\n\n if (islands.inspector) {\n if (sheet) {\n boxes.inspector = { left: edge, right: edge, bottom: edge };\n limits.inspector = { maxHeight: container.height * SHEET_MAX_HEIGHT_SHARE };\n } else {\n boxes.inspector = { top: free, right: edge, width: inspectorWidth };\n limits.inspector = { minBottom: free };\n }\n }\n\n if (islands.status) {\n const strip = sideInspector ? container.width - edge - inspectorWidth : container.width;\n boxes.status = { top: secondRow ? free + row + edge : free, centerX: strip / 2 };\n limits.status = {\n minLeft: edge,\n maxWidth: Math.min(STATUS_MAX_WIDTH, container.width - 2 * edge),\n };\n }\n\n if (web) {\n if (primary) {\n boxes.primary = { top: edge, right: edge, height: row };\n if (open.primaryCollapsed) boxes.primary.width = row;\n }\n boxes.legal = { left: edge, bottom: edge, height: legalHeight };\n limits.legal = { maxWidth: container.width - 2 * edge };\n if (islands[\"empty-state\"]) {\n boxes[\"empty-state\"] = {\n centerX: container.width / 2,\n centerY: container.height / 2,\n width: Math.min(EMPTY_STATE_MAX_WIDTH, container.width - 2 * edge),\n };\n }\n if (islands[\"drop-zone\"]) boxes[\"drop-zone\"] = { left: edge, top: edge, right: edge, bottom: edge };\n } else {\n Object.assign(hidden, WEB_ONLY);\n }\n\n if (host === \"ide\") {\n hidden.toasts = \"the IDE host shows no toasts; the extension shows the host's notification (guide §13.5)\";\n hidden[\"problems-popover\"] =\n \"the IDE host opens its Problems view, never a list of its own (guide §5.10)\";\n } else {\n if (islands.toasts) {\n const obstacles = ([\"zoom\", \"legal\", \"problems\"] as const).flatMap((name) => {\n const box = islands[name];\n return box ? [bottomObstacle(box, container)] : [];\n });\n boxes.toasts = {\n centerX: container.width / 2,\n width: toastStackWidth(container.width),\n bottom: toastStackBottom({\n containerWidth: container.width,\n obstacles,\n cardWidth: measurement.toastCardWidth,\n }),\n };\n }\n const pill = islands.problems;\n if (pill) {\n boxes[\"problems-popover\"] = { left: edge, bottom: container.height - pill.top + gap };\n limits[\"problems-popover\"] = {\n maxWidth: Math.min(POPOVER_MAX_WIDTH, container.width - 2 * edge),\n maxHeight: POPOVER_MAX_HEIGHT,\n };\n } else {\n hidden[\"problems-popover\"] = \"the problems list opens only above a visible pill (guide §5.10)\";\n }\n }\n\n return { boxes, limits, required, hidden };\n}\n\n/** The boxes guide §5.2–§5.12 expects for what was measured (anchors per host and breakpoint). */\nexport function expectedChromeBoxes(\n measurement: ChromeMeasurement,\n host: ShellHost,\n): Partial<Record<ChromeIsland, ExpectedBox>> {\n return chromeExpectations(measurement, host).boxes;\n}\n\nconst round = (value: number): number => Math.round(value * 10) / 10;\n\nfunction sides(box: IslandBox, container: Size): Required<ExpectedBox> {\n return {\n left: box.left,\n top: box.top,\n right: container.width - box.left - box.width,\n bottom: container.height - box.top - box.height,\n width: box.width,\n height: box.height,\n centerX: box.left + box.width / 2,\n centerY: box.top + box.height / 2,\n };\n}\n\n/** Every field of `expected` that `box` misses by more than `tolerance`, as readable problems. */\nexport function boxMismatches(\n name: string,\n box: IslandBox,\n expected: ExpectedBox,\n container: Size,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const actual = sides(box, container);\n return (Object.keys(expected) as Array<keyof ExpectedBox>).flatMap((field) => {\n const want = expected[field];\n if (want === undefined) return [];\n const have = actual[field];\n return Math.abs(have - want) > tolerance + 1e-6\n ? [`${name}: ${field} is ${round(have)}px, expected ${round(want)}px (±${tolerance}px)`]\n : [];\n });\n}\n\n/** Every limit `box` breaks by more than `tolerance`. */\nexport function limitViolations(\n name: string,\n box: IslandBox,\n limits: BoxLimits,\n container: Size,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const actual = sides(box, container);\n const problems: string[] = [];\n const atLeast = (field: string, have: number, limit: number | undefined) => {\n if (limit !== undefined && have < limit - tolerance - 1e-6) {\n problems.push(`${name}: ${field} is ${round(have)}px, at least ${round(limit)}px expected`);\n }\n };\n const atMost = (field: string, have: number, limit: number | undefined) => {\n if (limit !== undefined && have > limit + tolerance + 1e-6) {\n problems.push(`${name}: ${field} is ${round(have)}px, at most ${round(limit)}px expected`);\n }\n };\n atLeast(\"width\", actual.width, limits.minWidth);\n atMost(\"width\", actual.width, limits.maxWidth);\n atMost(\"height\", actual.height, limits.maxHeight);\n atLeast(\"left\", actual.left, limits.minLeft);\n atLeast(\"right\", actual.right, limits.minRight);\n atLeast(\"bottom\", actual.bottom, limits.minBottom);\n return problems;\n}\n\n/**\n * Every deviation of a measured state from guide §5.2 to §5.15: missing and unexpected islands,\n * boxes and limits, the palette row decision and the root's state attributes.\n */\nexport function geometryProblems(\n measurement: ChromeMeasurement,\n host: ShellHost,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const { container, islands, open, paletteRow } = measurement;\n const expectations = chromeExpectations(measurement, host);\n const problems: string[] = [];\n const sheet = sheetOpen(measurement);\n\n for (const name of expectations.required) {\n if (!islands[name]) problems.push(`${name}: [data-chrome=\"${name}\"] is missing or not visible`);\n }\n for (const name of CHROME_ISLANDS) {\n const box = islands[name];\n if (!box) continue;\n const expected = expectations.boxes[name];\n if (!expected) {\n const reason = expectations.hidden[name] ?? \"no anchor of the guide applies\";\n problems.push(`${name}: visible, but ${reason}`);\n continue;\n }\n problems.push(...boxMismatches(name, box, expected, container, tolerance));\n const limits = expectations.limits[name];\n if (limits) problems.push(...limitViolations(name, box, limits, container, tolerance));\n }\n\n if (isNarrow(container) && paletteRow !== \"second-row\") {\n problems.push(\n `palette: data-palette=\"${paletteRow}\" in a ${round(container.width)}px wide container; up to ${SHELL.narrow}px it is \"second-row\" (guide §5.15)`,\n );\n }\n const palette = islands.palette;\n const menu = islands.menu;\n const primary = host === \"web\" ? islands.primary : undefined;\n if (paletteRow === \"second-row\" && !isNarrow(container) && palette && menu) {\n const clipped = palette.width >= container.width - 2 * SHELL.edge - tolerance;\n const topRowLeft = (container.width - palette.width) / 2;\n const toMenu = topRowLeft - menu.left - menu.width;\n // Guide §5.15: the primary action loses its label before the palette moves, so it counts icon only.\n const toPrimary = primary\n ? container.width - SHELL.edge - SHELL.row - (topRowLeft + palette.width)\n : Number.POSITIVE_INFINITY;\n const fits = toMenu >= PALETTE_CLEARANCE + tolerance && toPrimary >= PALETTE_CLEARANCE + tolerance;\n if (!clipped && fits) {\n const kept = primary\n ? `${round(toMenu)}px to the menu trigger and ${round(toPrimary)}px to the primary action's icon`\n : `${round(toMenu)}px to the menu trigger`;\n problems.push(\n `palette: in the second row although the top row keeps ${kept} (at least ${PALETTE_CLEARANCE}px suffice, guide §5.15)`,\n );\n }\n }\n\n const state = (island: ChromeIsland, flag: boolean, attribute: string, hiddenBySheet: boolean) => {\n const shown = Boolean(islands[island]);\n if (flag && !shown && !hiddenBySheet) {\n problems.push(`${island}: the root carries ${attribute}, but the island is not visible`);\n }\n if (!flag && shown) problems.push(`${island}: visible, but the root lacks ${attribute}`);\n };\n state(\"problems\", open.problems, 'data-problems=\"shown\"', sheet || open.emptyState);\n state(\"legend\", open.legend, 'data-legend=\"open\"', sheet || open.emptyState);\n state(\"inspector\", open.inspector, 'data-inspector=\"open\"', open.emptyState);\n state(\"empty-state\", open.emptyState, 'data-empty-state=\"shown\"', false);\n problems.push(...webRowProblems(measurement, host, tolerance));\n\n return problems;\n}\n\n/**\n * The web app's state attributes for its top and bottom rows: `data-primary=\"collapsed\"` only with\n * a visible primary action, and `data-zoom-row=\"raised\"` exactly when the zoom panel at\n * `bottom: 12px` would keep less than 8px to the legal line (`zoomRowRaised`, the shell's rule).\n */\nexport function webRowProblems(\n measurement: ChromeMeasurement,\n host: ShellHost,\n tolerance: number = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const { container, islands, open } = measurement;\n const problems: string[] = [];\n if (host !== \"web\") {\n if (open.primaryCollapsed)\n problems.push('primary: the root carries data-primary=\"collapsed\" outside the web app');\n if (open.zoomRaised) problems.push('zoom: the root carries data-zoom-row=\"raised\" outside the web app');\n return problems;\n }\n if (open.primaryCollapsed && !islands.primary && !open.emptyState) {\n problems.push('primary: the root carries data-primary=\"collapsed\", but no primary action is visible');\n }\n const legal = islands.legal;\n const zoom = islands.zoom;\n if (legal && zoom) {\n const legalRight = legal.left + legal.width;\n const gap = container.width - SHELL.edge - zoom.width - legalRight;\n const raised = zoomRowRaised({ containerWidth: container.width, legalRight, zoomWidth: zoom.width });\n // A gap within the tolerance of the 8px limit may go either way.\n const borderline = Math.abs(gap - SHELL.gap) <= tolerance;\n if (raised && !open.zoomRaised && !borderline) {\n problems.push(\n `zoom: ${round(gap)}px between the legal line and the zoom panel, but the root lacks data-zoom-row=\"raised\" (below ${SHELL.gap}px the zoom panel stands above the legal line)`,\n );\n }\n if (!raised && open.zoomRaised && !borderline) {\n problems.push(\n `zoom: the root carries data-zoom-row=\"raised\" although the zoom panel keeps ${round(gap)}px to the legal line (at least ${SHELL.gap}px)`,\n );\n }\n }\n return problems;\n}\n\n/**\n * The fit insets of guide §5.9 for what was measured, recomputed from the guide's table: top 88\n * (second row 140), sides 24, bottom 64 (web app with the pill or the zoom panel raised above the\n * legal line 92); right 12 + 288 + 24 with a side\n * inspector; left 12 + legend width + 24 with an open legend in a container wider than 440px; with\n * a bottom sheet the bottom is the distance to its top edge plus 12, and the legend does not count.\n */\nexport function expectedFitInsets(measurement: ChromeMeasurement, host: ShellHost): Insets {\n const { container, islands, open, paletteRow } = measurement;\n const insets: Insets = {\n top: paletteRow === \"second-row\" ? SHELL.fitInsetTopSecondRow : SHELL.fitInsetTop,\n right: SHELL.fitInsetSide,\n bottom:\n host === \"web\" && (open.problems || open.zoomRaised)\n ? SHELL.fitInsetBottomWeb + legalLineHeight(islands.legal?.height) - LEGAL_LINE\n : SHELL.fitInsetBottom,\n left: SHELL.fitInsetSide,\n };\n if (sheetOpen(measurement)) {\n const sheet = islands.inspector;\n insets.bottom = sheet ? container.height - sheet.top + SHELL.edge : SHELL.fitInsetBottom;\n return insets;\n }\n if (open.inspector) insets.right = SHELL.edge + SHELL.inspectorWidth + SHELL.fitInsetSide;\n const legend = islands.legend;\n if (open.legend && legend && legend.width > 0 && container.width > SHELL.veryNarrow) {\n insets.left = SHELL.edge + legend.width + SHELL.fitInsetSide;\n }\n return insets;\n}\n\n/** A rectangle relative to the shell root's padding box, by its edges. */\nexport interface Rectangle {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/**\n * The free rectangle of guide §5.9: the container minus `expectedFitInsets`. Where the insets\n * leave no room on an axis, that axis spans the whole container (as the fit centres there).\n */\nexport function freeRectangle(measurement: ChromeMeasurement, host: ShellHost): Rectangle {\n const { container } = measurement;\n const insets = expectedFitInsets(measurement, host);\n const horizontal = container.width - insets.left - insets.right > 0;\n const vertical = container.height - insets.top - insets.bottom > 0;\n return {\n left: horizontal ? insets.left : 0,\n top: vertical ? insets.top : 0,\n right: horizontal ? container.width - insets.right : container.width,\n bottom: vertical ? container.height - insets.bottom : container.height,\n };\n}\n\n/** Where the dropdown opens (guide §5.4): under the trigger, at least 248px, inside the container. */\nexport function dropdownProblems(\n box: IslandBox,\n container: Size,\n tolerance = GEOMETRY_TOLERANCE_PX,\n): string[] {\n const { edge, gap, row, menuMinWidth } = SHELL;\n return [\n ...boxMismatches(\"dropdown\", box, { top: edge + row + gap, left: edge }, container, tolerance),\n ...limitViolations(\n \"dropdown\",\n box,\n {\n minWidth: menuMinWidth,\n maxWidth: Math.min(DROPDOWN_MAX_WIDTH, container.width - 2 * edge),\n minBottom: edge,\n },\n container,\n tolerance,\n ),\n ];\n}\n\n/** Which island a tooltip belongs to decides its row (guide §5.6). */\nexport type TooltipRow = \"top\" | \"second-row\" | \"bottom\";\n\n/**\n * Where the chrome tooltip of a control stands (guide §5.6): 8px below the top row (`top: 60px`)\n * or the second row (`top: 112px`), 8px above the bottom row (`bottom: 60px`, above the web app's\n * raised zoom row `bottom: 88px`: give its `bottomRow` of 40); centred on its control and shifted\n * to keep 12px to the sides.\n */\nexport function tooltipProblems(\n tooltip: IslandBox,\n anchor: IslandBox,\n row: TooltipRow,\n container: Size,\n tolerance = GEOMETRY_TOLERANCE_PX,\n bottomRow: number = SHELL.edge,\n): string[] {\n const { edge, gap, row: rowHeight, free } = SHELL;\n const clamp = (centred: number) =>\n Math.max(edge, Math.min(centred, container.width - edge - tooltip.width));\n const expectedAt = (left: number): ExpectedBox =>\n row === \"bottom\"\n ? { left, bottom: bottomRow + rowHeight + gap }\n : { left, top: (row === \"top\" ? edge : free) + rowHeight + gap };\n let mismatches = boxMismatches(\n \"tooltip\",\n tooltip,\n expectedAt(clamp(anchor.left + anchor.width / 2 - tooltip.width / 2)),\n container,\n tolerance,\n );\n // Guide §5.15 reads \"mittig im Container\" for the second row; until the guide settles whether\n // that means the container or the entry, either centre conforms.\n if (row === \"second-row\" && mismatches.length > 0) {\n const inContainer = boxMismatches(\n \"tooltip\",\n tooltip,\n expectedAt(clamp(container.width / 2 - tooltip.width / 2)),\n container,\n tolerance,\n );\n if (inContainer.length === 0) mismatches = inContainer;\n }\n return [\n ...mismatches,\n ...limitViolations(\n \"tooltip\",\n tooltip,\n { minLeft: edge, minRight: edge, maxWidth: Math.min(TOOLTIP_MAX_WIDTH, container.width - 2 * edge) },\n container,\n tolerance,\n ),\n ];\n}\n","import type { ElementFacts, RelativeBox, ToolWindow } from \"./page-tools.js\";\n\n/*\n * Snapshots the cases judge in Node (`checks.ts`). Each probe runs in the page and must stay\n * self-contained (see page-tools.ts).\n */\n\nexport type ZoomButton = \"out\" | \"actual\" | \"in\" | \"fit\";\n\n/**\n * The chrome parts in the DOM (and tab) order of guide §5.14; the web app adds the primary action\n * after the menu trigger, the start screen card after the hint, the legal line before the zoom\n * panel and the toast stack last (API.md, Web host).\n */\nexport const DOM_ORDER = [\n \"menu\",\n \"primary\",\n \"palette\",\n \"canvas\",\n \"status\",\n \"hint\",\n \"empty-state\",\n \"inspector\",\n \"problems\",\n \"legend\",\n \"legal\",\n \"zoom\",\n \"toasts\",\n] as const;\n\nexport type OrderedPart = (typeof DOM_ORDER)[number];\n\nexport interface PaletteEntryFacts extends ElementFacts {\n group: string | null;\n}\n\n/** A link of the web app's legal line. */\nexport interface LinkFacts {\n text: string;\n href: string;\n lang: string | null;\n target: string | null;\n rel: string | null;\n}\n\nexport interface AriaFacts {\n platform: \"mac\" | \"other\";\n documentLang: string;\n rootLang: string | null;\n trigger: ElementFacts | null;\n /** The element the trigger's `aria-controls` names. */\n controlled: ElementFacts | null;\n palette: ElementFacts | null;\n toolbar: ElementFacts | null;\n /** The focusable canvas `<svg>` (`.djs-container > svg`). */\n canvas: ElementFacts | null;\n entries: PaletteEntryFacts[];\n zoom: ElementFacts | null;\n zoomButtons: Partial<Record<ZoomButton, ElementFacts>>;\n /** The parts that exist, in DOM order. */\n order: OrderedPart[];\n /** Elements inside the root with a positive `tabindex`. */\n positiveTabindex: string[];\n /** Chrome controls with a native `title` tooltip. */\n titled: string[];\n problems: ElementFacts | null;\n status: ElementFacts | null;\n legend: ElementFacts | null;\n /** Text of the legend's `aria-labelledby` targets. */\n legendTitle: string | null;\n legendClose: ElementFacts | null;\n inspector: ElementFacts | null;\n /** The web app's primary action (`[data-chrome=\"primary\"]`). */\n primary: ElementFacts | null;\n /** The root's `data-primary=\"collapsed\"`. */\n primaryCollapsed: boolean;\n /** The web app's legal line and its links, in order. */\n legal: ElementFacts | null;\n legalLinks: LinkFacts[];\n /** The element the pill's `aria-controls` names (the web app's problems list). */\n problemsControlled: ElementFacts | null;\n}\n\nexport const ariaProbe = ({ root }: { root: string }): AriaFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const find = (selector: string) => rootElement.querySelector(selector);\n const factsOf = (element: Element | null | undefined) => (element ? tools.facts(element) : null);\n const navigatorLike = navigator as Navigator & { userAgentData?: { platform?: string } };\n const trigger = find('[data-chrome=\"menu\"]');\n const controlsId = trigger?.getAttribute(\"aria-controls\");\n const palette = find('[data-chrome=\"palette\"]');\n const toolbar =\n palette?.querySelector('[role=\"toolbar\"]') ?? palette?.querySelector(\".djs-palette-entries\");\n const zoom = find('[data-chrome=\"zoom\"]');\n const zoomButtons: Partial<Record<ZoomButton, ElementFacts>> = {};\n for (const name of [\"out\", \"actual\", \"in\", \"fit\"] as const) {\n const button = zoom?.querySelector(`[data-zoom=\"${name}\"]`);\n if (button) zoomButtons[name] = tools.facts(button);\n }\n const legend = find('[data-chrome=\"legend\"]');\n const labelledBy = legend?.getAttribute(\"aria-labelledby\");\n const legal = find('[data-chrome=\"legal\"]');\n const pillControls = find('[data-chrome=\"problems\"]')?.getAttribute(\"aria-controls\");\n const parts: Array<[string, Element | null]> = [\n [\"menu\", trigger],\n [\"primary\", find('[data-chrome=\"primary\"]')],\n [\"palette\", palette],\n [\"canvas\", find(\".djs-container > svg\")],\n [\"status\", find('[data-chrome=\"status\"]')],\n [\"hint\", find(\".cd-shell-hint\")],\n [\"inspector\", find('[data-chrome=\"inspector\"]')],\n [\"problems\", find('[data-chrome=\"problems\"]')],\n [\"empty-state\", find('[data-chrome=\"empty-state\"]')],\n [\"legend\", legend],\n [\"legal\", find('[data-chrome=\"legal\"]')],\n [\"zoom\", zoom],\n [\"toasts\", find('[data-chrome=\"toasts\"]')],\n ];\n const present = parts.filter((part): part is [string, Element] => part[1] !== null);\n present.sort(([, a], [, b]) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n const titledSelector = [\n '[data-chrome=\"menu\"][title]',\n '[data-chrome=\"primary\"][title]',\n '[data-chrome=\"palette\"] [data-action][title]',\n '[data-chrome=\"zoom\"] [title]',\n '[data-chrome=\"problems\"][title]',\n ].join(\", \");\n return {\n platform: /mac/i.test(navigatorLike.userAgentData?.platform ?? navigatorLike.platform ?? \"\")\n ? \"mac\"\n : \"other\",\n documentLang: document.documentElement.lang,\n rootLang: rootElement.getAttribute(\"lang\"),\n trigger: factsOf(trigger),\n controlled: factsOf(controlsId ? document.getElementById(controlsId) : null),\n palette: factsOf(palette),\n toolbar: factsOf(toolbar),\n canvas: factsOf(find(\".djs-container > svg\")),\n entries: [...(palette?.querySelectorAll(\"[data-action]\") ?? [])].map((entry) => ({\n ...tools.facts(entry),\n group: entry.closest(\"[data-group]\")?.getAttribute(\"data-group\") ?? null,\n })),\n zoom: factsOf(zoom),\n zoomButtons,\n order: present.map(([name]) => name) as OrderedPart[],\n positiveTabindex: [...rootElement.querySelectorAll(\"[tabindex]\")]\n .filter((element) => Number(element.getAttribute(\"tabindex\")) > 0)\n .map((element) => `${tools.describe(element)} (tabindex=\"${element.getAttribute(\"tabindex\")}\")`),\n titled: [...rootElement.querySelectorAll(titledSelector)].map((element) => tools.describe(element)),\n problems: factsOf(find('[data-chrome=\"problems\"]')),\n status: factsOf(find('[data-chrome=\"status\"]')),\n legend: factsOf(legend),\n legendTitle: labelledBy\n ? labelledBy\n .split(/\\s+/)\n .map((id) => document.getElementById(id)?.textContent?.trim() ?? \"\")\n .join(\" \")\n .trim()\n : null,\n legendClose: factsOf(legend?.querySelector(\"button\")),\n inspector: factsOf(find('[data-chrome=\"inspector\"]')),\n primary: factsOf(find('[data-chrome=\"primary\"]')),\n primaryCollapsed: rootElement.getAttribute(\"data-primary\") === \"collapsed\",\n legal: factsOf(legal),\n legalLinks: [...(legal?.querySelectorAll(\"a\") ?? [])].map((link) => ({\n text: (link.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n href: link.getAttribute(\"href\") ?? \"\",\n lang: link.getAttribute(\"lang\"),\n target: link.getAttribute(\"target\"),\n rel: link.getAttribute(\"rel\"),\n })),\n problemsControlled: factsOf(pillControls ? document.getElementById(pillControls) : null),\n };\n};\n\nexport interface MenuItemFacts {\n role: string;\n name: string;\n checked: string | null;\n disabled: string | null;\n haspopup: string | null;\n /** `aria-label` of the enclosing `role=\"group\"`; `null` outside a group. */\n group: string | null;\n}\n\nexport interface MenuFacts {\n /** The trigger's `aria-expanded` and `aria-controls`. */\n expanded: string | null;\n controls: string | null;\n /** The visible `role=\"menu\"` inside the root. */\n menu: ElementFacts | null;\n items: MenuItemFacts[];\n /** Index of the focused item; -1 when the focus is elsewhere. */\n active: number;\n activeIsTrigger: boolean;\n}\n\nexport const menuProbe = ({ root }: { root: string }): MenuFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const trigger = rootElement.querySelector('[data-chrome=\"menu\"]');\n const menu =\n [...rootElement.querySelectorAll('[role=\"menu\"]')].find((element) => tools.visible(element)) ?? null;\n const items = menu\n ? [\n ...menu.querySelectorAll('[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]'),\n ].filter((item) => tools.visible(item))\n : [];\n return {\n expanded: trigger?.getAttribute(\"aria-expanded\") ?? null,\n controls: trigger?.getAttribute(\"aria-controls\") ?? null,\n menu: menu ? tools.facts(menu) : null,\n items: items.map((item) => {\n const group = item.closest('[role=\"group\"]');\n return {\n role: item.getAttribute(\"role\") ?? \"\",\n name: (item.getAttribute(\"aria-label\") ?? item.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n checked: item.getAttribute(\"aria-checked\"),\n disabled: item.getAttribute(\"aria-disabled\"),\n haspopup: item.getAttribute(\"aria-haspopup\"),\n group: group && menu?.contains(group) ? (group.getAttribute(\"aria-label\") ?? \"\") : null,\n };\n }),\n active: items.findIndex((item) => item === document.activeElement),\n activeIsTrigger: Boolean(trigger) && document.activeElement === trigger,\n };\n};\n\nexport interface PaletteFocusFacts {\n /** `data-action` of every entry, in order. */\n entries: string[];\n /** Entries with `tabindex=\"0\"`. */\n tabStops: string[];\n /** `data-action` of the focused entry; `null` when the focus is elsewhere. */\n active: string | null;\n}\n\nexport const paletteFocusProbe = ({ root }: { root: string }): PaletteFocusFacts | null => {\n const palette = document.querySelector(root)?.querySelector('[data-chrome=\"palette\"]');\n if (!palette) return null;\n const entries = [...palette.querySelectorAll(\"[data-action]\")];\n const active = document.activeElement;\n return {\n entries: entries.map((entry) => entry.getAttribute(\"data-action\") ?? \"\"),\n tabStops: entries\n .filter((entry) => entry.getAttribute(\"tabindex\") === \"0\")\n .map((entry) => entry.getAttribute(\"data-action\") ?? \"\"),\n active: active && entries.includes(active) ? active.getAttribute(\"data-action\") : null,\n };\n};\n\nexport const zoomButtonsProbe = ({ root }: { root: string }): Partial<Record<ZoomButton, ElementFacts>> => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const zoom = document.querySelector(root)?.querySelector('[data-chrome=\"zoom\"]');\n const buttons: Partial<Record<ZoomButton, ElementFacts>> = {};\n for (const name of [\"out\", \"actual\", \"in\", \"fit\"] as const) {\n const button = zoom?.querySelector(`[data-zoom=\"${name}\"]`);\n if (button) buttons[name] = tools.facts(button);\n }\n return buttons;\n};\n\n/** The design-system roles whose resolved values must agree on every part (no half-dark). */\nexport const MODE_ROLES = [\"--cd-ui-grund\", \"--cd-ui-text\", \"--cd-ui-flaeche-hoch\", \"--cd-ui-linie\"] as const;\n\nexport interface ModeFacts {\n name: string;\n description: string;\n colorScheme: string;\n roles: Record<string, string>;\n}\n\nexport interface ThemedElementFacts {\n description: string;\n isDocument: boolean;\n /** Where it sits relative to the shell root. */\n relation: \"self\" | \"ancestor\" | \"descendant\" | \"elsewhere\";\n theme: string | null;\n kontrast: string | null;\n}\n\nexport interface AppearanceFacts {\n documentClasses: string[];\n /** Every element with `data-cd-theme` or `data-cd-kontrast`. */\n themed: ThemedElementFacts[];\n /** Root, canvas, every visible island, the open dropdown and the visible tooltip. */\n parts: ModeFacts[];\n}\n\nexport const appearanceProbe = ({\n root,\n roles,\n}: {\n root: string;\n roles: readonly string[];\n}): AppearanceFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const mode = (name: string, element: Element) => {\n const style = getComputedStyle(element);\n const resolved: Record<string, string> = {};\n for (const role of roles) resolved[role] = style.getPropertyValue(role).trim();\n return { name, description: tools.describe(element), colorScheme: style.colorScheme, roles: resolved };\n };\n const parts = [mode(\"root\", rootElement)];\n const canvas = rootElement.querySelector(\".djs-container\");\n if (canvas) parts.push(mode(\"canvas\", canvas));\n for (const island of rootElement.querySelectorAll(\"[data-chrome]\")) {\n if (tools.visible(island)) parts.push(mode(island.getAttribute(\"data-chrome\") ?? \"island\", island));\n }\n for (const [name, role] of [\n [\"dropdown\", \"menu\"],\n [\"tooltip\", \"tooltip\"],\n ] as const) {\n const popup = [...rootElement.querySelectorAll(`[role=\"${role}\"]`)].find((element) =>\n tools.visible(element),\n );\n if (popup) parts.push(mode(name, popup));\n }\n return {\n documentClasses: [...document.documentElement.classList],\n themed: [...document.querySelectorAll(\"[data-cd-theme], [data-cd-kontrast]\")].map((element) => ({\n description: tools.describe(element),\n isDocument: element === document.documentElement,\n relation:\n element === rootElement\n ? \"self\"\n : element.contains(rootElement)\n ? \"ancestor\"\n : rootElement.contains(element)\n ? \"descendant\"\n : \"elsewhere\",\n theme: element.getAttribute(\"data-cd-theme\"),\n kontrast: element.getAttribute(\"data-cd-kontrast\"),\n })),\n parts,\n };\n};\n\n/** The element with the focus, classified for the tab-sequence check. */\nexport const activeStopProbe = ({ root }: { root: string }): { description: string; kind: string } => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const active = document.activeElement;\n const rootElement = document.querySelector(root);\n if (!active || active === document.body || !rootElement) return { description: \"<body>\", kind: \"other\" };\n const description = tools.describe(active);\n if (!rootElement.contains(active))\n return { description: `${description} outside the shell root`, kind: \"other\" };\n if (active.matches('[data-chrome=\"palette\"] [data-action]')) return { description, kind: \"palette\" };\n if (active.matches(\".djs-container > svg\")) return { description, kind: \"canvas\" };\n if (active.closest('[data-chrome=\"primary\"]')) return { description, kind: \"primary\" };\n const tabindex = active.getAttribute(\"tabindex\");\n return {\n description: tabindex === null ? description : `${description}[tabindex=\"${tabindex}\"]`,\n kind: \"other\",\n };\n};\n\n/** The focused palette entry, its `aria-keyshortcuts` and the chip of the visible tooltip. */\nexport const paletteShortcutProbe = ({\n root,\n}: {\n root: string;\n}): { action: string; chip: string; keyShortcuts: string | null } | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector(root);\n const active = document.activeElement;\n if (!rootElement || !active?.matches('[data-chrome=\"palette\"] [data-action]')) return null;\n const tooltip = [...rootElement.querySelectorAll('[role=\"tooltip\"]')].find((element) =>\n tools.visible(element),\n );\n const chip = tooltip\n ? [...tooltip.querySelectorAll(\"kbd\")].find((element) => tools.visible(element))\n : undefined;\n return {\n action: active.getAttribute(\"data-action\") ?? \"\",\n chip: (chip?.textContent ?? \"\").trim(),\n keyShortcuts: active.getAttribute(\"aria-keyshortcuts\"),\n };\n};\n\n/** The canvas surround (guide §10.1) and the role it must show. */\nexport interface SurroundFacts {\n /** Whether the root holds a `.djs-container`. */\n container: boolean;\n /** The first element from `.djs-container` out to the root that paints a background colour. */\n painted: { description: string; color: string } | null;\n /** `--cd-ui-grund` resolved to a computed colour inside the root. */\n grund: string;\n}\n\nexport const surroundProbe = ({ root }: { root: string }): SurroundFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const transparent = (color: string): boolean => {\n if (color === \"\" || color === \"transparent\") return true;\n const legacy = /^rgba\\([^)]*,\\s*([\\d.]+)\\)$/.exec(color);\n if (legacy) return Number(legacy[1]) === 0;\n const modern = /\\/\\s*([\\d.]+)%?\\s*\\)$/.exec(color);\n return modern ? Number(modern[1]) === 0 : false;\n };\n const start = rootElement.querySelector(\".djs-container\");\n let painted: SurroundFacts[\"painted\"] = null;\n for (let node: Element | null = start; node && !painted; node = node.parentElement) {\n const color = getComputedStyle(node).backgroundColor;\n if (!transparent(color)) painted = { description: tools.describe(node), color };\n if (node === rootElement) break;\n }\n const probe = document.createElement(\"span\");\n probe.setAttribute(\"data-modeler-shell-conformance\", \"role-probe\");\n probe.style.cssText = \"position:absolute;visibility:hidden;background-color:var(--cd-ui-grund);\";\n rootElement.append(probe);\n const grund = getComputedStyle(probe).backgroundColor;\n probe.remove();\n return { container: start !== null, painted, grund };\n};\n\n/** One visible palette entry, as the keyboard walk and the read-only lock read it. */\nexport interface PaletteEntryState {\n action: string;\n /** `data-group` of the enclosing `.group`; `null` outside one. */\n group: string | null;\n pressed: boolean;\n disabled: boolean;\n /** Viewport coordinates of the centre, for `page.mouse`. */\n client: { x: number; y: number };\n}\n\nexport const paletteEntriesProbe = ({ root }: { root: string }): PaletteEntryState[] => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const palette = document.querySelector(root)?.querySelector('[data-chrome=\"palette\"]');\n if (!palette) return [];\n return [...palette.querySelectorAll(\"[data-action]\")]\n .filter((entry) => tools.visible(entry))\n .map((entry) => {\n const rect = entry.getBoundingClientRect();\n return {\n action: entry.getAttribute(\"data-action\") ?? \"\",\n group: entry.closest(\"[data-group]\")?.getAttribute(\"data-group\") ?? null,\n pressed: entry.getAttribute(\"aria-pressed\") === \"true\",\n disabled: entry.getAttribute(\"aria-disabled\") === \"true\",\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n };\n });\n};\n\n/** The computed colours of one visible palette entry and of its icon. */\nexport interface PaletteColorEntry extends Omit<PaletteEntryState, \"client\"> {\n hovered: boolean;\n color: string;\n /** The entry's `<svg>`, else its `::before` when that has content; `null` for an image or a text entry. */\n icon: { kind: \"svg\" | \"::before\"; color: string } | null;\n}\n\nexport interface PaletteColorFacts {\n /** The roles of guide §5.5 and §13.5, resolved to computed colours inside the palette. */\n roles: { text: string; interaktion: string; textLeise: string };\n entries: PaletteColorEntry[];\n}\n\nexport const paletteColorProbe = ({ root }: { root: string }): PaletteColorFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const palette = document.querySelector(root)?.querySelector('[data-chrome=\"palette\"]');\n if (!palette) return null;\n const resolve = (role: string): string => {\n const probe = document.createElement(\"span\");\n probe.setAttribute(\"data-modeler-shell-conformance\", \"role-probe\");\n probe.style.cssText = `position:absolute;visibility:hidden;color:var(${role});`;\n palette.append(probe);\n const color = getComputedStyle(probe).color;\n probe.remove();\n return color;\n };\n const iconOf = (entry: Element): PaletteColorEntry[\"icon\"] => {\n const svg = entry.querySelector(\"svg\");\n if (svg) return { kind: \"svg\", color: getComputedStyle(svg).color };\n const before = getComputedStyle(entry, \"::before\");\n if (before.content && before.content !== \"none\" && before.content !== \"normal\") {\n return { kind: \"::before\", color: before.color };\n }\n return null;\n };\n return {\n roles: {\n text: resolve(\"--cd-ui-text\"),\n interaktion: resolve(\"--cd-ui-interaktion\"),\n textLeise: resolve(\"--cd-ui-text-leise\"),\n },\n entries: [...palette.querySelectorAll(\"[data-action]\")]\n .filter((entry) => tools.visible(entry))\n .map((entry) => ({\n action: entry.getAttribute(\"data-action\") ?? \"\",\n group: entry.closest(\"[data-group]\")?.getAttribute(\"data-group\") ?? null,\n pressed: entry.getAttribute(\"aria-pressed\") === \"true\",\n disabled: entry.getAttribute(\"aria-disabled\") === \"true\",\n hovered: entry.matches(\":hover\"),\n color: getComputedStyle(entry).color,\n icon: iconOf(entry),\n })),\n };\n};\n\n/** One diagram-js shape on the canvas (`.djs-shape[data-element-id]`). */\nexport interface ShapeFacts {\n id: string;\n /** diagram-js's selection marker on the shape's `<g>`. */\n selected: boolean;\n /** The `<g>`'s `transform` (its position in the diagram, unaffected by panning). */\n transform: string;\n /** Size of its `.djs-visual` in diagram units. */\n size: { width: number; height: number };\n /** Its `.djs-visual` relative to the root's padding box. */\n box: RelativeBox;\n /** Viewport coordinates of the centre, for `page.mouse`. */\n client: { x: number; y: number };\n /** Whether a pointer at the centre reaches the shape and not chrome above it. */\n hit: boolean;\n}\n\nexport const shapesProbe = ({ root }: { root: string }): ShapeFacts[] => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return [];\n return [...rootElement.querySelectorAll<SVGGraphicsElement>(\".djs-container .djs-shape[data-element-id]\")]\n .filter((shape) => tools.visible(shape))\n .map((shape) => {\n const visual = shape.querySelector<SVGGraphicsElement>(\".djs-visual\") ?? shape;\n const rect = visual.getBoundingClientRect();\n const client = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };\n const local = typeof visual.getBBox === \"function\" ? visual.getBBox() : rect;\n const hitElement = document.elementFromPoint(client.x, client.y);\n return {\n id: shape.getAttribute(\"data-element-id\") ?? \"\",\n selected: shape.classList.contains(\"selected\"),\n transform: shape.getAttribute(\"transform\") ?? \"\",\n size: { width: local.width, height: local.height },\n box: tools.box(visual, rootElement),\n client,\n hit: hitElement !== null && shape.contains(hitElement),\n };\n });\n};\n\n/** What the canvas offers at the moment: focus, context pad, open text fields. */\nexport interface CanvasStateFacts {\n /** The focus is inside `.djs-container` (the `<svg>` or a label editor). */\n focusInCanvas: boolean;\n focused: string;\n /** Visible entries of a diagram-js context pad. */\n contextPadEntries: string[];\n /** Visible text fields inside `.djs-container` (a label editor), the kit's stand-ins aside. */\n textFields: string[];\n}\n\nexport const canvasStateProbe = ({ root }: { root: string }): CanvasStateFacts => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const container = document.querySelector(root)?.querySelector(\".djs-container\");\n const active = document.activeElement;\n const ours = (element: Element) => element.closest(\"[data-modeler-shell-conformance]\") !== null;\n const visibleIn = (selector: string) =>\n container\n ? [...container.querySelectorAll(selector)].filter(\n (element) => !ours(element) && tools.visible(element),\n )\n : [];\n return {\n focusInCanvas: Boolean(container && active && container.contains(active)),\n focused: !active || active === document.body ? \"<body>\" : tools.describe(active),\n contextPadEntries: visibleIn(\".djs-context-pad .entry\").map(\n (entry) => entry.getAttribute(\"data-action\") ?? tools.describe(entry),\n ),\n textFields: visibleIn('input, textarea, [contenteditable]:not([contenteditable=\"false\"])').map((field) =>\n tools.describe(field),\n ),\n };\n};\n\n/** The read-only marks of the root and the status box (guide §5.12, §13.5). */\nexport interface ReadOnlyStateFacts {\n readOnly: boolean;\n status: ElementFacts | null;\n}\n\nexport const readOnlyStateProbe = ({ root }: { root: string }): ReadOnlyStateFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector(root);\n if (!rootElement) return null;\n const status = rootElement.querySelector('[data-chrome=\"status\"]');\n return { readOnly: rootElement.hasAttribute(\"data-readonly\"), status: status ? tools.facts(status) : null };\n};\n\n/** One item of the open menu with the group it stands in, counted by the separators. */\nexport interface MenuEntryFacts {\n name: string;\n role: string;\n /** `data-menu-id` of the item or its radio group. */\n menuId: string | null;\n disabled: boolean;\n /**\n * `data-menu-group` of the item or its radio group: the shell's `model`, `export` and `help`,\n * in the web app also `file` and `appearance`.\n */\n group: string | null;\n /** `data-menu-value` of a radio option. */\n value: string | null;\n /** `aria-checked` of a checkbox or radio entry. */\n checked: string | null;\n /** Whether the entry's icon column holds an icon (guide §5.4, only the common set of §5.14). */\n icon: boolean;\n}\n\nexport const menuEntriesProbe = ({ root }: { root: string }): MenuEntryFacts[] | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector(root);\n const menu = rootElement\n ? [...rootElement.querySelectorAll('[role=\"menu\"]')].find((element) => tools.visible(element))\n : undefined;\n if (!menu) return null;\n const entries: MenuEntryFacts[] = [];\n const selector = '[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]';\n for (const element of menu.querySelectorAll(selector)) {\n const role = element.getAttribute(\"role\") ?? \"\";\n if (!tools.visible(element)) continue;\n entries.push({\n name: (element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n role,\n menuId: element.closest(\"[data-menu-id]\")?.getAttribute(\"data-menu-id\") ?? null,\n disabled: element.getAttribute(\"aria-disabled\") === \"true\",\n group: element.closest(\"[data-menu-group]\")?.getAttribute(\"data-menu-group\") ?? null,\n value: element.getAttribute(\"data-menu-value\"),\n checked: element.getAttribute(\"aria-checked\"),\n icon: element.querySelector(\".cd-shell-menu-item-icon svg\") !== null,\n });\n }\n return entries;\n};\n","import {\n MAX_TOASTS,\n SHELL,\n decideTopRow,\n defaultMessages,\n legalLineHeight,\n type Appearance,\n type AppearanceChoice,\n type ShellHost,\n type Size,\n type Theme,\n type ToastStatus,\n} from \"../core/index.js\";\nimport type { AriaFacts, MenuEntryFacts } from \"./facts.js\";\nimport { GEOMETRY_TOLERANCE_PX, boxMismatches, type IslandBox } from \"./geometry.js\";\nimport type { ModeChange, RecordedKey } from \"./page-tools.js\";\nimport type {\n DropZoneFacts,\n EmptyStateFacts,\n LegalLineFacts,\n LiveRegionFacts,\n PopoverFacts,\n ToastFacts,\n TopRowFacts,\n WebModeFacts,\n} from \"./web-facts.js\";\n\n/*\n * The judgements of the web column (0.2), as pure functions of what the probes in web-facts.ts saw.\n * Each returns readable problems (empty = conforming).\n */\n\nconst round = (value: number): number => Math.round(value * 10) / 10;\n\nconst normalize = (text: string): string => text.replace(/\\s+/g, \" \").trim();\n\n/** The Miragon legal pages, from the corporate-identity docs-site kit (`miragon/legal.ts`). */\nexport const MIRAGON_HOME = \"https://www.miragon.io/\";\nexport const MIRAGON_IMPRESSUM = \"https://www.miragon.io/impressum/\";\nexport const MIRAGON_DATENSCHUTZ = \"https://www.miragon.io/datenschutz/\";\n\n/** Guide §2: these two stay German in every tool language. */\nconst GERMAN_LEGAL_LINKS = [\"Impressum\", \"Datenschutz\"] as const;\n\n/** Whether the tool speaks English, so the kit may compare names with the shell's default messages. */\nexport function speaksEnglish(lang: string): boolean {\n return /^en(-|$)/i.test(lang.trim());\n}\n\n// ---- aria (extended) ----\n\n/** The primary action's role and name (guide §5.7, §5.15, WCAG 2.5.3). */\nexport function primaryAriaProblems(facts: AriaFacts, host: ShellHost): string[] {\n const primary = facts.primary;\n if (!primary || host !== \"web\") return [];\n const problems: string[] = [];\n if (primary.tag !== \"button\") problems.push(`primary: a <${primary.tag}>, expected a <button>`);\n const label = normalize(primary.attributes[\"aria-label\"] ?? \"\");\n if (!label) {\n problems.push(\n \"primary: no aria-label; it names the action also while the label is collapsed (guide §5.15)\",\n );\n } else if (!facts.primaryCollapsed && primary.text && !label.includes(primary.text)) {\n problems.push(\n `primary: the aria-label \"${label}\" does not contain the visible label \"${primary.text}\" (WCAG 2.5.3)`,\n );\n }\n if (primary.disabled) {\n problems.push(\n \"primary: natively disabled; a disabled primary action keeps the focus with aria-disabled (guide §8)\",\n );\n }\n return problems;\n}\n\n/** The legal line's landmark and languages (guide §2, §5.10). */\nexport function legalAriaProblems(facts: AriaFacts, host: ShellHost): string[] {\n if (host !== \"web\") return [];\n const legal = facts.legal;\n if (!legal) return ['legal: no [data-chrome=\"legal\"] in the web app (guide §5.10)'];\n const problems: string[] = [];\n if (legal.tag !== \"nav\") problems.push(`legal: the legal line is a <${legal.tag}>, expected a <nav>`);\n if (!normalize(legal.attributes[\"aria-label\"] ?? \"\")) problems.push(\"legal: the <nav> has no aria-label\");\n for (const text of GERMAN_LEGAL_LINKS) {\n const link = facts.legalLinks.find((candidate) => candidate.text === text);\n if (!link) {\n problems.push(`legal: no \"${text}\" link (guide §5.10)`);\n } else if (link.lang !== \"de\") {\n problems.push(\n `legal: \"${text}\" has ${link.lang === null ? \"no lang\" : `lang=\"${link.lang}\"`}, expected lang=\"de\" (guide §2: Impressum and Datenschutz stay German)`,\n );\n }\n }\n for (const link of facts.legalLinks) {\n if (link.target !== \"_blank\") continue;\n const rel = (link.rel ?? \"\").split(/\\s+/);\n if (!rel.includes(\"noopener\") || !rel.includes(\"noreferrer\")) {\n problems.push(`legal: the link \"${link.text}\" opens a new tab without rel=\"noopener noreferrer\"`);\n }\n }\n return problems;\n}\n\n/** The pill as the trigger of the problems list (guide §5.10): web, and embedded when it opens one. */\nexport function pillPopupAriaProblems(facts: AriaFacts, host: ShellHost): string[] {\n const pill = facts.problems;\n if (!pill || host === \"ide\") return [];\n const haspopup = pill.attributes[\"aria-haspopup\"];\n if (host === \"embedded\" && haspopup === undefined) return [];\n const problems: string[] = [];\n if (haspopup !== \"dialog\") {\n problems.push(\n `problems: the pill has aria-haspopup \"${haspopup ?? \"\"}\", expected \"dialog\" (it opens the problems list)`,\n );\n }\n if (pill.attributes[\"aria-expanded\"] !== \"false\") {\n problems.push(\n `problems: the pill has aria-expanded \"${pill.attributes[\"aria-expanded\"] ?? \"\"}\" while the list is closed, expected \"false\"`,\n );\n }\n const controls = pill.attributes[\"aria-controls\"];\n if (!controls) {\n problems.push(\"problems: the pill has no aria-controls\");\n } else if (!facts.problemsControlled) {\n problems.push(`problems: aria-controls=\"${controls}\" names no element`);\n } else {\n const role = facts.problemsControlled.attributes.role;\n if (role !== \"dialog\") {\n problems.push(\n `problems: aria-controls names a ${facts.problemsControlled.description} with role \"${role ?? \"\"}\", expected \"dialog\"`,\n );\n }\n if (facts.problemsControlled.attributes[\"aria-modal\"] === \"true\") {\n problems.push(\n 'problems: the problems list is aria-modal=\"true\"; it is a non-modal popover (guide §5.10)',\n );\n }\n }\n return problems;\n}\n\n/** The fixed order of the menu groups (guide §5.4). */\nexport const MENU_GROUP_ORDER = [\"file\", \"model\", \"export\", \"appearance\", \"help\"] as const;\n\n/** The File group's entries in their order, and whether the guide gives each an icon (§5.4, §5.14). */\nexport const FILE_ENTRIES: ReadonlyArray<{ id: string; icon: boolean }> = [\n { id: \"new-diagram\", icon: true },\n { id: \"open\", icon: true },\n { id: \"show-example\", icon: false },\n { id: \"import\", icon: true },\n];\n\nconst APPEARANCE_VALUES: readonly AppearanceChoice[] = [\"system\", \"light\", \"dark\"];\n\n/**\n * The web app's File and Appearance groups (guide §5.4, §13.3): groups in the fixed order, the File\n * group's ids, order and icons, the Appearance radio group of a dark-capable modeler with its three\n * options and exactly the expected one checked; neither group outside the web app.\n */\nexport function menuGroupProblems(\n entries: readonly MenuEntryFacts[],\n host: ShellHost,\n themes: readonly Theme[],\n choice: AppearanceChoice = \"system\",\n): string[] {\n const problems: string[] = [];\n const file = entries.filter((entry) => entry.group === \"file\");\n const appearance = entries.filter((entry) => entry.group === \"appearance\");\n if (host !== \"web\") {\n const guide =\n host === \"ide\"\n ? \"its file actions are native (guide §13.5)\"\n : \"the host owns file and mode (guide §5.2)\";\n if (file.length > 0) problems.push(`menu: the ${host} host shows a File group; ${guide}`);\n if (appearance.length > 0) problems.push(`menu: the ${host} host shows an Appearance group; ${guide}`);\n return problems;\n }\n\n const sequence: string[] = [];\n for (const entry of entries) {\n if (entry.group && sequence.at(-1) !== entry.group) sequence.push(entry.group);\n }\n const rank = (group: string) => MENU_GROUP_ORDER.indexOf(group as (typeof MENU_GROUP_ORDER)[number]);\n const ordered = sequence.every((group, index) => index === 0 || rank(sequence[index - 1]!) < rank(group));\n if (!ordered) {\n problems.push(\n `menu: the groups stand in the order ${sequence.join(\", \")}; expected File, Model, Export, Appearance, Help (guide §5.4)`,\n );\n }\n\n const known = FILE_ENTRIES.map((entry) => entry.id);\n for (const entry of file) {\n const spec = FILE_ENTRIES.find((candidate) => candidate.id === entry.menuId);\n if (!spec) {\n problems.push(\n `menu: File entry \"${entry.name}\" has data-menu-id \"${entry.menuId ?? \"\"}\"; the shell builds the File group from ${known.join(\", \")}`,\n );\n continue;\n }\n if (entry.role !== \"menuitem\")\n problems.push(`menu: File entry \"${entry.name}\" is a ${entry.role}, expected a menuitem`);\n if (spec.icon && !entry.icon) problems.push(`menu: File entry \"${entry.name}\" has no icon (guide §5.4)`);\n if (!spec.icon && entry.icon) {\n problems.push(\n `menu: File entry \"${entry.name}\" carries an icon; the guide gives ${entry.menuId} none (guide §5.14)`,\n );\n }\n }\n const fileIds = file.map((entry) => entry.menuId ?? \"\");\n const expectedIds = known.filter((id) => fileIds.includes(id));\n if (fileIds.join() !== expectedIds.join() && fileIds.every((id) => known.includes(id))) {\n problems.push(\n `menu: the File group reads ${fileIds.join(\", \")}; expected the order ${expectedIds.join(\", \")} (guide §5.4)`,\n );\n }\n\n if (themes.includes(\"dark\")) {\n if (appearance.length === 0) {\n problems.push(\"menu: a dark-capable modeler shows no Appearance group (guide §5.4, §13.3)\");\n } else {\n const values = appearance.map((entry) => entry.value ?? \"\");\n if (values.join() !== APPEARANCE_VALUES.join()) {\n problems.push(\n `menu: the Appearance options are ${values.join(\", \")}; expected system, light, dark (guide §13.3)`,\n );\n }\n for (const entry of appearance) {\n if (entry.role !== \"menuitemradio\" || entry.menuId !== \"appearance\") {\n problems.push(\n `menu: Appearance option \"${entry.name}\" is a ${entry.role} in \"${entry.menuId ?? \"\"}\"; expected a menuitemradio of the radio group \"appearance\"`,\n );\n }\n }\n problems.push(...appearanceChoiceProblems(entries, choice));\n }\n }\n return problems;\n}\n\n/** The Appearance radio group checks exactly `choice` (`aria-checked`, guide §12). */\nexport function appearanceChoiceProblems(\n entries: readonly MenuEntryFacts[],\n choice: AppearanceChoice,\n): string[] {\n const checked = entries\n .filter((entry) => entry.group === \"appearance\" && entry.checked === \"true\")\n .map((entry) => entry.value ?? \"\");\n return checked.length === 1 && checked[0] === choice\n ? []\n : [\n `menu: the Appearance group checks ${checked.length > 0 ? checked.join(\", \") : \"nothing\"}; expected \"${choice}\" (aria-checked, guide §12)`,\n ];\n}\n\n/** Guide §13.3: a light-only modeler has no Appearance group. */\nexport function lightOnlyMenuProblems(\n entries: readonly MenuEntryFacts[],\n themes: readonly Theme[],\n): string[] {\n if (themes.includes(\"dark\")) return [];\n return entries.some((entry) => entry.group === \"appearance\" || entry.menuId === \"appearance\")\n ? [\"menu: a light-only modeler shows the Appearance group; it comes with dark (guide §13.3)\"]\n : [];\n}\n\n// ---- webChrome ----\n\n/** The labelled width of the primary action: its widest measurement while it showed the label. */\nexport function labelledWidth(samples: readonly TopRowFacts[]): number | undefined {\n const widths = samples.flatMap((sample) =>\n sample.primary && !sample.primary.collapsed && sample.primary.label ? [sample.primary.box.width] : [],\n );\n return widths.length > 0 ? Math.max(...widths) : undefined;\n}\n\n/**\n * Guide §5.15 at every measured width: the primary action loses its label before the palette\n * moves to the second row (`decideTopRow` with the measured widths); collapsed it is 40 × 40, keeps\n * its `aria-label` and has no `aria-describedby`. A width where a 1px difference flips the\n * decision is left out.\n */\nexport function topRowProblems(samples: readonly TopRowFacts[], withLabel: number, name: string): string[] {\n const problems: string[] = [];\n for (const sample of samples) {\n const { container, paletteWidth, menuRight, primary } = sample;\n if (!primary || paletteWidth === null || menuRight === null) continue;\n const decide = (palette: number, labelled: number) =>\n decideTopRow({\n containerWidth: container.width,\n paletteWidth: palette,\n menuRight,\n primary: { withLabel: labelled, iconOnly: SHELL.row },\n });\n const expected = decide(paletteWidth, withLabel);\n const low = decide(paletteWidth - 1, withLabel - 1);\n const high = decide(paletteWidth + 1, withLabel + 1);\n const at = `[${round(container.width)}px wide]`;\n if (\n low.paletteRow === high.paletteRow &&\n low.primaryLabel === high.primaryLabel &&\n expected.paletteRow === low.paletteRow &&\n expected.primaryLabel === low.primaryLabel\n ) {\n const collapsed = expected.primaryLabel === \"collapsed\";\n if (collapsed && !primary.collapsed) {\n problems.push(\n expected.paletteRow === \"top\"\n ? `${at} primary: shows its label, but the ${round(paletteWidth)}px palette fits the top row only beside the icon; the label collapses first (guide §5.15)`\n : `${at} primary: shows its label, but it no longer fits next to the menu trigger (data-primary=\"collapsed\", guide §5.15)`,\n );\n }\n if (!collapsed && primary.collapsed) {\n problems.push(`${at} primary: collapsed although its ${round(withLabel)}px label fits (guide §5.15)`);\n }\n if (expected.paletteRow !== sample.paletteRow) {\n problems.push(\n expected.paletteRow === \"top\"\n ? `${at} palette: in the second row although it fits the top row beside the collapsed primary action; the label collapses first (guide §5.15)`\n : `${at} palette: in the top row although it keeps less than 16px to the primary action even icon only (guide §5.15)`,\n );\n }\n }\n if (primary.collapsed) {\n if (Math.abs(primary.box.width - SHELL.row) > GEOMETRY_TOLERANCE_PX + 1e-6) {\n problems.push(\n `${at} primary: ${round(primary.box.width)}px wide while collapsed, expected ${SHELL.row}px`,\n );\n }\n if (primary.label)\n problems.push(`${at} primary: collapsed, but its label \"${primary.label}\" still shows`);\n if (primary.ariaLabel !== name) {\n problems.push(\n `${at} primary: the aria-label is \"${primary.ariaLabel ?? \"\"}\" while collapsed; it keeps \"${name}\" (guide §5.15)`,\n );\n }\n } else if (!primary.label) {\n problems.push(`${at} primary: shows no label although the root lacks data-primary=\"collapsed\"`);\n }\n if (primary.describedBy) {\n problems.push(\n `${at} primary: aria-describedby=\"${primary.describedBy}\"; its tooltip repeats the name (API.md, Primary action)`,\n );\n }\n }\n return problems;\n}\n\n/** The chrome tooltip of the primary action: only while collapsed, with its label (guide §5.15). */\nexport function primaryTooltipProblems(\n collapsed: boolean,\n tooltip: string | null,\n name: string,\n width: number,\n): string[] {\n const at = `[${round(width)}px wide]`;\n if (collapsed && tooltip === null) {\n return [`${at} primary: no chrome tooltip while collapsed; it shows the label \"${name}\" (guide §5.15)`];\n }\n if (collapsed && tooltip !== null && !normalize(tooltip).startsWith(name)) {\n return [`${at} primary: the tooltip while collapsed reads \"${normalize(tooltip)}\", expected \"${name}\"`];\n }\n if (!collapsed && tooltip !== null) {\n return [\n `${at} primary: a tooltip \"${normalize(tooltip)}\" while the label shows; only the collapsed action has one`,\n ];\n }\n return [];\n}\n\n/** A key on the primary action: a native button turns Enter into one click (guide §5.7). */\nexport function primaryActivationProblems(clicks: { pointer: number; enter: number }): string[] {\n const problems: string[] = [];\n if (clicks.pointer !== 1)\n problems.push(`primary: a pointer click reached it ${clicks.pointer} times, expected once`);\n if (clicks.enter !== 1) {\n problems.push(\n `primary: Enter on the focused primary action clicked it ${clicks.enter} times, expected once (keyboard activation)`,\n );\n }\n return problems;\n}\n\n/** The legal line's content (guide §5.10, docs-site kit `miragon/legal.ts`). */\nexport function legalContentProblems(links: AriaFacts[\"legalLinks\"]): string[] {\n const problems: string[] = [];\n const [copyright, impressum, datenschutz] = links;\n if (!copyright || !/^©/.test(copyright.text) || !copyright.text.includes(\"Miragon GmbH\")) {\n problems.push(\n `legal: the line starts with \"${copyright?.text ?? \"\"}\", expected the copyright \"© <year> Miragon GmbH\" (guide §5.10)`,\n );\n } else if (copyright.href !== MIRAGON_HOME) {\n problems.push(`legal: the copyright links \"${copyright.href}\", expected ${MIRAGON_HOME}`);\n }\n const expected: Array<[typeof impressum, string, string]> = [\n [impressum, \"Impressum\", MIRAGON_IMPRESSUM],\n [datenschutz, \"Datenschutz\", MIRAGON_DATENSCHUTZ],\n ];\n for (const [link, text, href] of expected) {\n if (link?.text !== text) {\n problems.push(\n `legal: the links read ${links.map((entry) => `\"${entry.text}\"`).join(\", \")}; expected the copyright, \"Impressum\", \"Datenschutz\", then the modeler's links (guide §5.10)`,\n );\n break;\n }\n if (link.href !== href) problems.push(`legal: \"${text}\" links \"${link.href}\", expected ${href}`);\n }\n return [...new Set(problems)];\n}\n\n/**\n * Guide §5.10, WCAG 1.4.10: in the narrowest container every legal link lies whole inside the legal\n * line and the container, so Impressum and Datenschutz are never cut off or scrolled away.\n */\nexport function legalReachProblems(facts: LegalLineFacts): string[] {\n const legal = facts.legal;\n if (!legal) return [];\n const width = round(facts.container.width);\n const problems: string[] = [];\n for (const link of facts.links) {\n const box = link.box;\n const inside =\n box.left >= Math.max(0, legal.left) - GEOMETRY_TOLERANCE_PX &&\n box.left + box.width <=\n Math.min(legal.left + legal.width, facts.container.width) + GEOMETRY_TOLERANCE_PX &&\n box.top >= legal.top - GEOMETRY_TOLERANCE_PX &&\n box.top + box.height <= legal.top + legal.height + GEOMETRY_TOLERANCE_PX;\n if (!inside) {\n problems.push(\n `legal: [${width}px wide] \"${link.text}\" is cut off or scrolled out of the legal line; it wraps instead (guide §5.10, WCAG 1.4.10)`,\n );\n }\n }\n return problems;\n}\n\n/**\n * The zoom panel's bottom in the web app: 12px, 40px while `data-zoom-row=\"raised\"` (on a legal line\n * that wraps, 8px above its measured `legalHeight`).\n */\nexport function zoomRowBottomProblems(\n zoom: IslandBox | undefined,\n raised: boolean,\n container: Size,\n legalHeight?: number,\n): string[] {\n if (!zoom) return [];\n const bottom = raised ? SHELL.edge + legalLineHeight(legalHeight) + SHELL.gap : SHELL.edge;\n return boxMismatches(\"zoom\", zoom, { bottom }, container).map(\n (problem) => `[${round(container.width)}px wide${raised ? \", raised\" : \"\"}] ${problem}`,\n );\n}\n\n// ---- emptyState ----\n\n/** The start screen of guide §8 as `show.emptyState` leaves it. */\nexport function emptyStateProblems(facts: EmptyStateFacts, container: Size, lang: string): string[] {\n const problems: string[] = [];\n if (!facts.shown)\n problems.push('empty-state: the root lacks data-empty-state=\"shown\" after show.emptyState');\n const card = facts.card;\n if (!card?.visible) return [...problems, \"empty-state: the card is not visible after show.emptyState\"];\n problems.push(\n ...boxMismatches(\n \"empty-state\",\n card.box,\n {\n centerX: container.width / 2,\n centerY: container.height / 2,\n width: Math.min(400, container.width - 2 * SHELL.edge),\n },\n container,\n ),\n );\n if (!card.labelledBy) problems.push(\"empty-state: the card is not labelled by its title (aria-labelledby)\");\n if (!facts.komet) {\n problems.push(\"empty-state: no Komet <img> on the card (guide §2, §8)\");\n } else {\n if (facts.komet.alt !== \"\") {\n problems.push(\n `empty-state: the Komet has ${facts.komet.alt === null ? \"no alt\" : `alt=\"${facts.komet.alt}\"`}; it is decorative, alt=\"\" (guide §8)`,\n );\n }\n if (Math.abs(facts.komet.width - 64) > 1 || Math.abs(facts.komet.height - 64) > 1) {\n problems.push(\n `empty-state: the Komet is ${round(facts.komet.width)} × ${round(facts.komet.height)}px, expected 64 × 64 (guide §8)`,\n );\n }\n }\n if (facts.heading?.tag !== \"h1\") {\n problems.push(\n `empty-state: the title is ${facts.heading ? `a <${facts.heading.tag}>` : \"missing\"}, expected an <h1>`,\n );\n }\n const [primary, ghost, ...rest] = facts.buttons;\n if (!primary) {\n problems.push('empty-state: no \"New diagram\" button on the card (guide §8)');\n } else {\n if (primary.variant !== \"primary\") {\n problems.push(\n `empty-state: the first button \"${primary.name}\" is ${primary.variant ?? \"no\"} variant, expected the blue primary \"New diagram\" first (guide §8)`,\n );\n }\n if (ghost && ghost.variant !== \"ghost\") {\n problems.push(\n `empty-state: the second button \"${ghost.name}\" is ${ghost.variant ?? \"no\"} variant, expected the ghost \"Show example\" (guide §8)`,\n );\n }\n if (rest.length > 0)\n problems.push(\n `empty-state: ${facts.buttons.length} buttons on the card; exactly two actions (guide §8)`,\n );\n for (const button of [primary, ghost]) {\n if (button && Math.abs(button.height - SHELL.entry) > 1) {\n problems.push(\n `empty-state: \"${button.name}\" is ${round(button.height)}px high, expected ${SHELL.entry}px (guide §8)`,\n );\n }\n }\n if (speaksEnglish(lang)) {\n if (primary.name !== defaultMessages.newDiagram) {\n problems.push(\n `empty-state: the primary button reads \"${primary.name}\", expected \"${defaultMessages.newDiagram}\" (guide §2)`,\n );\n }\n if (ghost && ghost.name !== defaultMessages.showExample) {\n problems.push(\n `empty-state: the ghost button reads \"${ghost.name}\", expected \"${defaultMessages.showExample}\" (guide §2)`,\n );\n }\n }\n }\n for (const part of facts.work) {\n if (part.visible) {\n problems.push(\n `empty-state: ${part.name} is visible behind the start screen; it hides the work chrome (guide §8)`,\n );\n }\n }\n if (!facts.canvasInert) {\n problems.push(\n \"empty-state: the canvas slot is not inert behind the start screen; nothing else takes a click or the Tab (guide §8)\",\n );\n }\n if (!facts.legalVisible)\n problems.push(\"empty-state: the legal line is not visible; a public page always shows it (guide §8)\");\n return problems;\n}\n\n/** Tab on the start screen: only the card's buttons and the legal links (guide §8). */\nexport function emptyStateTabProblems(\n owners: ReadonlyArray<{ owner: string; description: string }>,\n): string[] {\n const problems: string[] = [];\n for (const stop of owners) {\n if ([\"empty-state\", \"legal\", \"toasts\", \"body\", \"outside\"].includes(stop.owner)) continue;\n problems.push(\n `empty-state: Tab reaches ${stop.description} (${stop.owner}) behind the start screen; only the card and the legal links take the focus (guide §8)`,\n );\n }\n if (!owners.some((stop) => stop.owner === \"empty-state\")) {\n problems.push(\"empty-state: Tab never reaches the card's buttons\");\n }\n if (!owners.some((stop) => stop.owner === \"legal\"))\n problems.push(\"empty-state: Tab never reaches the legal links\");\n return [...new Set(problems)];\n}\n\n/**\n * A chrome key behind the start screen (API.md, Empty state): it zooms no diagram, and it reaches\n * the browser unprevented, which zooms the page (WCAG 1.4.4: there is no diagram to zoom instead).\n */\nexport function emptyStateKeyProblems(\n key: string,\n before: number | null,\n after: number | null,\n keys: readonly RecordedKey[],\n): string[] {\n const problems: string[] = [];\n if (after !== before) {\n problems.push(\n `empty-state: ${key} behind the start screen changed the zoom from ${before ?? \"?\"}% to ${after ?? \"?\"}%; the chrome keys zoom no diagram there`,\n );\n }\n if (keys.some((recorded) => recorded.defaultPrevented)) {\n problems.push(\n `empty-state: ${key} behind the start screen arrived prevented; with no diagram to zoom the browser keeps its page zoom (WCAG 1.4.4)`,\n );\n }\n return problems;\n}\n\n/** After \"New diagram\": the card gone, the work chrome back, the focus on the canvas (guide §8). */\nexport function afterStartProblems(\n facts: EmptyStateFacts,\n focus: { owner: string; description: string },\n): string[] {\n const problems: string[] = [];\n const after = 'after \"New diagram\"';\n if (facts.shown) problems.push(`empty-state: ${after} the root still carries data-empty-state=\"shown\"`);\n if (facts.card?.visible) problems.push(`empty-state: ${after} the card still shows`);\n for (const name of [\"menu\", \"palette\", \"zoom\"]) {\n const part = facts.work.find((candidate) => candidate.name === name);\n if (part && !part.visible) problems.push(`empty-state: ${after} the ${name} is still hidden`);\n }\n if (facts.canvasInert) problems.push(`empty-state: ${after} the canvas slot is still inert`);\n if (focus.owner !== \"canvas\") {\n problems.push(\n `empty-state: ${after} the focus is on ${focus.description}, expected the canvas <svg> (API.md, Empty state)`,\n );\n }\n return problems;\n}\n\n// ---- toasts ----\n\n/** How a toast reached screen readers: its live region existed before it, and its text arrived there. */\nexport interface ToastAnnouncement {\n /** A live region of the toast's role was rendered in the root before the first toast. */\n persistent: boolean;\n /** The toast's text arrived in that region. */\n announced: boolean;\n}\n\n/**\n * The live region a toast of `status` is announced through (guide §8, §12): `role=\"alert\"` for\n * errors, `role=\"status\"` (`aria-live=\"polite\"`) otherwise.\n */\nexport function toastLiveRegion(\n regions: readonly LiveRegionFacts[],\n status: ToastStatus,\n): LiveRegionFacts | undefined {\n const role = status === \"danger\" ? \"alert\" : \"status\";\n return regions.find((region) => region.role === role);\n}\n\n/**\n * Guide §8, §12: announced through a persistent `role=\"alert\"` (errors) or `role=\"status\"` live\n * region, the card itself without a live role (it would be read twice); Close named \"Close\".\n */\nexport function toastAnatomyProblems(\n toast: ToastFacts,\n status: ToastStatus,\n lang: string,\n announcement: ToastAnnouncement,\n): string[] {\n const problems: string[] = [];\n const role = status === \"danger\" ? \"alert\" : \"status\";\n if (!announcement.persistent) {\n problems.push(\n `toasts: no role=\"${role}\" live region in the root before the first toast; a live region created together with its text is often not announced (guide §8, §12)`,\n );\n } else if (!announcement.announced) {\n problems.push(\n `toasts: the ${status} toast's text never reaches the role=\"${role}\" live region (guide §8, §12)`,\n );\n }\n if (toast.role === \"status\" || toast.role === \"alert\") {\n problems.push(\n `toasts: the ${status} toast's card carries role=\"${toast.role}\"; the live region announces it, so a live card is read twice`,\n );\n }\n const close = toast.buttons.at(-1);\n if (!close || close.text !== \"\") {\n problems.push(`toasts: the ${status} toast has no Close icon button at its end (guide §8)`);\n } else if (!close.name) {\n problems.push(`toasts: the ${status} toast's Close button has no accessible name`);\n } else if (speaksEnglish(lang) && close.name !== defaultMessages.close) {\n problems.push(\n `toasts: the Close button is named \"${close.name}\", expected \"${defaultMessages.close}\" (guide §8)`,\n );\n }\n if (toast.box.height < 40 - GEOMETRY_TOLERANCE_PX) {\n problems.push(\n `toasts: the ${status} toast is ${round(toast.box.height)}px high, at least 40px (guide §8)`,\n );\n }\n return problems;\n}\n\n/** Texts of the visible toasts that contain one of `texts`, in stack order. */\nexport function shownToasts(toasts: readonly ToastFacts[], texts: readonly string[]): string[] {\n return toasts.flatMap((toast) => texts.filter((text) => toast.text.includes(text)));\n}\n\n/**\n * The stack after `shown` toasts in this order (the first with an action): at most `MAX_TOASTS`,\n * the oldest without an action evicted, the newest at the bottom, a repeated text not stacked.\n */\nexport function toastStackProblems(\n toasts: readonly ToastFacts[],\n shown: readonly string[],\n expected: readonly string[],\n): string[] {\n const problems: string[] = [];\n const present = shownToasts(toasts, shown);\n if (toasts.length > MAX_TOASTS)\n problems.push(`toasts: ${toasts.length} toasts at once, at most ${MAX_TOASTS} (guide §8)`);\n if (present.join(\"\\u0000\") !== expected.join(\"\\u0000\")) {\n problems.push(\n `toasts: after ${shown.length} toasts the stack shows ${present.map((text) => `\"${text}\"`).join(\", \") || \"none\"}; expected ${expected.map((text) => `\"${text}\"`).join(\", \")} (at most ${MAX_TOASTS}, the oldest without an action leaves, guide §8)`,\n );\n }\n const tops = toasts\n .filter((toast) => shown.some((text) => toast.text.includes(text)))\n .map((toast) => toast.box.top);\n if (tops.some((top, index) => index > 0 && top < tops[index - 1]!)) {\n problems.push(\"toasts: the newest toast is not at the bottom of the stack (guide §8)\");\n }\n return problems;\n}\n\n/** A repeated request (status and text) restarts the shown toast instead of stacking a second. */\nexport function repeatedToastProblems(toasts: readonly ToastFacts[], text: string): string[] {\n const count = toasts.filter((toast) => toast.text.includes(text)).length;\n return count > 1\n ? [`toasts: a repeated \"${text}\" stacks ${count} toasts; it restarts the shown one (API.md, Toasts)`]\n : [];\n}\n\n/** How the kit treated a toast before it looked at it again. */\nexport type ToastCondition = \"plain\" | \"hovered\" | \"focused\" | \"resumed\" | \"action\";\n\nexport interface ToastTiming {\n text: string;\n expectation: \"present\" | \"gone\";\n /** Milliseconds since it appeared, or since pointer and focus left it (`resumed`). */\n after: number;\n present: boolean;\n condition: ToastCondition;\n}\n\nconst TOAST_RULES: Readonly<Record<ToastCondition, string>> = {\n plain: \"it stays for its lifetime\",\n hovered: \"hover pauses its time\",\n focused: \"focus pauses its time\",\n resumed: \"it resumes with at least 1.5s left\",\n action: \"a toast with an action never closes by itself\",\n};\n\n/** Guide §8: closing after `toastLifetime` unless hovered or focused; a toast with an action never. */\nexport function toastTimingProblems(timings: readonly ToastTiming[]): string[] {\n return timings.flatMap((timing) => {\n const since =\n timing.condition === \"resumed\" ? \"after the pointer and the focus left it\" : \"after it appeared\";\n if (timing.expectation === \"present\" && !timing.present) {\n return [\n `toasts: \"${timing.text}\" closed within ${timing.after}ms ${since}; ${TOAST_RULES[timing.condition]} (guide §8)`,\n ];\n }\n if (timing.expectation === \"gone\" && timing.present) {\n return [\n `toasts: \"${timing.text}\" is still there ${timing.after}ms ${since}; it closes after its lifetime (guide §8)`,\n ];\n }\n return [];\n });\n}\n\n// ---- problemsList ----\n\n/** One ArrowDown (or End) in the open problems list: the row it should reach, and the one it did. */\nexport interface PopoverKeyStep {\n key: string;\n expected: number;\n focused: { index: number; inView: boolean } | null;\n}\n\n/**\n * Guide §5.10, §12 (WCAG 2.1.1): the keyboard reaches every row of the problems list, text rows\n * without an element too, and each focused row scrolls into the list's visible part.\n */\nexport function popoverKeyboardProblems(steps: readonly PopoverKeyStep[], rowCount: number): string[] {\n const problems: string[] = [];\n for (const step of steps) {\n if (step.focused?.index !== step.expected) {\n problems.push(\n `problems-popover: ${step.key} reaches ${step.focused ? `row ${step.focused.index + 1}` : \"no row\"}, expected row ${step.expected + 1} of ${rowCount}; the keyboard reads every row, text rows too (guide §5.10, WCAG 2.1.1)`,\n );\n } else if (!step.focused.inView) {\n problems.push(\n `problems-popover: row ${step.expected + 1} takes the focus on ${step.key} but stays scrolled out of the list`,\n );\n }\n }\n return problems;\n}\n\n/** The problems list once the pill opened it (guide §5.10). */\nexport function openPopoverProblems(facts: PopoverFacts, container: Size, lang: string): string[] {\n const problems: string[] = [];\n const popover = facts.popover;\n if (!popover?.visible)\n return [\"problems-popover: a click on the pill shows no problems list (guide §5.10)\"];\n if (popover.attributes.role !== \"dialog\") {\n problems.push(`problems-popover: role \"${popover.attributes.role ?? \"\"}\", expected \"dialog\"`);\n }\n if (popover.attributes[\"aria-modal\"] === \"true\")\n problems.push('problems-popover: aria-modal=\"true\"; it is not modal');\n if (!popover.title) {\n problems.push(\"problems-popover: not labelled by its title (aria-labelledby)\");\n } else if (speaksEnglish(lang) && popover.title !== defaultMessages.problemsTitle) {\n problems.push(\n `problems-popover: titled \"${popover.title}\", expected \"${defaultMessages.problemsTitle}\" (guide §5.10)`,\n );\n }\n if (facts.pill?.attributes[\"aria-expanded\"] !== \"true\") {\n problems.push(\n `problems: aria-expanded is \"${facts.pill?.attributes[\"aria-expanded\"] ?? \"\"}\" while the list is open, expected \"true\"`,\n );\n }\n if (facts.rows.length === 0) {\n problems.push(\"problems-popover: the list has no rows; show.problems passes items in the web host\");\n }\n for (const row of facts.rows) {\n if (row.height < SHELL.entry - GEOMETRY_TOLERANCE_PX) {\n problems.push(\n `problems-popover: the row \"${row.text}\" is ${round(row.height)}px high, at least ${SHELL.entry}px (guide §5.10)`,\n );\n }\n if (!row.icon)\n problems.push(`problems-popover: the row \"${row.text}\" has no severity icon (guide §5.10)`);\n }\n if (facts.focus !== \"popover\") {\n problems.push(\n `problems-popover: opening it leaves the focus on ${facts.focused}; it moves to the first row (API.md, Problems popover)`,\n );\n }\n const pill = facts.pill;\n if (pill) {\n problems.push(\n ...boxMismatches(\n \"problems-popover\",\n popover.box,\n { left: SHELL.edge, bottom: container.height - pill.box.top + SHELL.gap },\n container,\n ),\n );\n if (popover.box.width > Math.min(320, container.width - 2 * SHELL.edge) + GEOMETRY_TOLERANCE_PX + 1e-6) {\n problems.push(\n `problems-popover: width is ${round(popover.box.width)}px, at most ${round(Math.min(320, container.width - 2 * SHELL.edge))}px expected`,\n );\n }\n if (popover.box.height > 320 + GEOMETRY_TOLERANCE_PX + 1e-6) {\n problems.push(`problems-popover: height is ${round(popover.box.height)}px, at most 320px expected`);\n }\n }\n return problems;\n}\n\n/** The problems list after a way of closing it (guide §5.10, API.md). */\nexport function closedPopoverProblems(\n facts: PopoverFacts,\n how: \"Escape\" | \"an outside click\" | \"a row with an element\",\n): string[] {\n const problems: string[] = [];\n if (facts.popover?.visible) problems.push(`problems-popover: ${how} does not close the list`);\n if (facts.pill && facts.pill.attributes[\"aria-expanded\"] !== \"false\") {\n problems.push(\n `problems: aria-expanded is \"${facts.pill.attributes[\"aria-expanded\"] ?? \"\"}\" after ${how}, expected \"false\"`,\n );\n }\n if (how === \"Escape\" && facts.focus !== \"pill\") {\n problems.push(`problems-popover: Escape leaves the focus on ${facts.focused}, expected the pill`);\n }\n if (how === \"an outside click\" && facts.focus === \"pill\") {\n problems.push(\n \"problems-popover: an outside click moved the focus to the pill; it closes without moving the focus\",\n );\n }\n if (how === \"a row with an element\" && facts.focus !== \"canvas\") {\n problems.push(\n `problems-popover: a row with an element leaves the focus on ${facts.focused}, expected the canvas`,\n );\n }\n return problems;\n}\n\n// ---- dropZone ----\n\nexport type ExpectedDrop = \"over\" | \"forbidden\" | \"none\";\n\n/** One drag state of guide §9: drag-over, drop forbidden, or a drag the drop zone leaves alone. */\nexport function dropStateProblems(\n facts: DropZoneFacts,\n expected: ExpectedDrop,\n context: string,\n container: Size,\n): string[] {\n const problems: string[] = [];\n const zone = facts.zone;\n const over = facts.events.filter((event) => event.type === \"dragover\");\n if (expected === \"none\") {\n if (facts.state !== null)\n problems.push(`drop-zone: ${context} sets data-drop=\"${facts.state}\"; it is no file drag`);\n if (zone?.visible) problems.push(`drop-zone: ${context} shows the drop zone`);\n if (over.some((event) => event.defaultPrevented))\n problems.push(`drop-zone: ${context} is prevented; the drop zone leaves non-file drags alone`);\n return problems;\n }\n if (facts.state !== expected) {\n problems.push(\n `drop-zone: ${context} sets data-drop=\"${facts.state ?? \"\"}\", expected \"${expected}\" (guide §9)`,\n );\n }\n if (facts.events.some((event) => !event.defaultPrevented && event.type !== \"dragleave\")) {\n problems.push(`drop-zone: ${context} is not prevented, so the browser would open the file`);\n }\n const effect = expected === \"over\" ? \"copy\" : \"none\";\n for (const event of over) {\n if (event.dropEffect !== effect)\n problems.push(`drop-zone: ${context} has dropEffect \"${event.dropEffect}\", expected \"${effect}\"`);\n }\n if (!zone?.visible) return [...problems, `drop-zone: ${context} shows no drop zone (guide §9)`];\n problems.push(\n ...boxMismatches(\"drop-zone\", zone.box, { left: 12, top: 12, right: 12, bottom: 12 }, container).map(\n (problem) => `${problem} (${context})`,\n ),\n );\n if (zone.ariaHidden !== \"true\") problems.push('drop-zone: the overlay lacks aria-hidden=\"true\"');\n const fill =\n expected === \"over\"\n ? [\"--cd-ui-hover\", facts.roles.hover]\n : [\"--cd-ui-danger-flaeche\", facts.roles.dangerFlaeche];\n const border =\n expected === \"over\"\n ? [\"--cd-ui-interaktion\", facts.roles.interaktion]\n : [\"--cd-ui-danger\", facts.roles.danger];\n if (zone.background !== fill[1]) {\n problems.push(\n `drop-zone: ${context} fills ${zone.background}, expected ${fill[0]} (${fill[1]}) (guide §9)`,\n );\n }\n if (zone.borderStyle !== \"dashed\" || zone.borderWidth !== \"2px\" || zone.borderColor !== border[1]) {\n problems.push(\n `drop-zone: ${context} has a ${zone.borderWidth} ${zone.borderStyle} ${zone.borderColor} border, expected 2px dashed ${border[0]} (${border[1]}) (guide §9)`,\n );\n }\n if (!facts.chip?.text) {\n problems.push(`drop-zone: ${context} shows no chip text (guide §9)`);\n } else if (facts.chip.background !== facts.roles.flaecheHoch) {\n problems.push(\n `drop-zone: the chip fills ${facts.chip.background}, expected --cd-ui-flaeche-hoch (${facts.roles.flaecheHoch})`,\n );\n }\n return problems;\n}\n\n// ---- appearance (web) ----\n\n/** What the web app's document carries for `choice` (guide §13.3), computed independently of the shell. */\nexport interface ExpectedWebMode {\n /** `data-cd-theme` on `<html>`. */\n carrier: Theme | \"system\";\n /** The mode the page shows under the emulated system preference. */\n effective: Appearance;\n}\n\nexport function expectedWebMode(\n requested: Appearance,\n themes: readonly Theme[],\n choice: AppearanceChoice,\n): ExpectedWebMode {\n const kontrast = requested.kontrast ? { kontrast: requested.kontrast } : {};\n if (!themes.includes(\"dark\")) return { carrier: \"light\", effective: { theme: \"light\", ...kontrast } };\n if (choice === \"system\") return { carrier: \"system\", effective: { theme: requested.theme, ...kontrast } };\n return { carrier: choice, effective: { theme: choice, ...kontrast } };\n}\n\n/**\n * `<html>`, the meta tags and the stored choice of the web app (guide §13.3): light-only static\n * light with one `theme-color` without `media`; dark-capable `system` with `color-scheme` \"light\n * dark\" and two `theme-color`s by `media`, a fixed choice stored and on both metas.\n */\nexport function webModeProblems(\n facts: WebModeFacts,\n themes: readonly Theme[],\n choice: AppearanceChoice,\n colors: { light: string; dark: string } | undefined,\n): string[] {\n const problems: string[] = [];\n const dark = themes.includes(\"dark\");\n if (!dark) {\n const metas = facts.themeColors;\n if (metas.length !== 1 || metas[0]?.media !== null) {\n problems.push(\n `mode: a light-only web app carries one theme-color without media (guide §13.3); found ${metas.map((meta) => (meta.media ? `${meta.content} (${meta.media})` : meta.content)).join(\", \") || \"none\"}`,\n );\n }\n if (facts.colorScheme !== null && facts.colorScheme.split(/\\s+/).includes(\"dark\")) {\n problems.push(`mode: a light-only web app declares color-scheme \"${facts.colorScheme}\"`);\n }\n return problems;\n }\n const label = choice === \"system\" ? \"System\" : choice === \"dark\" ? \"Dark\" : \"Light\";\n const expectedScheme = choice === \"system\" ? \"light dark\" : choice;\n if (facts.colorScheme !== expectedScheme) {\n problems.push(\n `mode: with ${label} <meta name=\"color-scheme\"> reads \"${facts.colorScheme ?? \"(none)\"}\", expected \"${expectedScheme}\" (guide §13.3)`,\n );\n }\n const stored = choice === \"system\" ? null : choice;\n if (!facts.storageBlocked && facts.stored !== stored) {\n problems.push(\n stored === null\n ? `mode: with System localStorage keeps miragon.darstellung=\"${facts.stored ?? \"\"}\"; System removes the entry (guide §13.3)`\n : `mode: with ${label} localStorage holds miragon.darstellung=${facts.stored === null ? \"(none)\" : `\"${facts.stored}\"`}, expected \"${stored}\" (guide §13.3)`,\n );\n }\n const byMedia = (scheme: \"light\" | \"dark\") =>\n facts.themeColors.find((meta) => meta.media?.replace(/\\s+/g, \"\") === `(prefers-color-scheme:${scheme})`);\n const light = byMedia(\"light\");\n const darkMeta = byMedia(\"dark\");\n if (!light || !darkMeta) {\n problems.push(\n \"mode: a dark-capable web app carries two theme-color metas, one per prefers-color-scheme (guide §13.3)\",\n );\n } else if (colors) {\n const want = choice === \"system\" ? colors : { light: colors[choice], dark: colors[choice] };\n if (light.content !== want.light || darkMeta.content !== want.dark) {\n problems.push(\n `mode: with ${label} the theme-color metas read ${light.content} (light) and ${darkMeta.content} (dark), expected ${want.light} and ${want.dark} (guide §13.3)`,\n );\n }\n }\n return problems;\n}\n\n/** Guide §13.3, §7: one switch changes `<html>` and every meta tag in one frame, transitions off for it. */\nexport function modeSwitchProblems(changes: readonly ModeChange[], label: string): string[] {\n const relevant = changes.filter((change) => [\"theme\", \"color-scheme\", \"theme-color\"].includes(change.part));\n if (relevant.length === 0) return [`mode: choosing ${label} changed nothing on <html> or its meta tags`];\n const problems: string[] = [];\n const frames = [...new Set(relevant.map((change) => change.frame))];\n if (frames.length > 1) {\n const parts = relevant.map((change) => `${change.part} in frame ${change.frame}`).join(\", \");\n problems.push(`mode: choosing ${label} changed ${parts}; one frame for all of them (guide §13.3)`);\n }\n const first = Math.min(...frames);\n if (\n !changes.some(\n (change) => change.part === \"no-transition\" && change.value === \"on\" && change.frame === first,\n )\n ) {\n problems.push(\n `mode: choosing ${label} switched without cd-shell-no-transition on <html> in that frame (guide §7: no colour fades)`,\n );\n }\n return problems;\n}\n","import { INVALID_STATUS_DELAY_MS, type Appearance, type ShellHost, type Theme } from \"../core/index.js\";\nimport {\n DOM_ORDER,\n type AppearanceFacts,\n type AriaFacts,\n type CanvasStateFacts,\n type MenuEntryFacts,\n type MenuFacts,\n type PaletteColorEntry,\n type PaletteColorFacts,\n type PaletteEntryState,\n type ReadOnlyStateFacts,\n type ShapeFacts,\n type SurroundFacts,\n type ZoomButton,\n} from \"./facts.js\";\nimport { GEOMETRY_TOLERANCE_PX, type Rectangle } from \"./geometry.js\";\nimport type { AbsentFeature, ShellConformanceHarness, ShowHook } from \"./harness.js\";\nimport type { ElementFacts, LeftoverFacts, RecordedKey } from \"./page-tools.js\";\nimport type { PageLike } from \"./page.js\";\nimport { legalAriaProblems, primaryAriaProblems } from \"./web-checks.js\";\n\n/*\n * The judgements of the cases, as pure functions of what the probes saw. Each returns readable\n * problems (empty = conforming), so a case can report all of them at once.\n */\n\nconst normalize = (text: string): string => text.replace(/\\s+/g, \" \").trim();\n\nconst name = (element: ElementFacts): string => normalize(element.attributes[\"aria-label\"] ?? element.text);\n\nconst attribute = (element: ElementFacts, key: string): string | undefined => element.attributes[key];\n\n/** `aria-keyshortcuts` of the zoom panel (guide §5.6, WAI-ARIA key names). */\nexport function expectedKeyShortcuts(platform: \"mac\" | \"other\"): Record<ZoomButton, string> {\n const modifier = platform === \"mac\" ? \"Meta\" : \"Control\";\n return {\n in: `${modifier}+= ${modifier}+Plus`,\n out: `${modifier}+-`,\n actual: `${modifier}+0`,\n fit: \"Shift+1\",\n };\n}\n\n/** Roles, names, states, DOM order and tab stops of guide §5.4 to §5.14 and §12. */\nexport function ariaProblems(facts: AriaFacts, host: ShellHost): string[] {\n const problems: string[] = [];\n\n if (host === \"embedded\") {\n if (!facts.rootLang)\n problems.push(\"root: an embedded shell root carries the tool's lang itself (guide §2, §12)\");\n } else if (!facts.documentLang) {\n problems.push(\"<html> has no lang (guide §2)\");\n }\n\n const trigger = facts.trigger;\n if (!trigger) {\n problems.push('menu: no [data-chrome=\"menu\"] trigger');\n } else {\n if (trigger.tag !== \"button\")\n problems.push(`menu: the trigger is a <${trigger.tag}>, expected a <button>`);\n if (!attribute(trigger, \"aria-label\")) problems.push(\"menu: the icon-only trigger has no aria-label\");\n if (attribute(trigger, \"aria-haspopup\") !== \"menu\") {\n problems.push(`menu: aria-haspopup is \"${attribute(trigger, \"aria-haspopup\") ?? \"\"}\", expected \"menu\"`);\n }\n if (attribute(trigger, \"aria-expanded\") !== \"false\") {\n problems.push(\n `menu: aria-expanded is \"${attribute(trigger, \"aria-expanded\") ?? \"\"}\" while closed, expected \"false\"`,\n );\n }\n if (!attribute(trigger, \"aria-controls\")) {\n problems.push(\"menu: the trigger has no aria-controls\");\n } else if (!facts.controlled) {\n problems.push(`menu: aria-controls=\"${attribute(trigger, \"aria-controls\")}\" names no element`);\n } else if (attribute(facts.controlled, \"role\") !== \"menu\") {\n problems.push(\n `menu: aria-controls names a ${facts.controlled.description} with role \"${attribute(facts.controlled, \"role\") ?? \"\"}\", expected \"menu\"`,\n );\n }\n }\n\n if (!facts.palette) {\n problems.push('palette: no [data-chrome=\"palette\"]');\n } else {\n const toolbar = facts.toolbar;\n if (!toolbar || attribute(toolbar, \"role\") !== \"toolbar\") {\n problems.push('palette: .djs-palette-entries has no role=\"toolbar\"');\n } else if (!attribute(toolbar, \"aria-label\")) {\n problems.push(\"palette: the toolbar has no aria-label\");\n }\n for (const entry of facts.entries) {\n const action = attribute(entry, \"data-action\") ?? entry.description;\n if (attribute(entry, \"role\") !== \"button\")\n problems.push(`palette: entry \"${action}\" has no role=\"button\"`);\n if (!attribute(entry, \"aria-label\"))\n problems.push(`palette: entry \"${action}\" has no aria-label (title)`);\n const tabindex = attribute(entry, \"tabindex\");\n if (tabindex !== \"0\" && tabindex !== \"-1\") {\n problems.push(`palette: entry \"${action}\" has tabindex \"${tabindex ?? \"\"}\", expected roving 0/-1`);\n }\n }\n const stops = facts.entries.filter((entry) => attribute(entry, \"tabindex\") === \"0\");\n if (facts.entries.length > 0 && stops.length !== 1) {\n problems.push(\n `palette: ${stops.length} entries with tabindex=\"0\", expected exactly one (roving tabindex)`,\n );\n }\n const tools = facts.entries.filter(\n (entry) => entry.group === \"tools\" && (attribute(entry, \"data-action\") ?? \"\").endsWith(\"-tool\"),\n );\n for (const tool of tools) {\n const pressed = attribute(tool, \"aria-pressed\");\n if (pressed !== \"true\" && pressed !== \"false\") {\n problems.push(`palette: tool \"${attribute(tool, \"data-action\")}\" has no aria-pressed`);\n }\n }\n const pressed = tools.filter((tool) => attribute(tool, \"aria-pressed\") === \"true\");\n if (pressed.length > 1) problems.push(`palette: ${pressed.length} tools are aria-pressed at once`);\n }\n\n const zoom = facts.zoom;\n if (!zoom) {\n problems.push('zoom: no [data-chrome=\"zoom\"]');\n } else {\n if (attribute(zoom, \"role\") !== \"group\") problems.push('zoom: the panel has no role=\"group\"');\n if (!attribute(zoom, \"aria-label\")) problems.push(\"zoom: the panel has no aria-label\");\n const shortcuts = expectedKeyShortcuts(facts.platform);\n for (const button of [\"out\", \"actual\", \"in\", \"fit\"] as const) {\n const control = facts.zoomButtons[button];\n if (!control) {\n problems.push(`zoom: no [data-zoom=\"${button}\"] button`);\n continue;\n }\n if (control.tag !== \"button\") problems.push(`zoom: [data-zoom=\"${button}\"] is a <${control.tag}>`);\n if (!name(control)) problems.push(`zoom: [data-zoom=\"${button}\"] has no accessible name`);\n if (attribute(control, \"aria-keyshortcuts\") !== shortcuts[button]) {\n problems.push(\n `zoom: [data-zoom=\"${button}\"] aria-keyshortcuts is \"${attribute(control, \"aria-keyshortcuts\") ?? \"\"}\", expected \"${shortcuts[button]}\" (${facts.platform})`,\n );\n }\n if (control.disabled) {\n problems.push(\n `zoom: [data-zoom=\"${button}\"] is natively disabled; aria-disabled keeps the focus (guide §5.8)`,\n );\n }\n }\n const readout = facts.zoomButtons.actual;\n if (readout) {\n if (!/\\d/.test(readout.text))\n problems.push(`zoom: the readout shows \"${readout.text}\", expected a percentage`);\n const label = normalize(attribute(readout, \"aria-label\") ?? \"\");\n if (!label.includes(readout.text)) {\n problems.push(\n `zoom: the readout's aria-label \"${label}\" does not name the current zoom \"${readout.text}\"`,\n );\n }\n if (attribute(readout, \"aria-disabled\") === \"true\")\n problems.push(\"zoom: the readout is never disabled\");\n }\n }\n\n const present = new Set(facts.order);\n const expectedOrder = DOM_ORDER.filter((part) => present.has(part));\n if (facts.order.join() !== expectedOrder.join()) {\n problems.push(\n `DOM order is ${facts.order.join(\", \")}; expected ${expectedOrder.join(\", \")} (guide §5.14)`,\n );\n }\n if (!present.has(\"canvas\")) problems.push(\"canvas: no diagram-js <svg> (.djs-container > svg) in the root\");\n const canvas = facts.canvas;\n if (canvas && !normalize(attribute(canvas, \"aria-label\") ?? \"\") && !attribute(canvas, \"aria-labelledby\")) {\n problems.push(\n 'canvas: the focusable <svg> has no accessible name (WCAG 4.1.2); shellModule names it role=\"application\" with messages.canvas',\n );\n }\n for (const element of facts.positiveTabindex)\n problems.push(`positive tabindex on ${element} (guide §5.14)`);\n for (const element of facts.titled) {\n problems.push(`${element} has a native title; the chrome tooltip replaces it (guide §5.6)`);\n }\n problems.push(...primaryAriaProblems(facts, host), ...legalAriaProblems(facts, host));\n return problems;\n}\n\n/** The optional islands once the harness showed them. */\nexport function optionalIslandProblems(facts: AriaFacts, shown: ReadonlySet<string>): string[] {\n const problems: string[] = [];\n if (shown.has(\"problems\")) {\n const pill = facts.problems;\n if (!pill?.visible) {\n problems.push(\"problems: the pill is not visible after show.problems\");\n } else {\n if (pill.tag !== \"button\") problems.push(`problems: the pill is a <${pill.tag}>, expected a <button>`);\n const label = normalize(attribute(pill, \"aria-label\") ?? \"\");\n if (!label) problems.push(\"problems: the pill has no aria-label (count and errors)\");\n else if (!label.includes(pill.text)) {\n problems.push(`problems: the aria-label \"${label}\" does not contain the visible text \"${pill.text}\"`);\n }\n }\n }\n if (shown.has(\"status\")) {\n const status = facts.status;\n if (!status?.visible) {\n problems.push(\"status: the status box is not visible after show.status\");\n } else {\n const role = attribute(status, \"role\");\n const severity = attribute(status, \"data-severity\");\n const expected = severity === \"danger\" ? \"alert\" : \"status\";\n if (role !== expected) {\n problems.push(\n `status: role is \"${role ?? \"\"}\" for data-severity=\"${severity ?? \"\"}\", expected \"${expected}\"`,\n );\n }\n }\n }\n if (shown.has(\"legend\")) {\n const legend = facts.legend;\n if (!legend?.visible) {\n problems.push(\"legend: the legend is not visible after show.legend\");\n } else {\n if (!facts.legendTitle)\n problems.push(\"legend: the card is not labelled by its title (aria-labelledby)\");\n if (!facts.legendClose || !attribute(facts.legendClose, \"aria-label\")) {\n problems.push(\"legend: the close button has no aria-label\");\n }\n }\n }\n if (shown.has(\"inspector\")) {\n const inspector = facts.inspector;\n if (!inspector?.visible) {\n problems.push(\"inspector: the inspector is not visible after show.inspector\");\n } else {\n if (inspector.tag !== \"aside\") problems.push(`inspector: a <${inspector.tag}>, expected an <aside>`);\n if (!attribute(inspector, \"aria-label\")) problems.push(\"inspector: the <aside> has no aria-label\");\n }\n }\n return problems;\n}\n\n/** One Tab stop as the kit's tab-sequence probe saw it. */\nexport interface TabStop {\n description: string;\n /** What the stop is: the palette's roving entry, the canvas `<svg>`, the web app's primary action. */\n kind: \"palette\" | \"canvas\" | \"primary\" | \"other\";\n}\n\n/**\n * Tab from the menu trigger (guide §5.14): the primary action (web app), the palette's one tab\n * stop, then the canvas `<svg>`; nothing else in between (a renderer's own `tabindex` on\n * `.djs-container` would be an extra, unnamed stop). With `primary` the web app shows one, and\n * Tab from the trigger lands on it first.\n */\nexport function tabSequenceProblems(stops: readonly TabStop[], primary = false): string[] {\n const [first, second, third] = stops;\n const sequence = first?.kind === \"primary\" ? [second, third] : [first, second];\n const [palette, canvas] = sequence;\n const problems: string[] = [];\n if (primary && first?.kind !== \"primary\") {\n problems.push(\n `tab order: Tab from the menu trigger lands on ${first?.description ?? \"nothing\"}, expected the primary action (top left, top right, top centre, guide §5.14)`,\n );\n }\n if (palette?.kind !== \"palette\") {\n problems.push(\n `tab order: Tab from the menu trigger lands on ${palette?.description ?? \"nothing\"}, expected the palette's roving entry (guide §5.14)`,\n );\n } else if (canvas?.kind !== \"canvas\") {\n problems.push(\n `tab order: Tab from the palette lands on ${canvas?.description ?? \"nothing\"}, expected the canvas <svg> (an unexpected tab stop, guide §5.14)`,\n );\n }\n return problems;\n}\n\n/** A palette entry with the keyboard focus: its tooltip's chip and what it names for assistive technology. */\nexport interface PaletteShortcutFacts {\n action: string;\n /** Text of the visible tooltip's `kbd` chip; empty without a chip. */\n chip: string;\n keyShortcuts: string | null;\n}\n\n/** Guide §5.6: an entry whose tooltip shows a shortcut carries `aria-keyshortcuts`. */\nexport function paletteShortcutProblems(entries: readonly PaletteShortcutFacts[]): string[] {\n return entries\n .filter((entry) => entry.chip && !entry.keyShortcuts)\n .map(\n (entry) =>\n `palette: entry \"${entry.action}\" shows the shortcut \"${entry.chip}\" in its tooltip but has no aria-keyshortcuts (guide §5.6)`,\n );\n}\n\n/**\n * The keys an open menu consumes (↑ ↓ Home End, a letter) never reach a `keydown` listener on\n * `document`: a modeler's document keyboard would act on them (Event Storming moves the selection\n * on ↑/↓).\n */\nexport function menuKeysAtDocumentProblems(\n pressed: readonly string[],\n documentKeys: readonly RecordedKey[],\n): string[] {\n const reached = new Set(documentKeys.map((key) => key.key));\n return pressed\n .filter((key) => reached.has(key))\n .map(\n (key) =>\n `menu: ${key} in the open menu reached a keydown listener on document; a modeler's document keyboard acts on it (stop it at the menu, guide §5.4)`,\n );\n}\n\n/** An open menu (guide §5.4): expanded trigger, labelled `role=\"menu\"`, named items, focus. */\nexport function menuOpenProblems(facts: MenuFacts, focus?: \"first\" | \"last\"): string[] {\n const problems: string[] = [];\n if (facts.expanded !== \"true\") {\n problems.push(`menu: aria-expanded is \"${facts.expanded ?? \"\"}\" while open, expected \"true\"`);\n }\n const menu = facts.menu;\n if (!menu) return [...problems, 'menu: no visible role=\"menu\" after opening'];\n if (!attribute(menu, \"aria-label\")) problems.push(\"menu: the dropdown has no aria-label\");\n if (facts.controls && attribute(menu, \"id\") !== facts.controls) {\n problems.push(\n `menu: the visible dropdown is #${attribute(menu, \"id\") ?? \"\"}, the trigger controls #${facts.controls}`,\n );\n }\n if (facts.items.length === 0) problems.push(\"menu: the dropdown has no menuitem\");\n facts.items.forEach((item, index) => {\n const label = item.name || `item ${index + 1}`;\n if (!item.name) problems.push(`menu: ${label} has no accessible name`);\n if (item.role !== \"menuitem\" && item.checked !== \"true\" && item.checked !== \"false\") {\n problems.push(`menu: \"${label}\" (${item.role}) has aria-checked \"${item.checked ?? \"\"}\"`);\n }\n if (item.role === \"menuitemradio\" && !item.group) {\n problems.push(`menu: radio \"${label}\" is not in a labelled role=\"group\"`);\n }\n if (item.haspopup === \"dialog\" && !item.name.endsWith(\"…\")) {\n problems.push(`menu: \"${label}\" opens a dialog, so its label ends with \"…\" (U+2026)`);\n }\n });\n if (focus && facts.items.length > 0) {\n const expected = focus === \"first\" ? 0 : facts.items.length - 1;\n if (facts.active !== expected) {\n problems.push(\n `menu: focus is on ${facts.active < 0 ? \"no entry\" : `entry ${facts.active + 1}`}, expected the ${focus} entry`,\n );\n }\n }\n return problems;\n}\n\nexport function menuClosedProblems(facts: MenuFacts, focusOnTrigger: boolean): string[] {\n const problems: string[] = [];\n if (facts.expanded !== \"false\")\n problems.push(`menu: aria-expanded is \"${facts.expanded ?? \"\"}\" after closing`);\n if (facts.menu) problems.push(\"menu: the dropdown is still visible after Escape\");\n if (focusOnTrigger && !facts.activeIsTrigger)\n problems.push(\"menu: Escape did not return the focus to the trigger\");\n return problems;\n}\n\n/**\n * How a key press must arrive at a `keydown` listener on `window` (guide §5.8, §13.5):\n * - `handled`: the shell executes it; IDE: stopped, else it arrives prevented;\n * - `blocked`: recognized but not executed (text field, modal, Escape with a dialog); IDE: stopped,\n * else it arrives unprevented (the browser, the field or the dialog acts);\n * - `canvas`: the canvas handled it (`defaultPrevented`); IDE: stopped, else it arrives prevented;\n * - `free`: nobody may handle it; it arrives unprevented in every host.\n * In the IDE host a stopped key never reaches `window`, so `prevented` is read on `document`.\n */\nexport type KeyReach = \"handled\" | \"blocked\" | \"canvas\" | \"free\";\n\nexport interface SeenKeys {\n /** What a listener on `window` saw. */\n keys: readonly RecordedKey[];\n /** What a listener on `document`, registered after the shell's, saw. */\n documentKeys?: readonly RecordedKey[];\n}\n\nexport function keyReachProblem(\n press: string,\n reach: KeyReach,\n host: ShellHost,\n seen: SeenKeys,\n): string | undefined {\n const shouldPrevent = reach === \"handled\" || reach === \"canvas\";\n if (host === \"ide\" && reach !== \"free\") {\n if (seen.keys.length > 0) {\n return `${press} reached a keydown listener on window; in the IDE host the shell stops it on document, or VS Code runs it again (guide §13.5)`;\n }\n const atDocument = seen.documentKeys ?? [];\n const prevented = atDocument.length === 1 ? atDocument[0]?.defaultPrevented : undefined;\n if (prevented === true && !shouldPrevent) {\n return `${press} was prevented; the shell only stops it, so the field, dialog or browser still acts (guide §13.5)`;\n }\n if (prevented === false && shouldPrevent) {\n return `${press} was stopped but not prevented; a handled key also calls preventDefault`;\n }\n return undefined;\n }\n if (seen.keys.length === 0) {\n return host === \"ide\"\n ? `${press} never reached window; keys the webview does not handle must go on to VS Code (guide §13.5)`\n : `${press} never reached window; outside the IDE host the shell never stops propagation`;\n }\n if (seen.keys.length > 1) return `${press} reached window ${seen.keys.length} times`;\n const prevented = seen.keys[0]?.defaultPrevented ?? false;\n if (prevented && !shouldPrevent) {\n return `${press} arrived prevented; ${reach === \"free\" ? \"nothing may handle it\" : \"the browser, the field or the dialog must act\"}`;\n }\n if (!prevented && shouldPrevent) {\n return `${press} arrived unprevented; a handled key calls preventDefault (the browser would zoom the page)`;\n }\n return undefined;\n}\n\n/** The decision of guide §13.5, computed independently of the shell under test. */\nexport function expectedAppearance(requested: Appearance, themes: readonly Theme[]): Appearance {\n const fallback = themes[0];\n if (fallback === undefined) throw new Error(\"@miragon/modeler-shell conformance: harness.themes is empty\");\n const theme = themes.includes(requested.theme) ? requested.theme : fallback;\n return requested.kontrast ? { theme, kontrast: requested.kontrast } : { theme };\n}\n\nconst describeAppearance = (appearance: Appearance): string =>\n appearance.kontrast ? `${appearance.theme} + ${appearance.kontrast}` : appearance.theme;\n\nexport interface AppearanceVerdict {\n problems: string[];\n}\n\n/**\n * What an embedded root must show (guide §13.3): until the contract's `appearance` surface there\n * is no channel to ask it for a mode, so it stays in its first one whatever the page shows, and\n * takes the page's high contrast over from the nearest mode carrier above it.\n */\nexport function expectedEmbeddedAppearance(facts: AppearanceFacts, themes: readonly Theme[]): Appearance {\n const fallback = themes[0];\n if (fallback === undefined) throw new Error(\"@miragon/modeler-shell conformance: harness.themes is empty\");\n const host = facts.themed.filter((element) => element.relation === \"ancestor\").at(-1);\n return host?.kontrast === \"hoch\" ? { theme: fallback, kontrast: \"hoch\" } : { theme: fallback };\n}\n\n/**\n * The web app's own expectation (guide §13.3): `<html>` carries `carrier` (`system` for a\n * dark-capable modeler without a stored choice) and the page shows `effective` under the emulated\n * system preference.\n */\nexport interface WebModeExpectation {\n carrier: string;\n effective: Appearance;\n}\n\n/** No half-dark (guide §13.3, §13.5): one mode on `<html>` (own document) or the root (embedded). */\nexport function appearanceProblems(\n facts: AppearanceFacts,\n host: ShellHost,\n requested: Appearance,\n themes: readonly Theme[],\n web?: WebModeExpectation,\n): AppearanceVerdict {\n const ownDocument = host !== \"embedded\";\n const expected =\n web?.effective ??\n (ownDocument ? expectedAppearance(requested, themes) : expectedEmbeddedAppearance(facts, themes));\n const carrierTheme = web?.carrier ?? expected.theme;\n const problems: string[] = [];\n const described =\n carrierTheme === expected.theme\n ? describeAppearance(expected)\n : `${carrierTheme} showing ${describeAppearance(expected)}`;\n const label = ownDocument\n ? `requested ${describeAppearance(requested)}, expected ${described}`\n : `host page ${describeAppearance(requested)}, expected ${described}`;\n\n const carrier = ownDocument\n ? facts.themed.find((element) => element.isDocument && element.theme !== null)\n : facts.themed.find((element) => element.relation === \"self\" && element.theme !== null);\n if (!carrier) {\n problems.push(\n ownDocument\n ? `<html> has no data-cd-theme (${label}); the host always writes it, also \"light\" (guide §13.3)`\n : `the embedded root has no data-cd-theme (${label}): it takes the host page's mode instead of its own (guide §13.3)`,\n );\n } else {\n if (carrier.theme !== carrierTheme) {\n problems.push(`${carrier.description} has data-cd-theme=\"${carrier.theme}\" (${label})`);\n }\n if ((carrier.kontrast ?? undefined) !== expected.kontrast) {\n problems.push(\n `${carrier.description} has ${carrier.kontrast ? `data-cd-kontrast=\"${carrier.kontrast}\"` : \"no data-cd-kontrast\"} (${label})`,\n );\n }\n }\n for (const element of facts.themed) {\n if (element === carrier) continue;\n const stray = ownDocument\n ? !element.isDocument || element.theme === null\n : element.relation === \"descendant\" || element.relation === \"self\";\n if (!stray) continue;\n const values = [\n element.theme !== null ? `data-cd-theme=\"${element.theme}\"` : \"\",\n element.kontrast !== null ? `data-cd-kontrast=\"${element.kontrast}\"` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n const sameMode =\n carrier !== undefined && element.theme === carrier.theme && element.kontrast === carrier.kontrast;\n problems.push(\n element.theme === null\n ? `${element.description} carries ${values} without data-cd-theme on the same element (guide §13.3)`\n : sameMode\n ? `${element.description} repeats ${values}: in an own document the attributes stand only on <html> (guide §13.5)`\n : `${element.description} carries ${values}: a second mode inside the modeler is half-dark (guide §13.5)`,\n );\n }\n\n if (ownDocument && !facts.documentClasses.includes(\"cd-shell-document\")) {\n problems.push(\n \"<html> lacks cd-shell-document in an own document (the reset of the webview's host styles)\",\n );\n }\n if (!ownDocument && facts.documentClasses.includes(\"cd-shell-document\")) {\n problems.push(\n \"<html> of a foreign page carries cd-shell-document: the own-document reset restyles the host page\",\n );\n }\n\n const reference = facts.parts[0];\n if (reference && !reference.roles[\"--cd-ui-text\"]) {\n problems.push(\n \"--cd-ui-text is empty at the shell root: the vendored cd-tokens.generated.css is not loaded\",\n );\n }\n for (const part of facts.parts) {\n const schemes = part.colorScheme.split(/\\s+/);\n const dark = schemes.includes(\"dark\");\n const light = schemes.includes(\"light\");\n if (expected.theme === \"light\" && (dark || (carrier && !light))) {\n problems.push(`${part.name}: color-scheme is \"${part.colorScheme}\" (${label})`);\n }\n if (expected.theme === \"dark\" && (!dark || light)) {\n problems.push(`${part.name}: color-scheme is \"${part.colorScheme}\" (${label})`);\n }\n if (reference && part !== reference) {\n for (const [role, value] of Object.entries(part.roles)) {\n if (value !== reference.roles[role]) {\n problems.push(\n `${part.name}: ${role} resolves to \"${value}\", the root to \"${reference.roles[role] ?? \"\"}\" (half-dark)`,\n );\n }\n }\n }\n }\n for (const required of [\"dropdown\", \"tooltip\"]) {\n if (!facts.parts.some((part) => part.name === required)) {\n problems.push(`${required}: not visible when the kit opened it, so its mode was not checked`);\n }\n }\n return { problems };\n}\n\n/** The root attributes the shell writes (API.md, DOM; the web host's state attributes included). */\nconst SHELL_ROOT_ATTRIBUTES = [\n \"data-cd-shell-host\",\n \"data-palette\",\n \"data-legend\",\n \"data-inspector\",\n \"data-problems\",\n \"data-readonly\",\n \"data-primary\",\n \"data-zoom-row\",\n \"data-empty-state\",\n \"data-drop\",\n];\n\n/** What an embedded root carries on top (its own mode). */\nconst EMBEDDED_ROOT_ATTRIBUTES = [\"data-cd-theme\", \"data-cd-kontrast\"];\n\n/** Messages of benign browser reports that are no shell error. */\nconst BENIGN_ERRORS = /ResizeObserver loop/;\n\n/** Nothing of the shell remains after `destroy` (API.md, `destroy()`). */\nexport function leftoverProblems(facts: LeftoverFacts, host: ShellHost): string[] {\n const problems: string[] = [];\n for (const element of facts.classedElements) problems.push(`${element} is left after destroy`);\n const ownDocument = host !== \"embedded\";\n for (const name of facts.documentClasses) {\n if (ownDocument && name === \"cd-shell-document\") continue;\n problems.push(`<html> keeps the class ${name} after destroy`);\n }\n for (const element of facts.chromeElements) problems.push(`${element} is left after destroy`);\n for (const name of facts.rootClasses) problems.push(`the root keeps the class ${name} after destroy`);\n const written = ownDocument\n ? SHELL_ROOT_ATTRIBUTES\n : [...SHELL_ROOT_ATTRIBUTES, ...EMBEDDED_ROOT_ATTRIBUTES];\n for (const name of facts.rootAttributes) {\n if (written.includes(name)) problems.push(`the root keeps ${name} after destroy`);\n }\n for (const error of facts.errors) {\n if (!BENIGN_ERRORS.test(error)) problems.push(`the page reported an error after destroy: ${error}`);\n }\n return problems;\n}\n\n/** After `destroy` no listener of the shell may act on a chrome key any more. */\nexport function afterDestroyKeyProblem(press: string, recorded: readonly RecordedKey[]): string | undefined {\n if (recorded.length === 0)\n return `${press} after destroy never reached window: a shell listener still stops it`;\n if (recorded.some((key) => key.defaultPrevented)) {\n return `${press} after destroy arrived prevented: a shell listener is still installed`;\n }\n return undefined;\n}\n\n/** The islands a harness may list as `absent`, as far as `geometry` and `aria` see them. */\nexport type AbsentIsland = Extract<ShowHook, \"legend\" | \"inspector\" | \"problems\" | \"status\">;\n\nconst ABSENT_ISLANDS: readonly AbsentIsland[] = [\"legend\", \"inspector\", \"problems\", \"status\"];\n\n/** The islands of `absent` (its state `invalid` has no island). */\nexport function absentIslands(absent: readonly AbsentFeature[] | undefined): AbsentIsland[] {\n return ABSENT_ISLANDS.filter((island) => absent?.includes(island));\n}\n\n/** An island the harness declares absent must never show. */\nexport function absentIslandProblems(\n visible: ReadonlySet<string>,\n absent: readonly AbsentFeature[] | undefined,\n): string[] {\n return absentIslands(absent)\n .filter((island) => visible.has(island))\n .map((island) => `${island}: visible, but harness.absent says the modeler has no ${island}`);\n}\n\n/** A hook the harness both gives and lists as absent is a contradiction in the harness itself. */\nexport function harnessHookProblems<P extends PageLike>(\n harness: ShellConformanceHarness<P>,\n hooks: readonly AbsentFeature[],\n): string[] {\n return hooks\n .filter((hook) =>\n hook === \"drop\"\n ? harness.absent?.includes(\"drop\") && harness.drop\n : hook !== \"problemSelection\" && harness.absent?.includes(hook) && harness.show?.[hook],\n )\n .map((hook) =>\n hook === \"drop\"\n ? 'harness: absent lists \"drop\", but harness.drop is given'\n : `harness: absent lists \"${hook}\", but show.${hook} is given`,\n );\n}\n\n/** Guide §10.1: the surround of the canvas is a container painted in `--cd-ui-grund`, in both modes. */\nexport function surroundProblems(facts: SurroundFacts): string[] {\n if (!facts.container) return [\"canvas surround: no .djs-container in the root to check\"];\n if (!facts.painted) {\n return [\n \"canvas surround: nothing from .djs-container out to the root paints a background colour; the surround is var(--cd-ui-grund) (guide §10.1)\",\n ];\n }\n if (facts.painted.color === facts.grund) return [];\n return [\n `canvas surround: ${facts.painted.description} paints ${facts.painted.color}, but --cd-ui-grund resolves to ${facts.grund}; the surround follows the mode (guide §10.1)`,\n ];\n}\n\n/** Lasso, Hand and the other tools of the `tools` group; every other entry is a notation preview. */\nexport function isToolEntry(entry: Pick<PaletteEntryState, \"action\" | \"group\">): boolean {\n return entry.group === \"tools\" || entry.action.endsWith(\"-tool\");\n}\n\nfunction paletteEntryState(entry: PaletteColorEntry): string {\n if (entry.disabled) return \"aria-disabled\";\n if (entry.hovered) return entry.pressed ? \"pressed and hovered\" : \"hovered\";\n return entry.pressed ? \"pressed\" : \"at rest\";\n}\n\n/**\n * Guide §5.5 and §13.5: a tool entry and its icon (`currentColor`) show `--cd-ui-text` at rest and\n * while pressed, `--cd-ui-interaktion` while hovered and `--cd-ui-text-leise` while aria-disabled.\n * Notation previews keep their own colours and are exempt.\n */\nexport function paletteColorProblems(facts: PaletteColorFacts): string[] {\n const problems: string[] = [];\n for (const entry of facts.entries) {\n if (!isToolEntry(entry)) continue;\n const [role, value] = entry.disabled\n ? ([\"--cd-ui-text-leise\", facts.roles.textLeise] as const)\n : entry.hovered\n ? ([\"--cd-ui-interaktion\", facts.roles.interaktion] as const)\n : ([\"--cd-ui-text\", facts.roles.text] as const);\n const state = paletteEntryState(entry);\n if (entry.color !== value) {\n problems.push(\n `palette: tool \"${entry.action}\" ${state} has color ${entry.color}, expected ${role} (${value}) (guide §5.5)`,\n );\n }\n if (entry.icon && entry.icon.color !== value) {\n const icon = entry.icon.kind === \"svg\" ? \"<svg> icon\" : \"::before icon\";\n problems.push(\n `palette: the ${icon} of tool \"${entry.action}\" ${state} has color ${entry.icon.color}, expected ${role} (${value}); a renderer rule overrides the skin (guide §5.5)`,\n );\n }\n }\n return problems;\n}\n\nexport interface CreateFacts {\n /** `data-action` of the entry the kit pressed Enter on. */\n entry: string;\n before: readonly ShapeFacts[];\n after: readonly ShapeFacts[];\n canvas: CanvasStateFacts;\n /** The free rectangle when Enter was pressed (guide §5.9). */\n free: Rectangle;\n}\n\nconst round = (value: number): number => Math.round(value * 10) / 10;\n\n/**\n * Guide §5.5: Enter on a creating entry places exactly one element in the centre of the free\n * rectangle, selects it and puts the focus on the canvas (its `<svg>` or the label editor).\n */\nexport function createProblems(facts: CreateFacts): string[] {\n const known = new Set(facts.before.map((shape) => shape.id));\n const added = facts.after.filter((shape) => !known.has(shape.id));\n const pressed = `Enter on palette entry \"${facts.entry}\"`;\n if (added.length === 0) {\n return [\n `create: ${pressed} added no element; Enter on a creating entry places it in the centre of the free rectangle (guide §5.5)`,\n ];\n }\n if (added.length > 1) {\n return [\n `create: ${pressed} added ${added.length} elements (${added.map((shape) => shape.id).join(\", \")}), expected exactly one`,\n ];\n }\n const [shape] = added as [ShapeFacts];\n const problems: string[] = [];\n if (!shape.selected) problems.push(`create: the new element \"${shape.id}\" is not selected (guide §5.5)`);\n if (!facts.canvas.focusInCanvas) {\n problems.push(\n `create: after ${pressed} the focus is on ${facts.canvas.focused}, expected the canvas (its <svg> or the label editor, guide §5.5)`,\n );\n }\n const centre = { x: shape.box.left + shape.box.width / 2, y: shape.box.top + shape.box.height / 2 };\n const { free } = facts;\n const tolerance = GEOMETRY_TOLERANCE_PX + 1e-6;\n const inside =\n centre.x >= free.left - tolerance &&\n centre.x <= free.right + tolerance &&\n centre.y >= free.top - tolerance &&\n centre.y <= free.bottom + tolerance;\n if (!inside) {\n problems.push(\n `create: the new element \"${shape.id}\" is centred at (${round(centre.x)}, ${round(centre.y)})px, outside the free rectangle ${round(free.left)}–${round(free.right)} × ${round(free.top)}–${round(free.bottom)}px (guide §5.5, §5.9)`,\n );\n }\n return problems;\n}\n\n/** The read-only marks once the invalid-file state shows (guide §5.12, §13.5). */\nexport function readOnlyStateProblems(facts: ReadOnlyStateFacts): string[] {\n const problems: string[] = [];\n const after = `${INVALID_STATUS_DELAY_MS}ms after show.invalid`;\n if (!facts.readOnly) problems.push(`read-only: the root has no data-readonly ${after}`);\n const status = facts.status;\n if (!status?.visible) {\n problems.push(`read-only: the status box is not visible ${after} (guide §5.12)`);\n } else if (status.attributes.role !== \"alert\") {\n problems.push(\n `read-only: the status box of an invalid file has role \"${status.attributes.role ?? \"\"}\", expected \"alert\" (guide §13.5)`,\n );\n }\n return problems;\n}\n\n/** The palette entries that stay active on a read-only canvas (guide §13.5), named independently of the shell. */\nexport const READ_ONLY_PALETTE_ACTIONS: readonly string[] = [\"lasso-tool\", \"hand-tool\"];\n\n/** Guide §13.5: every palette entry that changes something is aria-disabled, Lasso and Hand stay active. */\nexport function readOnlyPaletteProblems(entries: readonly PaletteEntryState[]): string[] {\n return entries.flatMap((entry) => {\n const staysActive = READ_ONLY_PALETTE_ACTIONS.includes(entry.action);\n if (staysActive && entry.disabled) {\n return [\n `palette: \"${entry.action}\" is aria-disabled on the read-only canvas; Lasso and Hand stay active (guide §13.5)`,\n ];\n }\n if (!staysActive && !entry.disabled) {\n return [`palette: \"${entry.action}\" is not aria-disabled on the read-only canvas (guide §13.5)`];\n }\n return [];\n });\n}\n\n/** The shell's own Legend toggle in the Model group. */\nconst LEGEND_MENU_ID = \"legend\";\n\n/**\n * Guide §13.5 and the product decision on view toggles: on a read-only canvas the Legend toggle,\n * export and help stay usable. The shell renders its `MenuGroups` as Model, Export, Help, empty\n * groups left out, so only the first group can be Model: an entry in a later one that read-only\n * newly disabled is a problem.\n */\nexport function readOnlyMenuProblems(\n before: readonly MenuEntryFacts[],\n after: readonly MenuEntryFacts[],\n): string[] {\n const problems: string[] = [];\n const key = (entry: MenuEntryFacts) => `${entry.menuId ?? \"\"}\\u0000${entry.name}`;\n const enabledBefore = new Set(before.filter((entry) => !entry.disabled).map(key));\n for (const entry of after) {\n if (!entry.disabled) continue;\n if (entry.menuId === LEGEND_MENU_ID && entry.role === \"menuitemcheckbox\") {\n problems.push(\n \"menu: the Legend toggle is aria-disabled on the read-only canvas; a view-only toggle stays usable (guide §13.5)\",\n );\n } else if (entry.group !== \"model\" && enabledBefore.has(key(entry))) {\n problems.push(\n `menu: \"${entry.name}\" is aria-disabled on the read-only canvas; export and help stay usable (guide §13.5)`,\n );\n }\n }\n return problems;\n}\n\n/** What the read-only lock must keep from a shape (guide §13.5): no context pad, move, resize, delete or label editor. */\nexport interface LockedShapeFacts {\n /** Context-pad entries visible after clicking the shape. */\n contextPadEntries: readonly string[];\n /** The shape before and after a 40px drag (`undefined`: gone). */\n dragged: { before: ShapeFacts; after: ShapeFacts | undefined };\n /** Text fields inside `.djs-container` after a double-click on the shape. */\n textFields: readonly string[];\n /** Whether the shape is still there after Delete, then after Backspace. */\n kept: { Delete: boolean; Backspace: boolean };\n}\n\nexport function lockedShapeProblems(facts: LockedShapeFacts): string[] {\n const problems: string[] = [];\n const { before, after } = facts.dragged;\n if (facts.contextPadEntries.length > 0) {\n problems.push(\n `read-only: selecting \"${before.id}\" shows the context pad (${facts.contextPadEntries.join(\", \")}) (guide §13.5)`,\n );\n }\n if (!after) {\n problems.push(`read-only: a 40px drag removed \"${before.id}\" from the canvas (guide §13.5)`);\n } else if (\n after.transform !== before.transform ||\n Math.abs(after.size.width - before.size.width) > 0.5 ||\n Math.abs(after.size.height - before.size.height) > 0.5\n ) {\n problems.push(\n `read-only: a 40px drag changed \"${before.id}\" (transform \"${before.transform}\" → \"${after.transform}\", ${round(before.size.width)} × ${round(before.size.height)} → ${round(after.size.width)} × ${round(after.size.height)}) (guide §13.5)`,\n );\n }\n if (facts.textFields.length > 0) {\n problems.push(\n `read-only: a double-click on \"${before.id}\" opens a text field (${facts.textFields.join(\", \")}) (guide §13.5)`,\n );\n }\n for (const key of [\"Delete\", \"Backspace\"] as const) {\n if (!facts.kept[key])\n problems.push(`read-only: ${key} on the canvas deleted \"${before.id}\" (guide §13.5)`);\n }\n return problems;\n}\n","import { TOOLTIP_DELAY_MS, type Appearance, type ShellHost, type Size } from \"../core/index.js\";\nimport { harnessHookProblems } from \"./checks.js\";\nimport { menuEntriesProbe, shapesProbe, type MenuEntryFacts, type ShapeFacts } from \"./facts.js\";\nimport type {\n AbsentFeature,\n OpenContext,\n ShellCaseOutcome,\n ShellConformanceHarness,\n ShellSkip,\n ShowHook,\n ShowHooks,\n} from \"./harness.js\";\nimport type { PageLike } from \"./page.js\";\nimport { findTarget, inPage, settle, type ChromeTarget, type TargetFacts } from \"./page-tools.js\";\n\n/*\n * What every case shares: opening the harness, failing and finishing, skips, polling and the\n * pointer and menu moves the cases make.\n */\n\n/** Wide, narrow and very narrow (guide §5.15); 900 is above, 700 below the low breakpoint. */\nexport const DEFAULT_SIZES: readonly Size[] = [\n { width: 1280, height: 900 },\n { width: 720, height: 700 },\n { width: 420, height: 700 },\n];\n\nexport const LIGHT: Appearance = { theme: \"light\" };\n\n/** Shown in this order, so the legend is measured without and then with the pill. */\nexport const SHOWN_ISLANDS = [\"legend\", \"problems\", \"status\", \"inspector\"] as const satisfies ReadonlyArray<\n keyof ShowHooks\n>;\n\nexport const POLL_MS = 50;\n\n/** Room for the chrome tooltip's own fade after its 300ms hover delay. */\nexport const HOVER_MARGIN_MS = 200;\n\n/** A spot without chrome: the root's top-left corner lies outside every island (12px edge). */\nexport const PARK = { x: 1, y: 1 } as const;\n\nexport function sizeLabel(size: Size): string {\n return `${size.width} × ${size.height}`;\n}\n\nexport function fail(caseName: string, host: ShellHost, problems: readonly string[]): never {\n const unique = [...new Set(problems)];\n throw new Error(\n `@miragon/modeler-shell conformance: ${caseName} (${host} host)\\n${unique.map((problem) => `- ${problem}`).join(\"\\n\")}`,\n );\n}\n\nexport function finish(\n caseName: string,\n host: ShellHost,\n problems: readonly string[],\n skipped: Iterable<ShellSkip>,\n): ShellCaseOutcome | void {\n if (problems.length > 0) fail(caseName, host, problems);\n const seen = new Set<string>();\n const unique = [...skipped].filter((skip) => !seen.has(skip.reason) && seen.add(skip.reason));\n return unique.length > 0 ? { skipped: unique } : undefined;\n}\n\n/** A harness that gives a hook it also declares absent contradicts itself: fail before opening anything. */\nexport function assertHooksConsistent<P extends PageLike>(\n caseName: string,\n harness: ShellConformanceHarness<P>,\n hooks: readonly AbsentFeature[],\n): void {\n const problems = harnessHookProblems(harness, hooks);\n if (problems.length > 0) fail(caseName, harness.host, problems);\n}\n\n/** A hook that is neither given nor declared absent. */\nexport function unfed<P extends PageLike>(harness: ShellConformanceHarness<P>, hook: ShowHook): boolean {\n return !harness.show?.[hook] && !harness.absent?.includes(hook);\n}\n\n/**\n * Opens the harness. In the web host the system's mode and contrast come first, through\n * `page.emulateMedia` where the page has it (API.md, `./testing`): the page's head script reads\n * them before the first paint.\n */\nexport async function openHarness<P extends PageLike>(\n page: P,\n harness: ShellConformanceHarness<P>,\n context: OpenContext,\n): Promise<void> {\n if (harness.host === \"web\" && page.emulateMedia) {\n await page.emulateMedia({\n colorScheme: context.requested.theme,\n contrast: context.requested.kontrast === \"hoch\" ? \"more\" : \"no-preference\",\n });\n }\n await harness.open(page, context);\n}\n\n/**\n * The web column's hooks a case of `host` needs, each with what it would have verified: the start\n * screen in the web app, toasts outside the IDE host.\n */\nexport function webHookSkips<P extends PageLike>(\n harness: ShellConformanceHarness<P>,\n hooks: Partial<Record<\"toast\" | \"emptyState\", string>>,\n): ShellSkip[] {\n return (Object.entries(hooks) as Array<[\"toast\" | \"emptyState\", string]>)\n .filter(([hook]) => (hook === \"toast\" ? harness.host !== \"ide\" : harness.host === \"web\"))\n .filter(([hook]) => unfed(harness, hook))\n .map(([hook, what]) => ({ hook, reason: `show.${hook} is undefined: ${what} not verified` }));\n}\n\n/** Reads until `done` holds or `timeoutMs` passed; the last value either way. */\nexport async function pollUntil<T>(\n page: PageLike,\n read: () => Promise<T>,\n done: (value: T) => boolean,\n timeoutMs: number,\n): Promise<T> {\n let value = await read();\n for (let waited = 0; !done(value) && waited < timeoutMs; waited += POLL_MS) {\n await page.waitForTimeout(POLL_MS);\n value = await read();\n }\n return value;\n}\n\n/** Hovers `target` long enough for its chrome tooltip; the hovered control, `null` when there is none. */\nexport async function hover(page: PageLike, root: string, target: ChromeTarget): Promise<TargetFacts | null> {\n const anchor = await findTarget(page, root, target);\n if (!anchor) return null;\n await page.mouse.move(PARK.x, PARK.y);\n await page.mouse.move(anchor.client.x, anchor.client.y);\n await page.waitForTimeout(TOOLTIP_DELAY_MS + HOVER_MARGIN_MS);\n await settle(page);\n return anchor;\n}\n\nexport async function openMenuByClick(page: PageLike, root: string): Promise<boolean> {\n const trigger = await findTarget(page, root, \"menu\");\n if (!trigger) return false;\n await page.mouse.click(trigger.client.x, trigger.client.y);\n await settle(page);\n return true;\n}\n\nexport async function closeByEscape(page: PageLike): Promise<void> {\n await page.keyboard.press(\"Escape\");\n await settle(page);\n}\n\n/** The open menu's entries, opened by a click and closed again by Escape. */\nexport async function menuEntries(page: PageLike, root: string): Promise<MenuEntryFacts[]> {\n if (!(await openMenuByClick(page, root))) return [];\n const entries = (await inPage(page, menuEntriesProbe, { root })) ?? [];\n await closeByEscape(page);\n return entries;\n}\n\n/** The visible shapes on the canvas. */\nexport function shapes(page: PageLike, root: string): Promise<ShapeFacts[]> {\n return inPage(page, shapesProbe, { root });\n}\n","import type { Size } from \"../core/index.js\";\nimport type { DropFixture } from \"./harness.js\";\nimport type { ModeChange, RelativeBox, ToolWindow } from \"./page-tools.js\";\n\n/*\n * In-page probes of the web column (0.2): mode and meta tags, top row, start screen, toasts,\n * problems list and drop zone. Like facts.ts, every probe runs in the page and stays\n * self-contained; the judgements are in web-checks.ts.\n */\n\ntype Point = { x: number; y: number };\n\n/** `<html>`'s mode, its meta tags and the stored choice of the web app (guide §13.3). */\nexport interface WebModeFacts {\n theme: string | null;\n kontrast: string | null;\n /** `content` of `<meta name=\"color-scheme\">`; `null` without one. */\n colorScheme: string | null;\n themeColors: Array<{ content: string; media: string | null }>;\n /** `localStorage[key]`; `null` without an entry. */\n stored: string | null;\n storageBlocked: boolean;\n noTransition: boolean;\n}\n\nexport const webModeProbe = ({ key }: { key: string }): WebModeFacts => {\n const html = document.documentElement;\n let stored: string | null = null;\n let storageBlocked = false;\n try {\n stored = localStorage.getItem(key);\n } catch {\n storageBlocked = true;\n }\n return {\n theme: html.getAttribute(\"data-cd-theme\"),\n kontrast: html.getAttribute(\"data-cd-kontrast\"),\n colorScheme: document.querySelector('meta[name=\"color-scheme\"]')?.getAttribute(\"content\") ?? null,\n themeColors: [...document.querySelectorAll('meta[name=\"theme-color\"]')].map((meta) => ({\n content: meta.getAttribute(\"content\") ?? \"\",\n media: meta.getAttribute(\"media\"),\n })),\n stored,\n storageBlocked,\n noTransition: html.classList.contains(\"cd-shell-no-transition\"),\n };\n};\n\n/**\n * Records every change of `<html data-cd-theme>`, `data-cd-kontrast`, `cd-shell-no-transition` and\n * the `color-scheme` and `theme-color` metas, with the animation frame each landed in, until\n * `modeChangesProbe` reads them.\n */\nexport const watchModeProbe = (_: null): void => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n tools.modeWatch?.stop();\n const html = document.documentElement;\n const changes: ModeChange[] = [];\n let frame = 0;\n let running = true;\n const tick = () => {\n if (!running) return;\n frame += 1;\n requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n const observer = new MutationObserver((records) => {\n for (const record of records) {\n const target = record.target as Element;\n if (target === html) {\n if (record.attributeName === \"class\") {\n const had = (record.oldValue ?? \"\").split(/\\s+/).includes(\"cd-shell-no-transition\");\n const has = html.classList.contains(\"cd-shell-no-transition\");\n if (had !== has) changes.push({ part: \"no-transition\", value: has ? \"on\" : \"off\", frame });\n } else if (record.attributeName === \"data-cd-theme\") {\n changes.push({ part: \"theme\", value: html.getAttribute(\"data-cd-theme\"), frame });\n } else if (record.attributeName === \"data-cd-kontrast\") {\n changes.push({ part: \"kontrast\", value: html.getAttribute(\"data-cd-kontrast\"), frame });\n }\n } else if (target.localName === \"meta\") {\n const name = target.getAttribute(\"name\");\n const media = target.getAttribute(\"media\");\n changes.push({\n part: name === \"color-scheme\" ? \"color-scheme\" : \"theme-color\",\n value: `${target.getAttribute(\"content\") ?? \"\"}${media ? ` ${media}` : \"\"}`,\n frame,\n });\n }\n }\n });\n observer.observe(html, {\n attributes: true,\n attributeOldValue: true,\n attributeFilter: [\"data-cd-theme\", \"data-cd-kontrast\", \"class\"],\n });\n for (const meta of document.querySelectorAll('meta[name=\"color-scheme\"], meta[name=\"theme-color\"]')) {\n observer.observe(meta, { attributes: true, attributeFilter: [\"content\"] });\n }\n tools.modeWatch = {\n changes,\n stop() {\n running = false;\n observer.disconnect();\n },\n };\n};\n\n/** The changes `watchModeProbe` recorded since it started; stops the recording. */\nexport const modeChangesProbe = (_: null): ModeChange[] => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const watch = tools.modeWatch;\n if (!watch) return [];\n watch.stop();\n tools.modeWatch = undefined;\n return [...watch.changes];\n};\n\n/** What the top row decision of guide §5.15 reads, as the shell measures it. */\nexport interface TopRowFacts {\n container: Size;\n paletteRow: \"top\" | \"second-row\";\n /** The palette's intrinsic border-box width (`offsetWidth − clientWidth + scrollWidth`). */\n paletteWidth: number | null;\n /** Right edge of the menu trigger, relative to the root. */\n menuRight: number | null;\n primary: {\n box: RelativeBox;\n client: Point;\n /** The root's `data-primary=\"collapsed\"`. */\n collapsed: boolean;\n ariaLabel: string | null;\n describedBy: string | null;\n /** Text of the visible label; `null` while no label shows. */\n label: string | null;\n } | null;\n}\n\n/** The legal line and each of its links, relative to the root (guide §5.10). */\nexport interface LegalLineFacts {\n container: { width: number; height: number };\n legal: RelativeBox | null;\n links: Array<{ text: string; box: RelativeBox }>;\n}\n\nexport const legalLineProbe = ({ root }: { root: string }): LegalLineFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const legal = rootElement.querySelector('[data-chrome=\"legal\"]');\n return {\n container: tools.container(rootElement),\n legal: legal && tools.visible(legal) ? tools.box(legal, rootElement) : null,\n links: [...(legal?.querySelectorAll(\"a\") ?? [])].map((link) => ({\n text: (link.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n box: tools.box(link, rootElement),\n })),\n };\n};\n\nexport const topRowProbe = ({ root }: { root: string }): TopRowFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const palette = rootElement.querySelector<HTMLElement>('[data-chrome=\"palette\"]');\n const menu = rootElement.querySelector('[data-chrome=\"menu\"]');\n const primary = rootElement.querySelector('[data-chrome=\"primary\"]');\n const menuBox = menu && tools.visible(menu) ? tools.box(menu, rootElement) : null;\n let primaryFacts: TopRowFacts[\"primary\"] = null;\n if (primary && tools.visible(primary)) {\n const rect = primary.getBoundingClientRect();\n const labels = [...primary.querySelectorAll(\"span\")].filter(\n (span) => tools.visible(span) && (span.textContent ?? \"\").trim() !== \"\",\n );\n primaryFacts = {\n box: tools.box(primary, rootElement),\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n collapsed: rootElement.getAttribute(\"data-primary\") === \"collapsed\",\n ariaLabel: primary.getAttribute(\"aria-label\"),\n describedBy: primary.getAttribute(\"aria-describedby\"),\n label: labels.length > 0 ? labels.map((span) => (span.textContent ?? \"\").trim()).join(\" \") : null,\n };\n }\n return {\n container: tools.container(rootElement),\n paletteRow: rootElement.getAttribute(\"data-palette\") === \"second-row\" ? \"second-row\" : \"top\",\n paletteWidth: palette ? palette.offsetWidth - palette.clientWidth + palette.scrollWidth : null,\n menuRight: menuBox ? menuBox.left + menuBox.width : null,\n primary: primaryFacts,\n };\n};\n\n/** Counts the `click` events that reach the first match of `selector` (removed with the stand-ins). */\nexport const countClicksProbe = ({ root, selector }: { root: string; selector: string }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const element = document.querySelector(root)?.querySelector(selector);\n if (!element) return false;\n tools.clicks = 0;\n const listener = () => {\n tools.clicks += 1;\n };\n element.addEventListener(\"click\", listener, true);\n tools.cleanups.push(() => element.removeEventListener(\"click\", listener, true));\n return true;\n};\n\nexport const clicksProbe = (_: null): number => (window as ToolWindow).__modelerShellConformance!.clicks;\n\n/** The web app's start screen and what it hides (guide §8). */\nexport interface EmptyStateFacts {\n /** The root's `data-empty-state=\"shown\"`. */\n shown: boolean;\n card: { visible: boolean; box: RelativeBox; tag: string; labelledBy: string | null } | null;\n komet: { tag: string; alt: string | null; width: number; height: number } | null;\n heading: { tag: string; text: string } | null;\n buttons: Array<{ variant: string | null; name: string; height: number; client: Point }>;\n hint: string | null;\n /** Each island of the work chrome in the DOM, with its computed visibility. */\n work: Array<{ name: string; visibility: string; visible: boolean }>;\n /** The canvas slot (`.cd-shell-canvas`) is `inert`. */\n canvasInert: boolean;\n legalVisible: boolean;\n}\n\nexport const emptyStateProbe = ({\n root,\n work,\n}: {\n root: string;\n work: readonly string[];\n}): EmptyStateFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const card = rootElement.querySelector('[data-chrome=\"empty-state\"]');\n const image = card?.querySelector(\"img\") ?? null;\n const heading = card?.querySelector(\"h1, h2, h3, h4, h5, h6\") ?? null;\n const labelledBy = card?.getAttribute(\"aria-labelledby\");\n const parts: Array<[string, Element | null]> = work.map((name) => [\n name,\n rootElement.querySelector(`[data-chrome=\"${name}\"]`),\n ]);\n parts.push([\"hint\", rootElement.querySelector(\".cd-shell-hint\")]);\n const legal = rootElement.querySelector('[data-chrome=\"legal\"]');\n return {\n shown: rootElement.getAttribute(\"data-empty-state\") === \"shown\",\n card: card\n ? {\n visible: tools.visible(card),\n box: tools.box(card, rootElement),\n tag: card.tagName.toLowerCase(),\n labelledBy: labelledBy\n ? labelledBy\n .split(/\\s+/)\n .map((id) => document.getElementById(id)?.textContent?.trim() ?? \"\")\n .join(\" \")\n .trim()\n : null,\n }\n : null,\n komet: image\n ? {\n tag: image.tagName.toLowerCase(),\n alt: image.getAttribute(\"alt\"),\n width: image.getBoundingClientRect().width,\n height: image.getBoundingClientRect().height,\n }\n : null,\n heading: heading\n ? { tag: heading.tagName.toLowerCase(), text: (heading.textContent ?? \"\").replace(/\\s+/g, \" \").trim() }\n : null,\n // The card's actions; a text link inside the hint paragraph is no action (guide §8).\n buttons: [...(card?.querySelectorAll(\"button\") ?? [])]\n .filter((button) => tools.visible(button) && !button.closest(\"p\"))\n .map((button) => {\n const rect = button.getBoundingClientRect();\n return {\n variant: button.getAttribute(\"data-variant\"),\n name: (button.getAttribute(\"aria-label\") ?? button.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n height: rect.height,\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n };\n }),\n hint:\n [...(card?.querySelectorAll(\"p\") ?? [])]\n .map((paragraph) => (paragraph.textContent ?? \"\").trim())\n .filter(Boolean)\n .at(-1) ?? null,\n work: parts\n .filter((part): part is [string, Element] => part[1] !== null)\n .map(([name, element]) => ({\n name,\n visibility: getComputedStyle(element).visibility,\n visible: tools.visible(element),\n })),\n canvasInert: rootElement.querySelector(\".cd-shell-canvas\")?.hasAttribute(\"inert\") ?? false,\n legalVisible: legal ? tools.visible(legal) : false,\n };\n};\n\n/** Where the focus is: the island (`data-chrome`) around it, the canvas, `<body>` or outside the root. */\nexport const focusOwnerProbe = ({ root }: { root: string }): { owner: string; description: string } => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const active = document.activeElement;\n const rootElement = document.querySelector(root);\n if (!active || active === document.body || active === document.documentElement) {\n return { owner: \"body\", description: \"<body>\" };\n }\n const description = tools.describe(active);\n if (!rootElement?.contains(active)) return { owner: \"outside\", description };\n if (active.closest(\".djs-container\")) return { owner: \"canvas\", description };\n const island = active.closest(\"[data-chrome]\")?.getAttribute(\"data-chrome\");\n return { owner: island ?? \"other\", description };\n};\n\n/** Removes the focus, so the next Tab starts at the beginning of the document. */\nexport const blurProbe = (_: null): void => {\n (document.activeElement as HTMLElement | null)?.blur?.();\n};\n\n/** One toast of the stack (guide §8). */\nexport interface ToastFacts {\n text: string;\n role: string | null;\n /** `data-status` of the card. */\n status: string | null;\n box: RelativeBox;\n client: Point;\n /** Its buttons: the action (with text) and Close (an icon with `aria-label`). */\n buttons: Array<{ name: string; text: string; client: Point }>;\n /** Whether the card is what a pointer at its centre reaches (nothing in the top layer above it). */\n topmost: boolean;\n focused: boolean;\n}\n\n/** One of the toasts' live regions (`.cd-shell-live [role]`), rendered whether a toast shows or not. */\nexport interface LiveRegionFacts {\n role: string | null;\n live: string | null;\n text: string;\n}\n\nexport interface ToastsFacts {\n /** `[data-chrome=\"toasts\"]`; `null` where there is none (the IDE host). */\n stack: { visible: boolean; box: RelativeBox; popover: string | null; popoverOpen: boolean } | null;\n /** The visible toasts (`[data-status]` cards of the stack), in DOM order (the newest last). */\n toasts: ToastFacts[];\n /** Toast cards (`.cd-shell-toast`) visible anywhere in the document outside the stack. */\n strays: string[];\n /** The live regions in the root that announce the toasts. */\n live: LiveRegionFacts[];\n}\n\nexport const toastsProbe = ({ root }: { root: string }): ToastsFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const stack = rootElement.querySelector<HTMLElement>('[data-chrome=\"toasts\"]');\n const open = (element: HTMLElement): boolean => {\n try {\n return element.matches(\":popover-open\");\n } catch {\n return false;\n }\n };\n const toasts = stack\n ? [...stack.querySelectorAll<HTMLElement>(\":scope > [data-status]\")].filter((toast) =>\n tools.visible(toast),\n )\n : [];\n const name = (element: Element) =>\n (element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n const centre = (element: Element): Point => {\n const rect = element.getBoundingClientRect();\n return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };\n };\n return {\n stack: stack\n ? {\n visible: tools.visible(stack),\n box: tools.box(stack, rootElement),\n popover: stack.getAttribute(\"popover\"),\n popoverOpen: open(stack),\n }\n : null,\n toasts: toasts.map((toast) => {\n const point = centre(toast);\n const hit = document.elementFromPoint(point.x, point.y);\n return {\n text: (toast.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n role: toast.getAttribute(\"role\"),\n status: toast.getAttribute(\"data-status\"),\n box: tools.box(toast, rootElement),\n client: point,\n buttons: [...toast.querySelectorAll(\"button\")]\n .filter((button) => tools.visible(button))\n .map((button) => ({\n name: name(button),\n text: (button.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n client: centre(button),\n })),\n topmost: hit !== null && toast.contains(hit),\n focused: toast.contains(document.activeElement),\n };\n }),\n strays: [...document.querySelectorAll(\".cd-shell-toast\")]\n .filter((element) => !stack?.contains(element) && tools.visible(element))\n .map((element) => tools.describe(element)),\n live: [...rootElement.querySelectorAll(\".cd-shell-live [role], .cd-shell-live [aria-live]\")].map(\n (region) => ({\n role: region.getAttribute(\"role\"),\n live: region.getAttribute(\"aria-live\"),\n text: (region.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n }),\n ),\n };\n};\n\n/** Focuses the button named `name` in the toast whose text contains `text`. */\nexport const focusToastButtonProbe = ({\n root,\n text,\n name,\n}: {\n root: string;\n text: string;\n name: string;\n}): boolean => {\n const stack = document.querySelector(root)?.querySelector('[data-chrome=\"toasts\"]');\n const toast = [...(stack?.querySelectorAll<HTMLElement>(\":scope > [data-status]\") ?? [])].find(\n (candidate) => (candidate.textContent ?? \"\").includes(text),\n );\n const button = [...(toast?.querySelectorAll(\"button\") ?? [])].find(\n (candidate) => (candidate.getAttribute(\"aria-label\") ?? candidate.textContent ?? \"\").trim() === name,\n );\n if (!button) return false;\n button.focus();\n return document.activeElement === button;\n};\n\n/**\n * Records the toast stack's popover toggles from now on (`beforetoggle`), so the kit sees whether a\n * toast shown over a modal dialog raised the stack in the top layer again.\n */\nexport const watchToastStackProbe = ({ root }: { root: string }): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const stack = document.querySelector(root)?.querySelector('[data-chrome=\"toasts\"]');\n if (!stack) return false;\n const seen: string[] = [];\n const listener = (event: Event) => seen.push((event as ToggleEvent).newState);\n stack.addEventListener(\"beforetoggle\", listener);\n tools.cleanups.push(() => stack.removeEventListener(\"beforetoggle\", listener));\n tools.toastToggles = seen;\n return true;\n};\n\n/** The toggles `watchToastStackProbe` recorded, and whether the stack is shown in the top layer now. */\nexport const toastStackTogglesProbe = ({ root }: { root: string }): { toggles: string[]; open: boolean } => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const stack = document.querySelector(root)?.querySelector('[data-chrome=\"toasts\"]');\n let open = false;\n try {\n open = stack?.matches(\":popover-open\") ?? false;\n } catch {\n open = false;\n }\n return { toggles: [...(tools.toastToggles ?? [])], open };\n};\n\n/** A `<dialog>` opened with `showModal()` in the top layer, as a modeler's dialog (removed with the stand-ins). */\nexport const showModalProbe = (_: null): boolean => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const dialog = document.createElement(\"dialog\");\n dialog.setAttribute(\"data-modeler-shell-conformance\", \"show-modal\");\n dialog.setAttribute(\"aria-label\", \"Conformance stand-in\");\n dialog.style.cssText = \"width:60vw;height:60vh;max-width:none;max-height:none;\";\n document.body.append(dialog);\n tools.injected.push(dialog);\n dialog.showModal();\n try {\n return dialog.matches(\":modal\");\n } catch {\n return dialog.open;\n }\n};\n\n/** The pill, the web app's problems list it opens, its rows and where the focus is (guide §5.10). */\nexport interface PopoverFacts {\n pill: { attributes: Record<string, string>; box: RelativeBox; client: Point; visible: boolean } | null;\n popover: {\n attributes: Record<string, string>;\n box: RelativeBox;\n visible: boolean;\n /** Text of its `aria-labelledby` targets. */\n title: string | null;\n } | null;\n rows: Array<{ button: boolean; height: number; icon: boolean; text: string; client: Point }>;\n focus: \"pill\" | \"popover\" | \"canvas\" | \"body\" | \"other\";\n focused: string;\n /**\n * The row holding the focus: its index among `rows`, and whether it lies inside the visible part\n * of the scrolling list; `null` while no row holds it.\n */\n focusedRow: { index: number; inView: boolean } | null;\n}\n\nexport const popoverProbe = ({ root }: { root: string }): PopoverFacts | null => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(root);\n if (!rootElement) return null;\n const pill = rootElement.querySelector('[data-chrome=\"problems\"]');\n const controls = pill?.getAttribute(\"aria-controls\");\n const popover =\n (controls ? document.getElementById(controls) : null) ??\n rootElement.querySelector('[data-chrome=\"problems-popover\"]');\n const attributes = (element: Element) => {\n const all: Record<string, string> = {};\n for (const name of element.getAttributeNames()) all[name] = element.getAttribute(name) ?? \"\";\n return all;\n };\n const labelledBy = popover?.getAttribute(\"aria-labelledby\");\n const active = document.activeElement;\n const rows = popover\n ? [...popover.querySelectorAll(\".cd-shell-problem\")].filter((row) => tools.visible(row))\n : [];\n const pillRect = pill?.getBoundingClientRect();\n return {\n pill:\n pill && pillRect\n ? {\n attributes: attributes(pill),\n box: tools.box(pill, rootElement),\n client: { x: pillRect.left + pillRect.width / 2, y: pillRect.top + pillRect.height / 2 },\n visible: tools.visible(pill),\n }\n : null,\n popover: popover\n ? {\n attributes: attributes(popover),\n box: tools.box(popover, rootElement),\n visible: tools.visible(popover),\n title: labelledBy\n ? labelledBy\n .split(/\\s+/)\n .map((id) => document.getElementById(id)?.textContent?.trim() ?? \"\")\n .join(\" \")\n .trim()\n : null,\n }\n : null,\n rows: rows.map((row) => {\n const target = row.matches(\"button\") ? row : row.querySelector(\"button\");\n const rect = (target ?? row).getBoundingClientRect();\n return {\n button: target !== null,\n height: row.getBoundingClientRect().height,\n icon: row.querySelector(\"svg\") !== null,\n text: (row.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n client: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },\n };\n }),\n focus:\n !active || active === document.body\n ? \"body\"\n : pill && active === pill\n ? \"pill\"\n : popover?.contains(active)\n ? \"popover\"\n : active.closest(\".djs-container\")\n ? \"canvas\"\n : \"other\",\n focused: !active || active === document.body ? \"<body>\" : tools.describe(active),\n focusedRow: (() => {\n const index = active ? rows.findIndex((row) => row === active || row.contains(active)) : -1;\n const row = rows[index];\n if (!row) return null;\n let scroller: Element | null = row.parentElement;\n while (scroller && scroller !== popover && scroller.scrollHeight <= scroller.clientHeight) {\n scroller = scroller.parentElement;\n }\n const view = (scroller ?? popover ?? row).getBoundingClientRect();\n const box = row.getBoundingClientRect();\n return { index, inView: box.top >= view.top - 1 && box.bottom <= view.bottom + 1 };\n })(),\n };\n};\n\n/** A synthetic drag the kit dispatches: files built in the page, or plain strings (a text drag). */\nexport interface DragSpec {\n root: string;\n files: readonly DropFixture[];\n strings?: readonly string[];\n steps: ReadonlyArray<\"dragenter\" | \"dragover\" | \"dragleave\" | \"drop\">;\n}\n\n/** The drop zone and the root's state after a drag step (guide §9). */\nexport interface DropZoneFacts {\n /** The root's `data-drop`. */\n state: string | null;\n /** Per dispatched step: `defaultPrevented` and the `dropEffect` the page set. */\n events: Array<{ type: string; defaultPrevented: boolean; dropEffect: string }>;\n zone: {\n visible: boolean;\n box: RelativeBox;\n ariaHidden: string | null;\n background: string;\n borderStyle: string;\n borderWidth: string;\n borderColor: string;\n radius: string;\n cursor: string;\n } | null;\n chip: { text: string; background: string } | null;\n /** The roles of guide §9 resolved to computed colours inside the root. */\n roles: { hover: string; interaktion: string; dangerFlaeche: string; danger: string; flaecheHoch: string };\n}\n\nexport const dragProbe = async (spec: DragSpec): Promise<DropZoneFacts | null> => {\n const tools = (window as ToolWindow).__modelerShellConformance!;\n const rootElement = document.querySelector<HTMLElement>(spec.root);\n if (!rootElement) return null;\n const transfer = new DataTransfer();\n for (const file of spec.files) {\n transfer.items.add(new File([file.text], file.name, { type: file.type }));\n }\n for (const text of spec.strings ?? []) transfer.items.add(text, \"text/plain\");\n const rect = rootElement.getBoundingClientRect();\n const clientX = rect.left + rect.width / 2;\n const clientY = rect.top + rect.height / 2;\n const target = document.elementFromPoint(clientX, clientY) ?? rootElement;\n const events: DropZoneFacts[\"events\"] = [];\n for (const type of spec.steps) {\n const event = new DragEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true,\n dataTransfer: transfer,\n clientX,\n clientY,\n });\n // Chromium ignores dropEffect on a constructed DataTransfer; the kit records what the page sets.\n const effects: Record<string, string> = { dropEffect: \"none\", effectAllowed: \"all\" };\n const recorded = new Proxy(transfer, {\n get(target, key) {\n if (key === \"dropEffect\" || key === \"effectAllowed\") return effects[key];\n const value = Reflect.get(target, key, target) as unknown;\n return typeof value === \"function\" ? (value as (...args: unknown[]) => unknown).bind(target) : value;\n },\n set(target, key, value) {\n if (key === \"dropEffect\" || key === \"effectAllowed\") {\n effects[key] = String(value);\n return true;\n }\n return Reflect.set(target, key, value, target);\n },\n });\n Object.defineProperty(event, \"dataTransfer\", { configurable: true, value: recorded });\n target.dispatchEvent(event);\n events.push({ type, defaultPrevented: event.defaultPrevented, dropEffect: effects.dropEffect ?? \"none\" });\n }\n await tools.settle();\n const resolve = (role: string): string => {\n const probe = document.createElement(\"span\");\n probe.setAttribute(\"data-modeler-shell-conformance\", \"role-probe\");\n probe.style.cssText = `position:absolute;visibility:hidden;background-color:var(${role});`;\n rootElement.append(probe);\n const color = getComputedStyle(probe).backgroundColor;\n probe.remove();\n return color;\n };\n const resolveColor = (role: string): string => {\n const probe = document.createElement(\"span\");\n probe.setAttribute(\"data-modeler-shell-conformance\", \"role-probe\");\n probe.style.cssText = `position:absolute;visibility:hidden;color:var(${role});`;\n rootElement.append(probe);\n const color = getComputedStyle(probe).color;\n probe.remove();\n return color;\n };\n const zone = rootElement.querySelector('[data-chrome=\"drop-zone\"]');\n const chip = zone?.querySelector(\".cd-shell-drop-zone-chip\") ?? null;\n const zoneStyle = zone ? getComputedStyle(zone) : null;\n return {\n state: rootElement.getAttribute(\"data-drop\"),\n events,\n zone:\n zone && zoneStyle\n ? {\n visible: tools.visible(zone),\n box: tools.box(zone, rootElement),\n ariaHidden: zone.getAttribute(\"aria-hidden\"),\n background: zoneStyle.backgroundColor,\n borderStyle: zoneStyle.borderTopStyle,\n borderWidth: zoneStyle.borderTopWidth,\n borderColor: zoneStyle.borderTopColor,\n radius: zoneStyle.borderTopLeftRadius,\n cursor: zoneStyle.cursor,\n }\n : null,\n chip: chip\n ? {\n text: (chip.textContent ?? \"\").replace(/\\s+/g, \" \").trim(),\n background: getComputedStyle(chip).backgroundColor,\n }\n : null,\n roles: {\n hover: resolve(\"--cd-ui-hover\"),\n interaktion: resolveColor(\"--cd-ui-interaktion\"),\n dangerFlaeche: resolve(\"--cd-ui-danger-flaeche\"),\n danger: resolveColor(\"--cd-ui-danger\"),\n flaecheHoch: resolve(\"--cd-ui-flaeche-hoch\"),\n },\n };\n};\n","import {\n INVALID_STATUS_DELAY_MS,\n TOAST_DURATION_MS,\n TOOLTIP_DELAY_MS,\n type ToastStatus,\n} from \"../core/index.js\";\nimport {\n DEFAULT_SIZES,\n HOVER_MARGIN_MS,\n LIGHT,\n PARK,\n assertHooksConsistent,\n closeByEscape,\n finish,\n menuEntries,\n openHarness,\n openMenuByClick,\n pollUntil,\n unfed,\n} from \"./case-tools.js\";\nimport { ariaProbe, menuProbe, type AriaFacts } from \"./facts.js\";\nimport {\n DEFAULT_ROOT,\n WORK_CHROME,\n measureChrome,\n webRowProblems,\n type ChromeMeasurement,\n} from \"./geometry.js\";\nimport type {\n DropFixture,\n ShellCaseOutcome,\n ShellConformanceCase,\n ShellConformanceHarness,\n ShellSkip,\n ToastFixture,\n} from \"./harness.js\";\nimport type { PageLike } from \"./page.js\";\nimport {\n afterPressProbe,\n clearKeysProbe,\n findOverlay,\n findTarget,\n focusTarget,\n inPage,\n injectProbe,\n removeInjectedProbe,\n settle,\n} from \"./page-tools.js\";\nimport {\n afterStartProblems,\n closedPopoverProblems,\n dropStateProblems,\n emptyStateKeyProblems,\n emptyStateProblems,\n emptyStateTabProblems,\n labelledWidth,\n legalContentProblems,\n legalReachProblems,\n openPopoverProblems,\n popoverKeyboardProblems,\n primaryActivationProblems,\n primaryTooltipProblems,\n repeatedToastProblems,\n toastAnatomyProblems,\n toastLiveRegion,\n toastStackProblems,\n toastTimingProblems,\n topRowProblems,\n zoomRowBottomProblems,\n type ExpectedDrop,\n type PopoverKeyStep,\n type ToastTiming,\n} from \"./web-checks.js\";\nimport {\n blurProbe,\n clicksProbe,\n countClicksProbe,\n dragProbe,\n emptyStateProbe,\n focusOwnerProbe,\n focusToastButtonProbe,\n legalLineProbe,\n popoverProbe,\n showModalProbe,\n toastStackTogglesProbe,\n toastsProbe,\n topRowProbe,\n watchToastStackProbe,\n type DragSpec,\n type DropZoneFacts,\n type EmptyStateFacts,\n type PopoverFacts,\n type ToastsFacts,\n type TopRowFacts,\n} from \"./web-facts.js\";\n\n/** The width steps of the web app's top and bottom rows, from wide to narrow (guide §5.15). */\nconst WIDEST_STEP = 1280;\nconst NARROWEST_STEP = 400;\n/** The narrowest container the legal line must still hold every link in (320 CSS px, WCAG 1.4.10). */\nconst PHONE_WIDTH = 320;\nconst STEP_PX = 24;\n\n/** Room after a toast's lifetime for its 250ms exit and a frame on either side. */\nconst TOAST_MARGIN_MS = 900;\n\n/** A toast's resumed time after hover or focus is at least this (API.md, Toasts). */\nconst TOAST_RESUME_MS = 1500;\n\n/** How long a toast's text may take to reach its live region. */\nconst TOAST_ANNOUNCE_WAIT_MS = 1000;\n\n/** Room for a modeler that reads a dropped file asynchronously before it opens it. */\nconst DROP_WAIT_MS = 2000;\n\n/** Tab presses on the start screen: the card's two buttons, the legal links and the way out. */\nconst START_SCREEN_TABS = 10;\n\nconst TOAST_STATUSES: readonly ToastStatus[] = [\"success\", \"info\", \"warning\", \"danger\"];\n\n/** The document's language, which decides whether names compare with the default messages. */\nconst documentLangProbe = (_: null): string => document.documentElement.lang;\n\nfunction sizeOf<P extends PageLike>(harness: ShellConformanceHarness<P>) {\n return (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n}\n\nfunction skipFor(hook: ShellSkip[\"hook\"], what: string): ShellCaseOutcome {\n return {\n skipped: [\n {\n hook,\n reason: `${hook === \"drop\" ? \"harness.drop\" : `show.${hook}`} is undefined: ${what} not verified`,\n },\n ],\n };\n}\n\nasync function aria(page: PageLike, root: string): Promise<AriaFacts | null> {\n return inPage(page, ariaProbe, { root });\n}\n\n// ---- webChrome ----\n\n/** Steps the page from wide to narrow; at every width the top row's decision and the bottom row. */\nasync function rowSamples(\n page: PageLike,\n root: string,\n height: number,\n): Promise<{ samples: TopRowFacts[]; measurements: ChromeMeasurement[] }> {\n const samples: TopRowFacts[] = [];\n const measurements: ChromeMeasurement[] = [];\n for (let width = WIDEST_STEP; width >= NARROWEST_STEP; width -= STEP_PX) {\n await page.setViewportSize({ width, height });\n await settle(page);\n const sample = await inPage(page, topRowProbe, { root });\n if (sample) samples.push(sample);\n measurements.push(await measureChrome(page, root));\n }\n return { samples, measurements };\n}\n\n/** Hovers the primary action at `width`; the visible chrome tooltip's text, `null` without one. */\nasync function primaryTooltipAt(\n page: PageLike,\n root: string,\n width: number,\n height: number,\n): Promise<string | null> {\n await page.setViewportSize({ width, height });\n await settle(page);\n const primary = await findTarget(page, root, \"primary\");\n if (!primary) return null;\n await page.mouse.move(PARK.x, PARK.y);\n await page.mouse.move(primary.client.x, primary.client.y);\n await page.waitForTimeout(TOOLTIP_DELAY_MS + HOVER_MARGIN_MS);\n await settle(page);\n const tooltip = await findOverlay(page, root, \"tooltip\");\n await page.mouse.move(PARK.x, PARK.y);\n return tooltip?.text ?? null;\n}\n\n/** A pointer click and Enter on the primary action, counted by a kit listener (guide §5.7). */\nasync function primaryActivation(page: PageLike, root: string): Promise<string[]> {\n const primary = await findTarget(page, root, \"primary\");\n if (!primary) return [];\n await inPage(page, countClicksProbe, { root, selector: '[data-chrome=\"primary\"]' });\n await page.mouse.click(primary.client.x, primary.client.y);\n await settle(page);\n const pointer = await inPage(page, clicksProbe, null);\n if (!(await focusTarget(page, root, \"primary\"))) {\n await inPage(page, removeInjectedProbe, null);\n return [\"primary: the primary action cannot take the focus\"];\n }\n await page.keyboard.press(\"Enter\");\n await settle(page);\n const enter = (await inPage(page, clicksProbe, null)) - pointer;\n await inPage(page, removeInjectedProbe, null);\n await page.mouse.move(PARK.x, PARK.y);\n return primaryActivationProblems({ pointer, enter });\n}\n\n/** Each File entry: a click closes the menu before its handler runs (guide §5.4). */\nasync function fileEntryProblems(page: PageLike, root: string): Promise<string[]> {\n const entries = (await menuEntries(page, root)).filter((entry) => entry.group === \"file\");\n const problems: string[] = [];\n for (const entry of entries) {\n if (!entry.menuId || !(await openMenuByClick(page, root))) continue;\n const item = await inPage(page, fileItemProbe, { root, menuId: entry.menuId });\n if (!item) {\n await closeByEscape(page);\n continue;\n }\n await page.mouse.click(item.x, item.y);\n await settle(page);\n const menu = await inPage(page, menuProbe, { root });\n if (menu?.menu || menu?.expanded === \"true\") {\n problems.push(\n `menu: File entry \"${entry.name}\" leaves the menu open; an action closes it first (guide §5.4)`,\n );\n await closeByEscape(page);\n }\n // A handler that opens an in-page dialog gets it closed again before the next entry.\n if (entry.name.endsWith(\"…\")) await closeByEscape(page);\n }\n return problems;\n}\n\n/** Viewport centre of the visible menu item `menuId`. */\nconst fileItemProbe = ({\n root,\n menuId,\n}: {\n root: string;\n menuId: string;\n}): { x: number; y: number } | null => {\n const item = document.querySelector(root)?.querySelector(`[role=\"menu\"] [data-menu-id=\"${menuId}\"]`);\n if (!item) return null;\n const rect = item.getBoundingClientRect();\n return rect.width > 0 ? { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 } : null;\n};\n\n/** Guide §13.5: File entries stay usable on a read-only canvas. */\nasync function lockedFileProblems<P extends PageLike>(\n page: P,\n harness: ShellConformanceHarness<P>,\n root: string,\n): Promise<string[]> {\n const invalid = harness.show?.invalid;\n if (!invalid) return [];\n await invalid(page);\n await page.waitForTimeout(INVALID_STATUS_DELAY_MS + HOVER_MARGIN_MS);\n return (await menuEntries(page, root))\n .filter((entry) => entry.group === \"file\" && entry.disabled)\n .map(\n (entry) => `menu: File entry \"${entry.name}\" is aria-disabled on the read-only canvas (guide §13.5)`,\n );\n}\n\nconst webChromeCase: ShellConformanceCase = {\n name: \"webChrome\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const size = sizeOf(harness);\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const problems: string[] = [];\n if (harness.host !== \"web\") {\n const measurement = await measureChrome(page, root);\n for (const island of [\"primary\", \"legal\", \"empty-state\", \"drop-zone\"] as const) {\n if (measurement.islands[island]) {\n problems.push(\n `${island}: visible in the ${harness.host} host; it belongs to the web app (guide §5.2)`,\n );\n }\n }\n return finish(\"webChrome\", harness.host, problems, []);\n }\n\n const facts = await aria(page, root);\n if (facts) problems.push(...legalContentProblems(facts.legalLinks));\n const name = (facts?.primary?.attributes[\"aria-label\"] ?? \"\").trim();\n problems.push(...(await primaryActivation(page, root)));\n\n const { samples, measurements } = await rowSamples(page, root, size.height);\n for (const measurement of measurements) {\n problems.push(\n ...webRowProblems(measurement, \"web\").map(\n (problem) => `[${Math.round(measurement.container.width)}px wide] ${problem}`,\n ),\n ...zoomRowBottomProblems(\n measurement.islands.zoom,\n measurement.open.zoomRaised,\n measurement.container,\n measurement.islands.legal?.height,\n ),\n );\n }\n if (samples.some((sample) => sample.primary)) {\n const withLabel = labelledWidth(samples);\n if (withLabel === undefined) {\n problems.push(\n `primary: never shows its label between ${WIDEST_STEP}px and ${NARROWEST_STEP}px; it collapses only when the top row gets tight (guide §5.15)`,\n );\n } else {\n problems.push(...topRowProblems(samples, withLabel, name));\n }\n const collapsed = samples.find((sample) => sample.primary?.collapsed);\n const labelled = samples.find((sample) => sample.primary && !sample.primary.collapsed);\n for (const sample of [labelled, collapsed]) {\n if (!sample?.primary) continue;\n const width = sample.container.width;\n const tooltip = await primaryTooltipAt(page, root, width, size.height);\n problems.push(...primaryTooltipProblems(sample.primary.collapsed, tooltip, name, width));\n }\n }\n\n // The narrowest phone: the legal line wraps rather than cutting off Datenschutz.\n await page.setViewportSize({ width: PHONE_WIDTH, height: size.height });\n await settle(page);\n const legalLine = await inPage(page, legalLineProbe, { root });\n if (legalLine) problems.push(...legalReachProblems(legalLine));\n\n await page.setViewportSize({ width: size.width, height: size.height });\n await settle(page);\n problems.push(...(await fileEntryProblems(page, root)));\n problems.push(...(await lockedFileProblems(page, harness, root)));\n return finish(\"webChrome\", harness.host, [...new Set(problems)], []);\n },\n};\n\n// ---- emptyState ----\n\nfunction startScreen(page: PageLike, root: string): Promise<EmptyStateFacts | null> {\n return inPage(page, emptyStateProbe, { root, work: WORK_CHROME });\n}\n\n/**\n * Closing a toast that holds the focus on the start screen hands the focus to the card; the canvas\n * and the menu trigger behind it cannot take it, and <body> would lose the user's place.\n */\nasync function toastFocusOnStartScreen<P extends PageLike>(\n page: P,\n root: string,\n show: (page: P, toast: ToastFixture) => Promise<void>,\n): Promise<string[]> {\n const text = \"Conformance: a toast on the start screen\";\n await show(page, { status: \"danger\", text });\n await settle(page);\n const closeName = (await toasts(page, root))?.toasts\n .find((toast) => toast.text.includes(text))\n ?.buttons.at(-1)?.name;\n if (!closeName || !(await inPage(page, focusToastButtonProbe, { root, text, name: closeName }))) return [];\n await page.keyboard.press(\"Enter\");\n await settle(page);\n const focus = await inPage(page, focusOwnerProbe, { root });\n return focus.owner === \"empty-state\"\n ? []\n : [\n `empty-state: closing a focused toast on the start screen leaves the focus on ${focus.description}; it goes to the card's \"New diagram\" (WCAG 2.4.3)`,\n ];\n}\n\nconst emptyStateCase: ShellConformanceCase = {\n name: \"emptyState\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"emptyState\", harness, [\"emptyState\"]);\n const root = harness.root ?? DEFAULT_ROOT;\n const size = sizeOf(harness);\n const show = harness.show?.emptyState;\n if (harness.host !== \"web\") {\n await openHarness(page, harness, { size, requested: LIGHT });\n if (show) await show(page);\n await settle(page);\n const facts = await startScreen(page, root);\n const problems: string[] = [];\n if (facts?.card?.visible || facts?.shown) {\n problems.push(\n `empty-state: a start screen in the ${harness.host} host; it shows the empty-file hint instead (guide §13.5)`,\n );\n }\n return finish(\"emptyState\", harness.host, problems, []);\n }\n if (!show) {\n return unfed(harness, \"emptyState\") ? skipFor(\"emptyState\", \"the start screen\") : undefined;\n }\n\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const lang = await inPage(page, documentLangProbe, null);\n await show(page);\n await settle(page);\n const container = (await measureChrome(page, root)).container;\n const facts = await startScreen(page, root);\n if (!facts) return finish(\"emptyState\", harness.host, [`no element matches \"${root}\"`], []);\n const problems = emptyStateProblems(facts, container, lang);\n\n await inPage(page, blurProbe, null);\n const stops: Array<{ owner: string; description: string }> = [];\n for (let press = 0; press < START_SCREEN_TABS; press++) {\n await page.keyboard.press(\"Tab\");\n stops.push(await inPage(page, focusOwnerProbe, { root }));\n }\n problems.push(...emptyStateTabProblems(stops));\n\n await inPage(page, blurProbe, null);\n for (const key of [\"Control+Equal\", \"Control+Minus\", \"Shift+Digit1\"]) {\n await inPage(page, clearKeysProbe, null);\n const before = (await inPage(page, afterPressProbe, { root })).zoom;\n await page.keyboard.press(key);\n const after = await inPage(page, afterPressProbe, { root });\n problems.push(...emptyStateKeyProblems(key, before, after.zoom, after.keys));\n }\n\n const showToast = harness.show?.toast;\n if (showToast) problems.push(...(await toastFocusOnStartScreen(page, root, showToast)));\n\n const start = facts.buttons[0];\n if (start) {\n await page.mouse.click(start.client.x, start.client.y);\n await settle(page);\n const after = await pollUntil(\n page,\n () => startScreen(page, root),\n (state) => state === null || !state.shown,\n 1000,\n );\n if (after) problems.push(...afterStartProblems(after, await inPage(page, focusOwnerProbe, { root })));\n }\n return finish(\"emptyState\", harness.host, problems, []);\n },\n};\n\n// ---- toasts ----\n\nfunction toasts(page: PageLike, root: string): Promise<ToastsFacts | null> {\n return inPage(page, toastsProbe, { root });\n}\n\n/**\n * Clicks the Close button of every visible toast, oldest first, and parks the pointer away from the\n * stack: a toast appearing under it would be hovered, which pauses and protects it.\n */\nasync function dismissAll(page: PageLike, root: string): Promise<void> {\n for (let attempt = 0; attempt < 6; attempt++) {\n const close = (await toasts(page, root))?.toasts[0]?.buttons.at(-1);\n if (!close) break;\n await page.mouse.click(close.client.x, close.client.y);\n await settle(page);\n }\n await page.mouse.move(PARK.x, PARK.y);\n}\n\n/** Waits until `ms` after `since` (Node's clock), then reads which of `texts` are shown. */\nasync function presentAt(\n page: PageLike,\n root: string,\n since: number,\n ms: number,\n texts: readonly string[],\n): Promise<Set<string>> {\n const wait = since + ms - Date.now();\n if (wait > 0) await page.waitForTimeout(wait);\n await settle(page);\n const shown = (await toasts(page, root))?.toasts ?? [];\n return new Set(texts.filter((text) => shown.some((toast) => toast.text.includes(text))));\n}\n\nasync function toastAnatomy<P extends PageLike>(\n page: P,\n root: string,\n show: (page: P, toast: ToastFixture) => Promise<void>,\n lang: string,\n): Promise<string[]> {\n const problems: string[] = [];\n // Read before any toast of the case: a region that only comes with its first text is too late.\n const before = (await toasts(page, root))?.live ?? [];\n for (const status of TOAST_STATUSES) {\n const text = `Conformance: a ${status} toast`;\n await show(page, { status, text });\n await settle(page);\n const toast = (await toasts(page, root))?.toasts.find((candidate) => candidate.text.includes(text));\n if (!toast) {\n problems.push(`toasts: show.toast with a ${status} toast shows nothing`);\n continue;\n }\n const persistent = toastLiveRegion(before, status) !== undefined;\n const reached = (facts: ToastsFacts | null): boolean =>\n toastLiveRegion(facts?.live ?? [], status)?.text.includes(text) ?? false;\n const announced =\n persistent && reached(await pollUntil(page, () => toasts(page, root), reached, TOAST_ANNOUNCE_WAIT_MS));\n problems.push(...toastAnatomyProblems(toast, status, lang, { persistent, announced }));\n const close = toast.buttons.at(-1);\n if (close) {\n await page.mouse.click(close.client.x, close.client.y);\n await page.mouse.move(PARK.x, PARK.y);\n await settle(page);\n const still = (await toasts(page, root))?.toasts.some((candidate) => candidate.text.includes(text));\n if (still) problems.push(`toasts: Close does not close the ${status} toast`);\n }\n }\n await dismissAll(page, root);\n return problems;\n}\n\nasync function toastStack<P extends PageLike>(\n page: P,\n root: string,\n show: (page: P, toast: ToastFixture) => Promise<void>,\n): Promise<string[]> {\n const texts = [\"A\", \"B\", \"C\", \"D\"].map((letter) => `Conformance: stacked ${letter}`);\n const [first, second, third, fourth] = texts as [string, string, string, string];\n await show(page, { status: \"info\", text: first, actionLabel: \"Undo\" });\n for (const text of [second, third, fourth]) await show(page, { status: \"success\", text });\n await settle(page);\n const problems = toastStackProblems((await toasts(page, root))?.toasts ?? [], texts, [\n first,\n third,\n fourth,\n ]);\n await show(page, { status: \"success\", text: third });\n await settle(page);\n problems.push(...repeatedToastProblems((await toasts(page, root))?.toasts ?? [], third));\n await dismissAll(page, root);\n return problems;\n}\n\nasync function toastTiming<P extends PageLike>(\n page: P,\n root: string,\n show: (page: P, toast: ToastFixture) => Promise<void>,\n): Promise<string[]> {\n const lifetime = TOAST_DURATION_MS.success;\n const plain = \"Conformance: a plain toast\";\n const hovered = \"Conformance: a hovered toast\";\n const focused = \"Conformance: a focused toast\";\n const texts = [plain, hovered, focused];\n for (const text of texts) await show(page, { status: \"success\", text });\n const shownAt = Date.now();\n await settle(page);\n const target = (await toasts(page, root))?.toasts.find((toast) => toast.text.includes(hovered));\n if (target) await page.mouse.move(target.client.x, target.client.y);\n const focusTarget = (await toasts(page, root))?.toasts.find((toast) => toast.text.includes(focused));\n const closeName = focusTarget?.buttons.at(-1)?.name ?? \"\";\n await inPage(page, focusToastButtonProbe, { root, text: focused, name: closeName });\n\n const timings: ToastTiming[] = [];\n const record = (\n shown: Set<string>,\n after: number,\n expect: Array<[string, ToastTiming[\"expectation\"], ToastTiming[\"condition\"]]>,\n ) => {\n for (const [text, expectation, condition] of expect) {\n timings.push({ text, expectation, after, present: shown.has(text), condition });\n }\n };\n const early = lifetime - 800;\n record(await presentAt(page, root, shownAt, early, texts), early, [[plain, \"present\", \"plain\"]]);\n const late = lifetime + TOAST_MARGIN_MS;\n record(await presentAt(page, root, shownAt, late, texts), late, [\n [plain, \"gone\", \"plain\"],\n [hovered, \"present\", \"hovered\"],\n [focused, \"present\", \"focused\"],\n ]);\n\n await page.mouse.move(PARK.x, PARK.y);\n await inPage(page, blurProbe, null);\n const leftAt = Date.now();\n const resumed = TOAST_RESUME_MS - 500;\n record(await presentAt(page, root, leftAt, resumed, texts), resumed, [\n [hovered, \"present\", \"resumed\"],\n [focused, \"present\", \"resumed\"],\n ]);\n const gone = lifetime + TOAST_MARGIN_MS;\n record(await presentAt(page, root, leftAt, gone, texts), gone, [\n [hovered, \"gone\", \"resumed\"],\n [focused, \"gone\", \"resumed\"],\n ]);\n\n const action = \"Conformance: a toast with an action\";\n await show(page, { status: \"info\", text: action, actionLabel: \"Undo\" });\n const actionAt = Date.now();\n const actionWait = TOAST_DURATION_MS.info + TOAST_MARGIN_MS;\n record(await presentAt(page, root, actionAt, actionWait, [action]), actionWait, [\n [action, \"present\", \"action\"],\n ]);\n await dismissAll(page, root);\n return toastTimingProblems(timings);\n}\n\n/**\n * Web host: a toast shown while a `showModal()` dialog is open stays above it (API.md, Toasts): the\n * stack, already shown for an earlier toast, is shown again in the top layer, above the dialog.\n * A modal dialog makes everything outside it inert, so the kit reads the popover's toggles instead\n * of hit-testing the toast.\n */\nasync function toastAboveModal<P extends PageLike>(\n page: P,\n root: string,\n show: (page: P, toast: ToastFixture) => Promise<void>,\n): Promise<string[]> {\n const before = \"Conformance: a toast before the dialog\";\n const text = \"Conformance: a toast above the dialog\";\n await show(page, { status: \"info\", text: before, actionLabel: \"Undo\" });\n await settle(page);\n const problems: string[] = [];\n if ((await toasts(page, root))?.stack?.popover !== \"manual\") {\n problems.push(\n 'toasts: the web app\\'s stack is no popover=\"manual\"; it stays above a showModal() dialog only in the top layer (API.md, Toasts)',\n );\n } else if (await inPage(page, watchToastStackProbe, { root })) {\n if (await inPage(page, showModalProbe, null)) {\n await show(page, { status: \"success\", text });\n await settle(page);\n const shown = (await toasts(page, root))?.toasts.some((toast) => toast.text.includes(text)) ?? false;\n const { toggles, open } = await inPage(page, toastStackTogglesProbe, { root });\n if (!shown) problems.push(\"toasts: show.toast with a showModal() dialog open shows nothing\");\n else if (!open || toggles.at(-1) !== \"open\") {\n problems.push(\n \"toasts: a toast shown with a showModal() dialog open does not raise the stack above it; the stack is shown again with every toast (API.md, Toasts)\",\n );\n }\n }\n }\n await inPage(page, removeInjectedProbe, null);\n await settle(page);\n await dismissAll(page, root);\n return problems;\n}\n\nconst toastsCase: ShellConformanceCase = {\n name: \"toasts\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"toasts\", harness, [\"toast\"]);\n const root = harness.root ?? DEFAULT_ROOT;\n const size = sizeOf(harness);\n const show = harness.show?.toast;\n if (harness.host === \"ide\") {\n await openHarness(page, harness, { size, requested: LIGHT });\n if (show) await show(page, { status: \"success\", text: \"Conformance: a toast in the IDE host\" });\n await settle(page);\n const facts = await toasts(page, root);\n const problems: string[] = [];\n if (facts?.stack) {\n problems.push(\n 'toasts: the IDE host renders a toast stack [data-chrome=\"toasts\"]; it shows no toasts (guide §13.5)',\n );\n }\n if ((facts?.toasts.length ?? 0) > 0 || (facts?.strays.length ?? 0) > 0) {\n problems.push(\n \"toasts: show.toast shows a toast in the IDE host; the extension shows the host's notification (guide §13.5)\",\n );\n }\n return finish(\"toasts\", harness.host, problems, []);\n }\n if (!show) return unfed(harness, \"toast\") ? skipFor(\"toast\", \"the toasts\") : undefined;\n\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const lang = await inPage(page, documentLangProbe, null);\n await dismissAll(page, root);\n const problems = [\n ...(await toastAnatomy(page, root, show, lang)),\n ...(await toastStack(page, root, show)),\n ...(await toastTiming(page, root, show)),\n ];\n if (harness.host === \"web\") problems.push(...(await toastAboveModal(page, root, show)));\n return finish(\"toasts\", harness.host, problems, []);\n },\n};\n\n// ---- problemsList ----\n\nfunction popover(page: PageLike, root: string): Promise<PopoverFacts | null> {\n return inPage(page, popoverProbe, { root });\n}\n\nasync function clickPill(page: PageLike, root: string): Promise<PopoverFacts | null> {\n const pill = (await popover(page, root))?.pill;\n if (!pill?.visible) return null;\n await page.mouse.click(pill.client.x, pill.client.y);\n await settle(page);\n return popover(page, root);\n}\n\n/**\n * Opens the list from the pill with Enter, then walks it with ArrowDown to the last row and jumps\n * back with Home and to the end with End; every step must land on its row, inside the list.\n */\nasync function keyboardRows(page: PageLike, root: string): Promise<string[]> {\n if (!(await focusTarget(page, root, \"pill\"))) return [\"problems: the pill cannot take the focus\"];\n await page.keyboard.press(\"Enter\");\n await settle(page);\n const opened = await popover(page, root);\n const count = opened?.rows.length ?? 0;\n if (!opened?.popover?.visible || count === 0) {\n await closeByEscape(page);\n return opened?.popover?.visible ? [] : [\"problems-popover: Enter on the pill does not open the list\"];\n }\n const steps: PopoverKeyStep[] = [{ key: \"Enter on the pill\", expected: 0, focused: opened.focusedRow }];\n for (let index = 1; index < count; index++) {\n await page.keyboard.press(\"ArrowDown\");\n steps.push({\n key: \"ArrowDown\",\n expected: index,\n focused: (await popover(page, root))?.focusedRow ?? null,\n });\n }\n if (count > 1) {\n await page.keyboard.press(\"Home\");\n steps.push({ key: \"Home\", expected: 0, focused: (await popover(page, root))?.focusedRow ?? null });\n await page.keyboard.press(\"End\");\n steps.push({ key: \"End\", expected: count - 1, focused: (await popover(page, root))?.focusedRow ?? null });\n }\n await closeByEscape(page);\n return popoverKeyboardProblems(steps, count);\n}\n\nconst problemsListCase: ShellConformanceCase = {\n name: \"problemsList\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"problemsList\", harness, [\"problems\"]);\n const root = harness.root ?? DEFAULT_ROOT;\n const size = sizeOf(harness);\n const show = harness.show?.problems;\n if (!show) return unfed(harness, \"problems\") ? skipFor(\"problems\", \"the problems list\") : undefined;\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n await show(page);\n await settle(page);\n const before = await popover(page, root);\n const problems: string[] = [];\n if (!before?.pill?.visible) {\n return finish(\n \"problemsList\",\n harness.host,\n [\"problems: the pill is not visible after show.problems\"],\n [],\n );\n }\n const opensList = harness.host === \"web\" || before.pill.attributes[\"aria-haspopup\"] === \"dialog\";\n if (!opensList) {\n const after = await clickPill(page, root);\n if (after?.popover?.visible) {\n problems.push(\n `problems-popover: the ${harness.host} host shows a problems list; its pill opens the host's own view (guide §5.10)`,\n );\n }\n return finish(\"problemsList\", harness.host, problems, []);\n }\n const lang = await inPage(page, documentLangProbe, null);\n const container = (await measureChrome(page, root)).container;\n const opened = await clickPill(page, root);\n if (!opened) return finish(\"problemsList\", harness.host, [\"problems: the pill cannot be clicked\"], []);\n problems.push(...openPopoverProblems(opened, container, lang));\n\n await closeByEscape(page);\n const escaped = await popover(page, root);\n if (escaped) problems.push(...closedPopoverProblems(escaped, \"Escape\"));\n\n await clickPill(page, root);\n await page.mouse.click(PARK.x, PARK.y);\n await settle(page);\n const outside = await popover(page, root);\n if (outside) problems.push(...closedPopoverProblems(outside, \"an outside click\"));\n\n problems.push(...(await keyboardRows(page, root)));\n\n const skipped: ShellSkip[] = [];\n const reopened = await clickPill(page, root);\n const row = reopened?.rows.find((candidate) => candidate.button);\n if (row) {\n await page.mouse.click(row.client.x, row.client.y);\n await settle(page);\n const selected = await popover(page, root);\n if (selected) problems.push(...closedPopoverProblems(selected, \"a row with an element\"));\n } else {\n await closeByEscape(page);\n if ((reopened?.rows.length ?? 0) > 0 && !harness.absent?.includes(\"problemSelection\")) {\n skipped.push({\n hook: \"problems\",\n reason:\n 'show.problems gives no item with an elementId: a row that selects its element was not verified (absent: [\"problemSelection\"] for a modeler whose problems never point at an element)',\n });\n }\n }\n return finish(\"problemsList\", harness.host, problems, skipped);\n },\n};\n\n// ---- dropZone ----\n\nfunction drag(page: PageLike, spec: DragSpec): Promise<DropZoneFacts | null> {\n return inPage(page, dragProbe, spec);\n}\n\n/** A file the drop zone forbids as the second of two. */\nfunction secondFile(file: DropFixture): DropFixture {\n return { ...file, name: `second-${file.name}` };\n}\n\nconst dropZoneCase: ShellConformanceCase = {\n name: \"dropZone\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"dropZone\", harness, [\"drop\", \"emptyState\"]);\n const root = harness.root ?? DEFAULT_ROOT;\n const size = sizeOf(harness);\n const fixtures = harness.drop;\n if (harness.host === \"web\" && !fixtures) {\n return harness.absent?.includes(\"drop\") ? undefined : skipFor(\"drop\", \"the drop zone\");\n }\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const problems: string[] = [];\n const probeFile: DropFixture = { name: \"conformance.txt\", type: \"text/plain\", text: \"conformance\" };\n\n if (harness.host !== \"web\" || !fixtures) {\n const facts = await drag(page, { root, files: [probeFile], steps: [\"dragenter\", \"dragover\"] });\n if (facts && (facts.state !== null || facts.zone?.visible)) {\n problems.push(\n `drop-zone: a file drag shows a drop zone in the ${harness.host} host; its files belong to the host (guide §5.2)`,\n );\n }\n await drag(page, { root, files: [probeFile], steps: [\"dragleave\"] });\n return finish(\"dropZone\", harness.host, problems, []);\n }\n\n const container = (await measureChrome(page, root)).container;\n const { accepted, rejected } = fixtures;\n const check = async (\n files: readonly DropFixture[],\n strings: readonly string[],\n expected: ExpectedDrop,\n context: string,\n ) => {\n const over = await drag(page, { root, files, strings, steps: [\"dragenter\", \"dragover\"] });\n if (over) problems.push(...dropStateProblems(over, expected, context, container));\n const left = await drag(page, { root, files, strings, steps: [\"dragleave\"] });\n if (left && expected !== \"none\") {\n problems.push(...dropStateProblems(left, \"none\", `${context}, once it left the page,`, container));\n }\n };\n await check([accepted], [], \"over\", `a drag of \"${accepted.name}\"`);\n await check(\n [accepted, secondFile(accepted)],\n [],\n fixtures.multiple ? \"over\" : \"forbidden\",\n fixtures.multiple ? \"a drag of two files (multiple)\" : \"a drag of two files\",\n );\n if (await inPage(page, injectProbe, { root, kind: \"modal\" })) {\n await check([accepted], [], \"forbidden\", \"a file drag with a modal dialog open\");\n }\n await inPage(page, removeInjectedProbe, null);\n await check([], [\"Conformance text\"], \"none\", \"a text drag\");\n\n const emptyState = harness.show?.emptyState;\n if (emptyState) {\n await emptyState(page);\n await settle(page);\n }\n const onStartScreen = async () =>\n (await inPage(page, emptyStateProbe, { root, work: [] }))?.shown ?? false;\n const started = await onStartScreen();\n if (rejected) {\n await drag(page, { root, files: [rejected], steps: [\"dragenter\", \"dragover\", \"drop\"] });\n const shown = await pollUntil(\n page,\n () => toasts(page, root),\n (facts) => facts?.toasts.some((toast) => toast.status === \"danger\") ?? false,\n DROP_WAIT_MS,\n );\n if (!shown?.toasts.some((toast) => toast.status === \"danger\")) {\n problems.push(\n `drop-zone: dropping \"${rejected.name}\" shows no danger toast (guide §9, or the modeler's onReject)`,\n );\n }\n if (started && !(await onStartScreen())) {\n problems.push(\n `drop-zone: dropping \"${rejected.name}\" opened it; a file outside accept opens nothing`,\n );\n }\n await dismissAll(page, root);\n }\n const dropped = await drag(page, { root, files: [accepted], steps: [\"dragenter\", \"dragover\", \"drop\"] });\n if (dropped?.events.find((event) => event.type === \"drop\")?.defaultPrevented === false) {\n problems.push(\n `drop-zone: the drop of \"${accepted.name}\" is not prevented, so the browser would open the file`,\n );\n }\n if (started) {\n const opened = await pollUntil(page, onStartScreen, (shown) => !shown, DROP_WAIT_MS);\n if (opened)\n problems.push(\n `drop-zone: dropping \"${accepted.name}\" on the start screen does not open it (the card stays)`,\n );\n }\n const after = await drag(page, { root, files: [], steps: [] });\n if (after && (after.state !== null || after.zone?.visible)) {\n problems.push(\"drop-zone: the drop zone still shows after the drop\");\n }\n return finish(\"dropZone\", harness.host, problems, []);\n },\n};\n\n/**\n * The web column's cases (0.2), in this order after the 0.1 cases of `createCases`: `webChrome`\n * (primary action, legal line, raised zoom row, File entries), `emptyState`, `toasts`,\n * `problemsList` and `dropZone`. Each runs in every host; outside the hosts it applies to it\n * asserts that nothing of it shows (API.md, `./testing`).\n */\nexport function createWebCases(): ShellConformanceCase[] {\n return [webChromeCase, emptyStateCase, toastsCase, problemsListCase, dropZoneCase];\n}\n","import {\n APPEARANCE_STORAGE_KEY,\n INVALID_STATUS_DELAY_MS,\n SHELL,\n TOOLTIP_DELAY_MS,\n legalLineHeight,\n type Appearance,\n type AppearanceChoice,\n} from \"../core/index.js\";\nimport {\n absentIslandProblems,\n afterDestroyKeyProblem,\n appearanceProblems,\n ariaProblems,\n createProblems,\n isToolEntry,\n keyReachProblem,\n leftoverProblems,\n lockedShapeProblems,\n menuClosedProblems,\n menuKeysAtDocumentProblems,\n menuOpenProblems,\n optionalIslandProblems,\n paletteColorProblems,\n paletteShortcutProblems,\n readOnlyMenuProblems,\n readOnlyPaletteProblems,\n readOnlyStateProblems,\n surroundProblems,\n tabSequenceProblems,\n type KeyReach,\n type PaletteShortcutFacts,\n type TabStop,\n} from \"./checks.js\";\nimport {\n MODE_ROLES,\n activeStopProbe,\n appearanceProbe,\n ariaProbe,\n canvasStateProbe,\n menuEntriesProbe,\n menuProbe,\n paletteColorProbe,\n paletteEntriesProbe,\n paletteFocusProbe,\n paletteShortcutProbe,\n readOnlyStateProbe,\n surroundProbe,\n zoomButtonsProbe,\n type AppearanceFacts,\n type AriaFacts,\n type MenuFacts,\n type PaletteEntryState,\n type ShapeFacts,\n} from \"./facts.js\";\nimport {\n DEFAULT_ROOT,\n dropdownProblems,\n freeRectangle,\n geometryProblems,\n measureChrome,\n tooltipProblems,\n type ChromeMeasurement,\n type TooltipRow,\n} from \"./geometry.js\";\nimport type { ShellConformanceCase, ShellConformanceHarness, ShellSkip, ToastFixture } from \"./harness.js\";\nimport type { PageLike } from \"./page.js\";\nimport {\n afterPressProbe,\n armCleanupProbe,\n canvasHandlesProbe,\n clearKeysProbe,\n findOverlay,\n findTarget,\n focusTarget,\n hostPageModeProbe,\n inPage,\n injectProbe,\n leftoverProbe,\n removeInjectedProbe,\n settle,\n targetProbe,\n type ChromeTarget,\n type InjectedKind,\n} from \"./page-tools.js\";\nimport {\n appearanceChoiceProblems,\n expectedWebMode,\n lightOnlyMenuProblems,\n menuGroupProblems,\n modeSwitchProblems,\n pillPopupAriaProblems,\n webModeProblems,\n} from \"./web-checks.js\";\nimport { createWebCases } from \"./web-cases.js\";\nimport {\n DEFAULT_SIZES,\n HOVER_MARGIN_MS,\n LIGHT,\n PARK,\n SHOWN_ISLANDS,\n assertHooksConsistent,\n closeByEscape,\n fail,\n finish,\n hover,\n menuEntries,\n openHarness,\n openMenuByClick,\n pollUntil,\n shapes,\n sizeLabel,\n unfed,\n webHookSkips,\n} from \"./case-tools.js\";\n\nexport { DEFAULT_SIZES } from \"./case-tools.js\";\nimport { modeChangesProbe, watchModeProbe, webModeProbe, type WebModeFacts } from \"./web-facts.js\";\n\n/** How far the read-only case drags a shape (guide §13.5: no move). */\nconst LOCKED_DRAG_PX = 40;\n\n/** Room for a modeler that places, selects or re-renders a frame or two after Enter. */\nconst CREATE_WAIT_MS = 1000;\n\n/** Room after `INVALID_STATUS_DELAY_MS` for the read-only marks and the status box to show. */\nconst READ_ONLY_WAIT_MS = 1000;\n\n/** Room for the palette's 150ms colour transition (`--cd-motion-fast`) and a frame on either side. */\nconst COLOR_WAIT_MS = 600;\n\n/** Requested from the modeler by the appearance case (VS Code Dark, High Contrast, High Contrast Light). */\nconst REQUESTED_APPEARANCES: readonly Appearance[] = [\n { theme: \"dark\" },\n { theme: \"dark\", kontrast: \"hoch\" },\n { theme: \"light\", kontrast: \"hoch\" },\n];\n\n/** Every kind of text field a modeler renders: inspector and dialog fields, the label editor. */\nconst TEXT_FIELDS: ReadonlyArray<readonly [InjectedKind, string]> = [\n [\"input\", \"a text field\"],\n [\"textarea\", \"a textarea\"],\n [\"contenteditable\", \"an editable label\"],\n];\n\nconst UNDO_REDO_PRESSES = [\n \"Control+KeyZ\",\n \"Meta+KeyZ\",\n \"Control+Shift+KeyZ\",\n \"Meta+Shift+KeyZ\",\n \"Control+KeyY\",\n] as const;\n\nconst ONE_STEP_UP = 135;\nconst TWO_STEPS_UP = 182;\nconst ZOOM_LIMIT_MAX = 400;\nconst ZOOM_LIMIT_MIN = 20;\n\nfunction appearanceLabel(appearance: Appearance): string {\n return appearance.kontrast ? `${appearance.theme} + ${appearance.kontrast}` : appearance.theme;\n}\n\nfunction missingHooks<P extends PageLike>(harness: ShellConformanceHarness<P>, what: string): ShellSkip[] {\n return SHOWN_ISLANDS.filter((island) => unfed(harness, island)).map((island) => ({\n hook: island,\n reason: `show.${island} is undefined: ${what} of the ${island} island not verified`,\n }));\n}\n\n/** The visible islands of an ARIA snapshot that a harness may declare absent. */\nfunction visibleIslands(facts: AriaFacts): Set<string> {\n const islands = new Set<string>();\n for (const island of SHOWN_ISLANDS) if (facts[island]?.visible) islands.add(island);\n return islands;\n}\n\n/** Dropdown and tooltips of one measured state (guide §5.4, §5.6). */\nasync function popupGeometry(\n page: PageLike,\n root: string,\n measurement: ChromeMeasurement,\n): Promise<string[]> {\n const problems: string[] = [];\n if (!(await openMenuByClick(page, root))) return [\"dropdown: no visible menu trigger to open it\"];\n const dropdown = await findOverlay(page, root, \"menu\");\n if (!dropdown) problems.push('dropdown: no visible role=\"menu\" after clicking the trigger');\n else problems.push(...dropdownProblems(dropdown.box, measurement.container));\n await closeByEscape(page);\n\n const rows: Array<[ChromeTarget, TooltipRow]> = [\n [\"menu\", \"top\"],\n [\"palette-entry\", measurement.paletteRow === \"second-row\" ? \"second-row\" : \"top\"],\n [\"zoom-in\", \"bottom\"],\n ];\n for (const [target, row] of rows) {\n const anchor = await hover(page, root, target);\n if (!anchor) {\n problems.push(`tooltip: no visible ${target} to hover`);\n continue;\n }\n const tooltip = await findOverlay(page, root, \"tooltip\");\n if (!tooltip) {\n problems.push(`tooltip: none visible ${TOOLTIP_DELAY_MS + HOVER_MARGIN_MS}ms after hovering ${target}`);\n continue;\n }\n if (tooltip.count > 1) problems.push(`tooltip: ${tooltip.count} tooltips visible at once`);\n if (anchor.label && !tooltip.text.startsWith(anchor.label)) {\n problems.push(`tooltip: hovering ${target} (\"${anchor.label}\") shows \"${tooltip.text}\"`);\n }\n // The web app's raised zoom row stands above the legal line (`data-zoom-row=\"raised\"`).\n const legalHeight = legalLineHeight(measurement.islands.legal?.height);\n const bottomRow = measurement.open.zoomRaised ? SHELL.edge + legalHeight + SHELL.gap : SHELL.edge;\n problems.push(\n ...tooltipProblems(tooltip.box, anchor.box, row, measurement.container, undefined, bottomRow).map(\n (problem) => `${problem} (on ${target})`,\n ),\n );\n }\n await page.mouse.move(PARK.x, PARK.y);\n return problems;\n}\n\n/** Shown by the geometry case after \"as opened\"; its action keeps it on screen through every state. */\nconst GEOMETRY_TOAST: ToastFixture = {\n status: \"info\",\n text: \"Conformance: the toast stack's geometry\",\n actionLabel: \"Undo\",\n};\n\n/** The pill's list in the web app (and an embedded one that opens it), measured after a click (guide §5.10). */\nasync function withProblemsListOpen(\n page: PageLike,\n root: string,\n check: () => Promise<unknown>,\n): Promise<void> {\n const pill = await findTarget(page, root, \"pill\");\n if (!pill) return;\n await page.mouse.click(pill.client.x, pill.client.y);\n await settle(page);\n await check();\n await closeByEscape(page);\n}\n\nconst geometryCase: ShellConformanceCase = {\n name: \"geometry\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"geometry\", harness, [...SHOWN_ISLANDS, \"toast\", \"emptyState\"]);\n const root = harness.root ?? DEFAULT_ROOT;\n const problems: string[] = [];\n for (const size of harness.sizes ?? DEFAULT_SIZES) {\n const at = sizeLabel(size);\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const check = async (state: string): Promise<ChromeMeasurement> => {\n const measurement = await measureChrome(page, root);\n problems.push(\n ...[\n ...geometryProblems(measurement, harness.host),\n ...absentIslandProblems(new Set(Object.keys(measurement.islands)), harness.absent),\n ].map((problem) => `[${at}, ${state}] ${problem}`),\n );\n return measurement;\n };\n const opened = await check(\"as opened\");\n problems.push(...(await popupGeometry(page, root, opened)).map((problem) => `[${at}] ${problem}`));\n const toast = harness.show?.toast;\n if (toast) {\n await toast(page, GEOMETRY_TOAST);\n await settle(page);\n await check(\"with a toast\");\n }\n for (const island of SHOWN_ISLANDS) {\n const show = harness.show?.[island];\n if (!show) continue;\n await show(page);\n await settle(page);\n await check(`after show.${island}`);\n if (island === \"problems\" && harness.host !== \"ide\") {\n await withProblemsListOpen(page, root, () => check(\"with the problems list open\"));\n }\n }\n const emptyState = harness.show?.emptyState;\n if (emptyState) {\n await emptyState(page);\n await settle(page);\n await check(\"after show.emptyState\");\n }\n }\n return finish(\"geometry\", harness.host, problems, [\n ...missingHooks(harness, \"the geometry\"),\n ...webHookSkips(harness, {\n toast: \"the geometry of the toast stack\",\n emptyState: \"the geometry of the start screen\",\n }),\n ]);\n },\n};\n\nasync function menuState(page: PageLike, root: string): Promise<MenuFacts> {\n const facts = await inPage(page, menuProbe, { root });\n if (!facts) throw new Error(`@miragon/modeler-shell conformance: no element matches \"${root}\"`);\n return facts;\n}\n\n/** Keyboard model of the menu (guide §5.4): Enter/↓ open on the first entry, ↑ on the last, wrap, Escape. */\nasync function menuKeyboardProblems(page: PageLike, root: string): Promise<string[]> {\n const problems: string[] = [];\n const openWith = async (key: string, focus: \"first\" | \"last\"): Promise<MenuFacts | undefined> => {\n if (!(await focusTarget(page, root, \"menu\"))) {\n problems.push(\"menu: the trigger cannot take focus\");\n return undefined;\n }\n await page.keyboard.press(key);\n await settle(page);\n const opened = await menuState(page, root);\n problems.push(...menuOpenProblems(opened, focus).map((problem) => `${key} on the trigger: ${problem}`));\n return opened;\n };\n const close = async (key: string) => {\n await closeByEscape(page);\n problems.push(\n ...menuClosedProblems(await menuState(page, root), true).map(\n (problem) => `${key}, then Escape: ${problem}`,\n ),\n );\n };\n\n const opened = await openWith(\"Enter\", \"first\");\n if (opened && opened.items.length > 1) {\n const moves: Array<[string, (count: number) => number]> = [\n [\"ArrowUp\", (count) => count - 1],\n [\"ArrowDown\", () => 0],\n [\"End\", (count) => count - 1],\n [\"Home\", () => 0],\n ];\n await inPage(page, clearKeysProbe, null);\n for (const [key, target] of moves) {\n await page.keyboard.press(key);\n const moved = await menuState(page, root);\n const expected = target(moved.items.length);\n if (moved.active !== expected) {\n problems.push(\n `menu: ${key} moves the focus to entry ${moved.active + 1}, expected entry ${expected + 1} of ${moved.items.length}`,\n );\n }\n }\n const { documentKeys } = await inPage(page, afterPressProbe, { root });\n problems.push(\n ...menuKeysAtDocumentProblems(\n moves.map(([key]) => key),\n documentKeys,\n ),\n );\n }\n if (opened) await close(\"Enter\");\n if (await openWith(\"ArrowDown\", \"first\")) await close(\"ArrowDown\");\n if (await openWith(\"ArrowUp\", \"last\")) await close(\"ArrowUp\");\n return problems;\n}\n\n/** Roving tabindex of the palette toolbar (guide §5.5): ← → Home End. */\nasync function paletteKeyboardProblems(page: PageLike, root: string): Promise<string[]> {\n const before = await inPage(page, paletteFocusProbe, { root });\n if (!before || before.entries.length < 2) return [];\n if (!(await focusTarget(page, root, \"palette-tab-stop\"))) {\n return ['palette: no entry with tabindex=\"0\" takes the focus'];\n }\n const problems: string[] = [];\n const start = before.entries.indexOf(before.tabStops[0] ?? \"\");\n const step = start < before.entries.length - 1 ? 1 : -1;\n const moves: Array<[string, number]> = [\n [step === 1 ? \"ArrowRight\" : \"ArrowLeft\", start + step],\n [\"End\", before.entries.length - 1],\n [\"Home\", 0],\n ];\n for (const [key, index] of moves) {\n await page.keyboard.press(key);\n const after = await inPage(page, paletteFocusProbe, { root });\n const expected = before.entries[index];\n if (!after || after.active !== expected) {\n problems.push(`palette: ${key} focuses \"${after?.active ?? \"nothing\"}\", expected \"${expected}\"`);\n } else if (after.tabStops.length !== 1 || after.tabStops[0] !== expected) {\n problems.push(\n `palette: after ${key} tabindex=\"0\" is on ${after.tabStops.join(\", \") || \"no entry\"}, expected \"${expected}\"`,\n );\n }\n }\n return problems;\n}\n\n/** Every palette entry by keyboard: a shortcut its tooltip shows is named in `aria-keyshortcuts`. */\nasync function paletteShortcutWalk(page: PageLike, root: string): Promise<string[]> {\n const before = await inPage(page, paletteFocusProbe, { root });\n if (!before || before.entries.length === 0) return [];\n if (!(await focusTarget(page, root, \"palette-tab-stop\"))) return [];\n if (before.entries.length > 1) await page.keyboard.press(\"End\");\n await page.keyboard.press(\"Home\");\n const seen: PaletteShortcutFacts[] = [];\n for (let index = 0; index < before.entries.length; index++) {\n const facts = await inPage(page, paletteShortcutProbe, { root });\n if (facts) seen.push(facts);\n await page.keyboard.press(\"ArrowRight\");\n }\n return paletteShortcutProblems(seen);\n}\n\n/** Tab from the menu trigger: the primary action (web app), the palette's one stop, then the canvas (guide §5.14). */\nasync function tabSequenceFromMenu(page: PageLike, root: string, primary: boolean): Promise<string[]> {\n if (!(await focusTarget(page, root, \"menu\"))) return [];\n const stops: TabStop[] = [];\n for (let step = 0; step < 3; step++) {\n await page.keyboard.press(\"Tab\");\n const stop = await inPage(page, activeStopProbe, { root });\n stops.push({ description: stop.description, kind: stop.kind as TabStop[\"kind\"] });\n }\n return tabSequenceProblems(stops, primary);\n}\n\n/** `aria-disabled` at 400 % and 20 % (guide §5.8), reached by clicking the buttons. */\nasync function zoomLimitProblems(page: PageLike, root: string): Promise<string[]> {\n const problems: string[] = [];\n const limits: Array<[\"in\" | \"out\", ChromeTarget, number, number, \"in\" | \"out\"]> = [\n [\"in\", \"zoom-in\", ZOOM_LIMIT_MAX, 12, \"out\"],\n [\"out\", \"zoom-out\", ZOOM_LIMIT_MIN, 16, \"in\"],\n ];\n for (const [button, target, limit, maxClicks, other] of limits) {\n const control = await findTarget(page, root, target);\n if (!control) continue;\n let buttons = await inPage(page, zoomButtonsProbe, { root });\n for (\n let click = 0;\n click < maxClicks && buttons[button]?.attributes[\"aria-disabled\"] !== \"true\";\n click++\n ) {\n await page.mouse.click(control.client.x, control.client.y);\n await settle(page);\n buttons = await inPage(page, zoomButtonsProbe, { root });\n }\n const { zoom } = await inPage(page, afterPressProbe, { root });\n const reached = buttons[button];\n if (reached?.attributes[\"aria-disabled\"] !== \"true\") {\n problems.push(\n `zoom: [data-zoom=\"${button}\"] is not aria-disabled after ${maxClicks} clicks (readout ${zoom ?? \"?\"}%)`,\n );\n } else {\n if (zoom !== limit) {\n problems.push(`zoom: [data-zoom=\"${button}\"] is disabled at ${zoom ?? \"?\"}%, expected at ${limit}%`);\n }\n if (reached.disabled) problems.push(`zoom: [data-zoom=\"${button}\"] is natively disabled at the limit`);\n }\n if (buttons[other]?.attributes[\"aria-disabled\"] === \"true\") {\n problems.push(`zoom: [data-zoom=\"${other}\"] is aria-disabled at ${zoom ?? \"?\"}%`);\n }\n if (buttons.actual?.attributes[\"aria-disabled\"] === \"true\") {\n problems.push(\"zoom: the readout is disabled at a limit\");\n }\n }\n await page.mouse.move(PARK.x, PARK.y);\n return problems;\n}\n\nconst ariaCase: ShellConformanceCase = {\n name: \"aria\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"aria\", harness, SHOWN_ISLANDS);\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const facts = await inPage(page, ariaProbe, { root });\n if (!facts) fail(\"aria\", harness.host, [`no element matches the shell root selector \"${root}\"`]);\n const problems = ariaProblems(facts, harness.host);\n problems.push(...menuGroupProblems(await menuEntries(page, root), harness.host, harness.themes));\n problems.push(...(await menuKeyboardProblems(page, root)));\n problems.push(...(await paletteKeyboardProblems(page, root)));\n problems.push(...(await paletteShortcutWalk(page, root)));\n problems.push(\n ...(await tabSequenceFromMenu(page, root, harness.host === \"web\" && Boolean(facts.primary?.visible))),\n );\n problems.push(...(await zoomLimitProblems(page, root)));\n\n const shown = new Set<string>();\n for (const island of SHOWN_ISLANDS) {\n const show = harness.show?.[island];\n if (!show) continue;\n await show(page);\n shown.add(island);\n }\n let final: AriaFacts = facts;\n if (shown.size > 0) {\n await settle(page);\n const withIslands = await inPage(page, ariaProbe, { root });\n if (withIslands) {\n final = withIslands;\n problems.push(...optionalIslandProblems(withIslands, shown));\n if (shown.has(\"problems\")) problems.push(...pillPopupAriaProblems(withIslands, harness.host));\n const known = new Set(problems);\n problems.push(\n ...ariaProblems(withIslands, harness.host)\n .filter((problem) => !known.has(problem))\n .map((problem) => `with every island shown: ${problem}`),\n );\n }\n }\n problems.push(...absentIslandProblems(visibleIslands(final), harness.absent));\n return finish(\"aria\", harness.host, problems, missingHooks(harness, \"the roles and names\"));\n },\n};\n\nconst keysCase: ShellConformanceCase = {\n name: \"keys\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const host = harness.host;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const problems: string[] = [];\n\n if (!(await focusTarget(page, root, \"canvas\"))) {\n fail(\"keys\", host, [\"canvas: the diagram-js <svg> (.djs-container > svg) cannot take focus\"]);\n }\n await inPage(page, clearKeysProbe, null);\n let current = (await inPage(page, afterPressProbe, { root })).zoom;\n if (current === null) fail(\"keys\", host, ['zoom: no readout [data-zoom=\"actual\"] showing a percentage']);\n\n const press = async (\n key: string,\n reach: KeyReach | undefined,\n zoom: number | \"unchanged\" | undefined,\n context = \"on the canvas\",\n ) => {\n const before = current;\n await page.keyboard.press(key);\n let after = await inPage(page, afterPressProbe, { root });\n const where = `${key} ${context}`;\n if (reach) {\n const problem = keyReachProblem(where, reach, host, after);\n if (problem) problems.push(problem);\n }\n if (zoom === undefined) return;\n const expected = zoom === \"unchanged\" ? before : zoom;\n // a readout that has not moved yet may still be waiting for its frame; a wrong one stays wrong\n for (let poll = 0; after.zoom === before && expected !== before && poll < 10; poll++) {\n await page.waitForTimeout(50);\n after = await inPage(page, afterPressProbe, { root });\n }\n if (after.zoom !== expected) {\n problems.push(\n zoom === \"unchanged\"\n ? `${where} changed the zoom from ${before}% to ${after.zoom ?? \"?\"}%; it must not act`\n : `${where} zoomed to ${after.zoom ?? \"?\"}% from ${before}%, expected ${expected}% (exactly one step)`,\n );\n }\n current = after.zoom ?? current;\n };\n const inside = async (kind: InjectedKind, context: string, steps: () => Promise<void>) => {\n if (await inPage(page, injectProbe, { root, kind })) await steps();\n else problems.push(`cannot focus ${context} stand-in inside the root`);\n await inPage(page, removeInjectedProbe, null);\n };\n\n await press(\"Control+Digit0\", \"handled\", 100);\n const pairs: Array<[string, string]> = [\n [\"Control+Equal\", \"Control+Minus\"],\n [\"Control+Shift+Equal\", \"Control+Shift+Minus\"],\n [\"Meta+Equal\", \"Meta+Minus\"],\n [\"Meta+Shift+Equal\", \"Meta+Shift+Minus\"],\n [\"Control+NumpadAdd\", \"Control+NumpadSubtract\"],\n [\"Meta+NumpadAdd\", \"Meta+NumpadSubtract\"],\n ];\n for (const [zoomIn, zoomOut] of pairs) {\n await press(zoomIn, \"handled\", ONE_STEP_UP);\n await press(zoomOut, \"handled\", 100);\n }\n for (const zoomToActual of [\"Meta+Digit0\", \"Control+Numpad0\"]) {\n await press(\"Control+Equal\", \"handled\", ONE_STEP_UP);\n await press(zoomToActual, \"handled\", 100);\n }\n for (const key of [\"Equal\", \"Minus\", \"Shift+Equal\", \"Shift+Minus\", \"NumpadAdd\", \"NumpadSubtract\"]) {\n await press(key, \"free\", \"unchanged\", \"on the canvas without Cmd/Ctrl\");\n }\n for (const key of [\"Digit0\", \"Control+Alt+Equal\", \"Control+Alt+Minus\", \"Control+Shift+Digit1\"]) {\n await press(key, undefined, \"unchanged\");\n }\n await press(\"F1\", \"free\", undefined);\n await press(\"Escape\", \"free\", undefined, \"on the canvas without a menu or dialog\");\n if (await inPage(page, canvasHandlesProbe, { root, key: \"F9\" })) {\n await press(\"F9\", \"canvas\", undefined, \"handled by the canvas\");\n }\n await inPage(page, removeInjectedProbe, null);\n if (host === \"ide\") {\n // Guide §13.5: on the canvas, undo and redo use the document's history, never the canvas's.\n for (const key of UNDO_REDO_PRESSES) {\n await press(key, \"free\", undefined, \"on the canvas (undo and redo belong to the VS Code document)\");\n }\n }\n // Guide §13.5: keys the canvas uses act on the canvas only, select all included; in VS Code an\n // unhandled Cmd/Ctrl+A would select the webview's text instead.\n for (const key of [\"Control+KeyA\", \"Meta+KeyA\"]) {\n await press(key, \"canvas\", undefined, \"on the canvas (select all acts on the canvas only)\");\n }\n\n await press(\"Control+Equal\", \"handled\", ONE_STEP_UP);\n for (const [kind, field] of TEXT_FIELDS) {\n await inside(kind, field, async () => {\n await press(\"Control+Equal\", \"blocked\", \"unchanged\", `in ${field}`);\n await press(\"Control+Minus\", \"blocked\", \"unchanged\", `in ${field}`);\n await press(\"Shift+Digit1\", \"free\", \"unchanged\", `in ${field}`);\n await press(\"Control+KeyZ\", \"blocked\", undefined, `in ${field}`);\n await press(\"Meta+Shift+KeyZ\", \"blocked\", undefined, `in ${field}`);\n await press(\"Control+KeyY\", \"blocked\", undefined, `in ${field}`);\n });\n }\n await inside(\"modal\", \"a modal dialog\", async () => {\n await press(\"Control+Equal\", \"blocked\", \"unchanged\", \"with a modal dialog open\");\n await press(\"Shift+Digit1\", \"free\", \"unchanged\", \"with a modal dialog open\");\n await press(\"Escape\", \"blocked\", undefined, \"with a modal dialog open\");\n });\n await inside(\"popover\", \"a popover\", async () => {\n await press(\"Control+Minus\", \"handled\", 100, \"in a popover\");\n await press(\"Control+Equal\", \"handled\", ONE_STEP_UP, \"in a popover\");\n await press(\"Escape\", \"blocked\", undefined, \"with a popover open\");\n });\n\n if (await openMenuByClick(page, root)) {\n await inPage(page, clearKeysProbe, null);\n await press(\"Escape\", \"handled\", undefined, \"with the menu open\");\n if (await findOverlay(page, root, \"menu\")) problems.push(\"Escape with the menu open did not close it\");\n }\n\n await focusTarget(page, root, \"canvas\");\n await press(\"Control+Equal\", \"handled\", TWO_STEPS_UP);\n await page.keyboard.press(\"Shift+Digit1\");\n let fitted = await inPage(page, afterPressProbe, { root });\n const reachProblem = keyReachProblem(\"Shift+Digit1 on the canvas\", \"handled\", host, fitted);\n if (reachProblem) problems.push(reachProblem);\n for (let poll = 0; (fitted.zoom === null || fitted.zoom > 100) && poll < 20; poll++) {\n await page.waitForTimeout(50);\n fitted = await inPage(page, afterPressProbe, { root });\n }\n if (fitted.zoom === null || fitted.zoom > 100) {\n problems.push(\n `Shift+Digit1 on the canvas left the zoom at ${fitted.zoom ?? \"?\"}%, expected a fit (at most 100%)`,\n );\n }\n return finish(\"keys\", host, problems, []);\n },\n};\n\nasync function appearanceFacts(page: PageLike, root: string): Promise<AppearanceFacts | null> {\n const probe = () => inPage(page, appearanceProbe, { root, roles: MODE_ROLES });\n await hover(page, root, \"zoom-in\");\n const withTooltip = await probe();\n const opened = await openMenuByClick(page, root);\n const withMenu = await probe();\n if (opened) await closeByEscape(page);\n await page.mouse.move(PARK.x, PARK.y);\n if (!withTooltip || !withMenu) return withTooltip ?? withMenu;\n const names = new Set(withTooltip.parts.map((part) => part.name));\n return {\n ...withMenu,\n parts: [...withTooltip.parts, ...withMenu.parts.filter((part) => !names.has(part.name))],\n };\n}\n\n/** The palette's tool colours in the current state, read until a running colour transition is done. */\nasync function paletteColors(page: PageLike, root: string): Promise<string[]> {\n const read = async () => {\n const facts = await inPage(page, paletteColorProbe, { root });\n return facts ? paletteColorProblems(facts) : [];\n };\n return pollUntil(page, read, (problems) => problems.length === 0, COLOR_WAIT_MS);\n}\n\n/**\n * Guide §5.5: every tool entry at rest, hovered in turn, and the first tool armed by a click\n * (pressed and hovered, then pressed with the pointer away), Escape afterwards.\n */\nasync function paletteColorWalk(page: PageLike, root: string): Promise<string[]> {\n const problems: string[] = [];\n await page.mouse.move(PARK.x, PARK.y);\n problems.push(...(await paletteColors(page, root)));\n const tools = (await inPage(page, paletteEntriesProbe, { root })).filter(\n (entry) => isToolEntry(entry) && !entry.disabled,\n );\n for (const tool of tools) {\n await page.mouse.move(tool.client.x, tool.client.y);\n problems.push(...(await paletteColors(page, root)));\n await page.mouse.move(PARK.x, PARK.y);\n }\n const armed =\n tools.find((tool) => tool.action === \"lasso-tool\") ?? tools.find((tool) => tool.action.endsWith(\"-tool\"));\n if (armed) {\n await page.mouse.click(armed.client.x, armed.client.y);\n await settle(page);\n const pressed = (await inPage(page, paletteEntriesProbe, { root })).find(\n (entry) => entry.action === armed.action,\n );\n if (!pressed?.pressed) {\n problems.push(`palette: clicking tool \"${armed.action}\" does not set aria-pressed=\"true\" (guide §5.5)`);\n }\n problems.push(...(await paletteColors(page, root)));\n await page.mouse.move(PARK.x, PARK.y);\n problems.push(...(await paletteColors(page, root)));\n await closeByEscape(page);\n }\n return [...new Set(problems)];\n}\n\n/** The web app's mode, its meta tags and the stored choice. */\nfunction webMode(page: PageLike): Promise<WebModeFacts> {\n return inPage(page, webModeProbe, { key: APPEARANCE_STORAGE_KEY });\n}\n\nconst APPEARANCE_LABELS: Readonly<Record<AppearanceChoice, string>> = {\n system: \"System\",\n light: \"Light\",\n dark: \"Dark\",\n};\n\n/**\n * Guide §13.3 for a dark-capable web app: Dark, Light, then System through the Appearance group,\n * each written to `<html>`, `color-scheme`, both `theme-color`s and `localStorage` in one frame and\n * never half-dark; the theme colours are the ones the page showed under System.\n */\nasync function appearanceSwitchProblems<P extends PageLike>(\n page: P,\n harness: ShellConformanceHarness<P>,\n root: string,\n requested: Appearance,\n): Promise<string[]> {\n const problems: string[] = [];\n const system = await webMode(page);\n const media = (scheme: string) =>\n system.themeColors.find((meta) => meta.media?.replace(/\\s+/g, \"\") === `(prefers-color-scheme:${scheme})`)\n ?.content;\n const light = media(\"light\");\n const dark = media(\"dark\");\n const colors = light && dark ? { light, dark } : undefined;\n for (const choice of [\"dark\", \"light\", \"system\"] as const) {\n const label = APPEARANCE_LABELS[choice];\n if (!(await openMenuByClick(page, root))) {\n problems.push(`menu: no visible menu trigger to choose ${label}`);\n break;\n }\n const option = await inPage(page, targetProbe, {\n root,\n selector: `[data-menu-id=\"appearance\"] [data-menu-value=\"${choice}\"]`,\n });\n if (!option) {\n problems.push(`menu: no Appearance option \"${choice}\" to choose (guide §13.3)`);\n await closeByEscape(page);\n break;\n }\n await inPage(page, watchModeProbe, null);\n await page.mouse.click(option.client.x, option.client.y);\n await settle(page);\n problems.push(...modeSwitchProblems(await inPage(page, modeChangesProbe, null), label));\n problems.push(\n ...appearanceChoiceProblems((await inPage(page, menuEntriesProbe, { root })) ?? [], choice),\n );\n await closeByEscape(page);\n problems.push(...webModeProblems(await webMode(page), harness.themes, choice, colors));\n const facts = await appearanceFacts(page, root);\n if (facts) {\n const expected = expectedWebMode(requested, harness.themes, choice);\n problems.push(\n ...appearanceProblems(facts, \"web\", requested, harness.themes, expected).problems.map(\n (problem) => `[chose ${label}] ${problem}`,\n ),\n );\n }\n }\n return problems;\n}\n\nconst appearanceCase: ShellConformanceCase = {\n name: \"appearance\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n const problems: string[] = [];\n const skipped: ShellSkip[] = [];\n const web = harness.host === \"web\";\n // Without emulateMedia the web app's system preference stays the browser's light default.\n const emulated = !web || page.emulateMedia !== undefined;\n if (!emulated) {\n skipped.push({\n hook: \"open\",\n reason:\n \"page.emulateMedia is undefined: the web app's mode under a dark system and under high contrast was not verified\",\n });\n }\n let switched = false;\n for (const requested of emulated ? REQUESTED_APPEARANCES : [LIGHT]) {\n const at = `[requested ${appearanceLabel(requested)}]`;\n await openHarness(page, harness, { size, requested });\n if (harness.host === \"embedded\") {\n // The foreign page itself in that mode: a themed page around the modeler (guide §13.3).\n await inPage(page, hostPageModeProbe, {\n theme: requested.theme,\n kontrast: requested.kontrast ?? null,\n });\n }\n await settle(page);\n const facts = await appearanceFacts(page, root);\n if (!facts) {\n problems.push(`${at} no element matches the shell root selector \"${root}\"`);\n continue;\n }\n const expected = web ? expectedWebMode(requested, harness.themes, \"system\") : undefined;\n const verdict = appearanceProblems(facts, harness.host, requested, harness.themes, expected);\n problems.push(...verdict.problems.map((problem) => `${at} ${problem}`));\n const surround = await inPage(page, surroundProbe, { root });\n if (surround) problems.push(...surroundProblems(surround).map((problem) => `${at} ${problem}`));\n problems.push(...(await paletteColorWalk(page, root)).map((problem) => `${at} ${problem}`));\n if (web) {\n problems.push(\n ...webModeProblems(await webMode(page), harness.themes, \"system\", undefined).map(\n (problem) => `${at} ${problem}`,\n ),\n ...lightOnlyMenuProblems(await menuEntries(page, root), harness.themes).map(\n (problem) => `${at} ${problem}`,\n ),\n );\n if (harness.themes.includes(\"dark\") && !switched && requested.theme === \"dark\") {\n switched = true;\n problems.push(\n ...(await appearanceSwitchProblems(page, harness, root, requested)).map(\n (problem) => `${at} ${problem}`,\n ),\n );\n }\n }\n }\n return finish(\"appearance\", harness.host, problems, skipped);\n },\n};\n\n/** Moves the palette's roving focus by keyboard to `action`; `false` when it cannot get there. */\nasync function focusPaletteEntry(page: PageLike, root: string, action: string): Promise<boolean> {\n const before = await inPage(page, paletteFocusProbe, { root });\n if (!before || !before.entries.includes(action)) return false;\n if (!(await focusTarget(page, root, \"palette-tab-stop\"))) return false;\n await page.keyboard.press(\"Home\");\n for (let step = 0; step <= before.entries.length; step++) {\n if ((await inPage(page, paletteFocusProbe, { root }))?.active === action) return true;\n await page.keyboard.press(\"ArrowRight\");\n }\n return false;\n}\n\n/** The first entry that creates something: outside the tools group and not a tool. */\nfunction firstCreatingEntry(entries: readonly PaletteEntryState[]): PaletteEntryState | undefined {\n return entries.find((entry) => !isToolEntry(entry));\n}\n\n/** Enter on `entry`; the shapes once a new one appeared or `CREATE_WAIT_MS` passed. */\nasync function enterOnEntry(\n page: PageLike,\n root: string,\n entry: string,\n before: readonly ShapeFacts[],\n): Promise<ShapeFacts[] | undefined> {\n if (!(await focusPaletteEntry(page, root, entry))) return undefined;\n await page.keyboard.press(\"Enter\");\n await settle(page);\n const known = new Set(before.map((shape) => shape.id));\n return pollUntil(\n page,\n () => shapes(page, root),\n (after) => after.some((shape) => !known.has(shape.id)),\n CREATE_WAIT_MS,\n );\n}\n\nconst createCase: ShellConformanceCase = {\n name: \"create\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const entry = firstCreatingEntry(await inPage(page, paletteEntriesProbe, { root }));\n // A notation whose palette only switches tools has nothing to place.\n if (!entry) return undefined;\n await page.mouse.move(PARK.x, PARK.y);\n const free = freeRectangle(await measureChrome(page, root), harness.host);\n const before = await shapes(page, root);\n const after = await enterOnEntry(page, root, entry.action, before);\n if (!after) {\n fail(\"create\", harness.host, [`create: the palette's roving focus does not reach \"${entry.action}\"`]);\n }\n const canvas = await inPage(page, canvasStateProbe, { root });\n const problems = createProblems({ entry: entry.action, before, after, canvas, free });\n await closeByEscape(page);\n return finish(\"create\", harness.host, problems, []);\n },\n};\n\n/** A shape whose centre a pointer reaches (no chrome above it), found again by its id. */\nasync function reachableShape(page: PageLike, root: string, id?: string): Promise<ShapeFacts | undefined> {\n const all = await shapes(page, root);\n return id === undefined ? all.find((shape) => shape.hit) : all.find((shape) => shape.id === id);\n}\n\n/** Guide §13.5, \"Was der Schreibschutz sperrt\", on one shape: select, drag, double-click, delete. */\nasync function lockedShapeChecks(page: PageLike, root: string, shape: ShapeFacts): Promise<string[]> {\n await page.mouse.click(shape.client.x, shape.client.y);\n await settle(page);\n const selected = await inPage(page, canvasStateProbe, { root });\n\n const before = (await reachableShape(page, root, shape.id)) ?? shape;\n await page.mouse.move(before.client.x, before.client.y);\n await page.mouse.down();\n for (let step = 1; step <= 4; step++) {\n await page.mouse.move(before.client.x + (LOCKED_DRAG_PX * step) / 4, before.client.y);\n }\n await page.mouse.up();\n await settle(page);\n const dragged = await reachableShape(page, root, shape.id);\n\n const target = dragged ?? before;\n await page.mouse.dblclick(target.client.x, target.client.y);\n await settle(page);\n const { textFields } = await inPage(page, canvasStateProbe, { root });\n await closeByEscape(page);\n\n const kept = { Delete: true, Backspace: true };\n for (const key of [\"Delete\", \"Backspace\"] as const) {\n const current = await reachableShape(page, root, shape.id);\n if (!current) break;\n // a key that deletes the selection must not miss it; a click on a selected shape deselects it\n if (!current.selected) await page.mouse.click(current.client.x, current.client.y);\n await focusTarget(page, root, \"canvas\");\n await page.keyboard.press(key);\n await settle(page);\n kept[key] = (await reachableShape(page, root, shape.id)) !== undefined;\n }\n await page.mouse.move(PARK.x, PARK.y);\n return lockedShapeProblems({\n contextPadEntries: selected.contextPadEntries,\n dragged: { before, after: dragged },\n textFields,\n kept,\n });\n}\n\nconst readOnlyCase: ShellConformanceCase = {\n name: \"readOnly\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n assertHooksConsistent(\"readOnly\", harness, [\"invalid\"]);\n const invalid = harness.show?.invalid;\n if (!invalid) {\n if (harness.absent?.includes(\"invalid\")) return undefined;\n return {\n skipped: [\n {\n hook: \"invalid\",\n reason: \"show.invalid is undefined: the read-only canvas of an invalid file was not verified\",\n },\n ],\n };\n }\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n const problems: string[] = [];\n const skipped: ShellSkip[] = [];\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const menuBefore = await menuEntries(page, root);\n\n await invalid(page);\n await page.waitForTimeout(INVALID_STATUS_DELAY_MS);\n const state = await pollUntil(\n page,\n () => inPage(page, readOnlyStateProbe, { root }),\n (facts) => facts === null || readOnlyStateProblems(facts).length === 0,\n READ_ONLY_WAIT_MS,\n );\n if (!state) fail(\"readOnly\", harness.host, [`no element matches the shell root selector \"${root}\"`]);\n await settle(page);\n problems.push(...readOnlyStateProblems(state));\n\n const entries = await inPage(page, paletteEntriesProbe, { root });\n problems.push(...readOnlyPaletteProblems(entries));\n problems.push(...(await paletteColors(page, root)));\n const creating = firstCreatingEntry(entries);\n if (creating) {\n const before = await shapes(page, root);\n const after = await enterOnEntry(page, root, creating.action, before);\n const known = new Set(before.map((shape) => shape.id));\n const added = (after ?? []).filter((shape) => !known.has(shape.id));\n if (added.length > 0) {\n problems.push(\n `read-only: Enter on palette entry \"${creating.action}\" added ${added.map((shape) => `\"${shape.id}\"`).join(\", \")} (guide §13.5)`,\n );\n }\n await closeByEscape(page);\n }\n\n problems.push(...readOnlyMenuProblems(menuBefore, await menuEntries(page, root)));\n\n const shape = await reachableShape(page, root);\n if (shape) {\n problems.push(...(await lockedShapeChecks(page, root, shape)));\n } else {\n skipped.push({\n hook: \"open\",\n reason:\n \"the opened document shows no shape a pointer reaches: context pad, move, delete and label editor of the read-only canvas not verified\",\n });\n }\n return finish(\"readOnly\", harness.host, problems, skipped);\n },\n};\n\nconst cleanupCase: ShellConformanceCase = {\n name: \"cleanup\",\n async run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>) {\n if (!harness.destroy) {\n return {\n skipped: [\n {\n hook: \"destroy\",\n reason: \"harness.destroy is undefined: the cleanup after destroy was not verified\",\n },\n ],\n };\n }\n const root = harness.root ?? DEFAULT_ROOT;\n const size = (harness.sizes ?? DEFAULT_SIZES)[0] ?? DEFAULT_SIZES[0]!;\n await openHarness(page, harness, { size, requested: LIGHT });\n await settle(page);\n const armed = await inPage(page, armCleanupProbe, { root });\n if (!armed) fail(\"cleanup\", harness.host, [`no element matches the shell root selector \"${root}\"`]);\n const problems: string[] = [];\n\n // A hover leaves the tooltip timer pending, so a timer that outlives destroy shows up below.\n const zoomIn = await findTarget(page, root, \"zoom-in\");\n if (zoomIn) {\n await page.mouse.move(PARK.x, PARK.y);\n await page.mouse.move(zoomIn.client.x, zoomIn.client.y);\n }\n try {\n await harness.destroy(page);\n } catch (error) {\n problems.push(`destroy threw: ${error instanceof Error ? error.message : String(error)}`);\n }\n await page.waitForTimeout(Math.max(INVALID_STATUS_DELAY_MS, TOOLTIP_DELAY_MS) + HOVER_MARGIN_MS);\n await page.mouse.move(PARK.x, PARK.y);\n await page.setViewportSize({ width: size.width - 40, height: size.height - 40 });\n await settle(page);\n\n await inPage(page, injectProbe, { root, kind: \"focus-target\" });\n await inPage(page, clearKeysProbe, null);\n for (const key of [\"Control+Equal\", \"Control+Minus\", \"Control+Digit0\", \"Shift+Digit1\"]) {\n await page.keyboard.press(key);\n const { keys } = await inPage(page, afterPressProbe, { root });\n const problem = afterDestroyKeyProblem(key, keys);\n if (problem) problems.push(problem);\n }\n await inPage(page, removeInjectedProbe, null);\n problems.push(...leftoverProblems(await inPage(page, leftoverProbe, null), harness.host));\n return finish(\"cleanup\", harness.host, problems, []);\n },\n};\n\n/** The 0.1 cases, extended for the web column. */\nexport function createBaseCases(): ShellConformanceCase[] {\n return [geometryCase, ariaCase, keysCase, createCase, readOnlyCase, appearanceCase, cleanupCase];\n}\n\nexport function createCases(): ShellConformanceCase[] {\n return [...createBaseCases(), ...createWebCases()];\n}\n","import type { Appearance, ColorThemeSetting, ShellHost, Size, Theme, ToastStatus } from \"../core/index.js\";\nimport { createCases } from \"./cases.js\";\nimport type { PageLike } from \"./page.js\";\n\nexport interface OpenContext {\n /** The page's viewport, which is the modeler's container in an own document. */\n size: Size;\n /**\n * What the host requests before the modeler resolves it: in an IDE host the VS Code color theme\n * (`vsCodeStubSearch` hands it to a page with the VS Code stub). For an embedded host the kit\n * itself puts the foreign page's `<html>` in this mode once `open` resolved. In the web host the\n * system's preference without a stored choice: the kit emulates `prefers-color-scheme` and\n * `prefers-contrast` (`PageLike.emulateMedia`) before `open`, and `open` loads the page with an\n * empty `localStorage` entry `miragon.darstellung`.\n */\n requested: Appearance;\n}\n\n/**\n * How the kit makes the optional islands visible (`geometry`, `aria`) and puts the modeler into its\n * invalid-file state (`readOnly`).\n */\nexport interface ShowHooks<P extends PageLike = PageLike> {\n problems?: ((page: P) => Promise<void>) | undefined;\n status?: ((page: P) => Promise<void>) | undefined;\n legend?: ((page: P) => Promise<void>) | undefined;\n inspector?: ((page: P) => Promise<void>) | undefined;\n /**\n * Puts the modeler into its invalid-file state the way its host does (an invalid import): a\n * read-only canvas and the status box. The kit waits `INVALID_STATUS_DELAY_MS` afterwards.\n */\n invalid?: ((page: P) => Promise<void>) | undefined;\n /**\n * Web host: puts the page on its start screen, the way a fresh visit without a document shows\n * it (`shell.setEmptyState(true)`); `open` itself loads a document.\n */\n emptyState?: ((page: P) => Promise<void>) | undefined;\n /**\n * Web and embedded hosts: shows `toast` through the modeler's `shell.toast`, with\n * `{ label: toast.actionLabel, onSelect() {} }` as its action when `actionLabel` is given.\n */\n toast?: ((page: P, toast: ToastFixture) => Promise<void>) | undefined;\n}\n\n/** A toast the kit asks the `toast` hook to show (cases `toasts`, `geometry`). */\nexport interface ToastFixture {\n status: ToastStatus;\n text: string;\n actionLabel?: string | undefined;\n}\n\n/** A file the kit drops on the page (case `dropZone`), built in the page as `new File([text], name, { type })`. */\nexport interface DropFixture {\n name: string;\n type: string;\n text: string;\n}\n\nexport interface DropFixtures {\n /** A file `DropZoneOptions.accept` takes; dropping it on the start screen opens it (the card goes). */\n accepted: DropFixture;\n /** A file outside `accept`; dropping it opens nothing and shows a danger toast (or the modeler's `onReject`). */\n rejected?: DropFixture | undefined;\n /** `DropZoneOptions.multiple` of the modeler; default `false`, so a drag of two files is forbidden. */\n multiple?: boolean | undefined;\n}\n\n/**\n * A show hook by name: the islands `legend`, `inspector`, `problems`, `status`, the state\n * `invalid`, and in the web column `emptyState` and `toast`.\n */\nexport type ShowHook = keyof ShowHooks;\n\n/**\n * What a harness can lack: a show hook, the web app's drop zone (`drop`), or problems that point at\n * an element (`problemSelection`: the modeler's diagnostics only name lines, so no row selects).\n */\nexport type AbsentFeature = ShowHook | \"drop\" | \"problemSelection\";\n\nexport interface ShellConformanceHarness<P extends PageLike = PageLike> {\n host: ShellHost;\n /** The modes the modeler declares (static); the appearance case requests dark from `[\"light\"]`. */\n themes: readonly Theme[];\n /** Load the modeler with the shell at `size`, as the host would with `requested`; resolve once the first import is done. */\n open(page: P, context: OpenContext): Promise<void>;\n /** Tear modeler and shell down through the page's own path; `undefined` skips the cleanup case. */\n destroy?: ((page: P) => Promise<void>) | undefined;\n /** CSS selector of the shell root; default `.cd-shell`. */\n root?: string | undefined;\n /** Hooks for the islands and states the modeler has; one that is neither given nor `absent` is reported as skipped. */\n show?: ShowHooks<P> | undefined;\n /** Web host: the files the `dropZone` case drops; without them (and not `absent`) it is skipped with `hook: \"drop\"`. */\n drop?: DropFixtures | undefined;\n /**\n * The islands and states the modeler does not have. An absent hook is not reported as skipped,\n * and `geometry` and `aria` assert that its island is never visible. Listing a hook that `show`\n * also gives fails every case that uses it.\n */\n absent?: readonly AbsentFeature[] | undefined;\n /** Container sizes of the geometry case; default wide 1280 × 900, narrow 720 × 700, very narrow 420 × 700. */\n sizes?: readonly Size[] | undefined;\n}\n\n/** One part of a case the harness could not feed. */\nexport interface ShellSkip {\n /**\n * The harness field that would feed it: a show hook, `destroy`, or `open` when the document it\n * opens lacks what the case needs (a shape on the canvas).\n */\n hook: ShowHook | \"drop\" | \"destroy\" | \"open\";\n reason: string;\n}\n\nexport interface ShellCaseOutcome {\n /** What the case could not (fully) run, one entry per missing harness field. */\n skipped?: readonly ShellSkip[];\n}\n\nexport interface ShellConformanceCase {\n name: string;\n run<P extends PageLike>(page: P, harness: ShellConformanceHarness<P>): Promise<ShellCaseOutcome | void>;\n}\n\n/**\n * The cases: `geometry` (every `data-chrome` island ±1px, per host and breakpoint), `aria`\n * (roles, names, `aria-expanded`/`-controls`/`-keyshortcuts`/`-disabled`, DOM order, no positive\n * tabindex), `keys` (each chrome key acts exactly once; in the IDE host a `keydown` listener on\n * `window` never fires for a handled key; unmodified `+`/`-` never zoom; select all acts on the\n * canvas only), `create` (Enter on the first creating palette entry places one selected element in\n * the free rectangle and focuses the canvas), `readOnly` (the invalid-file lock of guide §13.5),\n * `appearance` (dark requested from a light-only modeler: nothing turns dark, `color-scheme` light\n * everywhere, the canvas surround and the palette's tool colours from the roles; the web app's mode\n * and its Appearance group) and `cleanup` (after `destroy` no shell element, class, attribute or\n * key handling remains); then the web column's `webChrome`, `emptyState`, `toasts`,\n * `problemsList` and `dropZone`, which assert in the other hosts that nothing of them shows.\n */\nexport function shellConformanceCases(): ShellConformanceCase[] {\n return createCases();\n}\n\n/** Playwright's `test` (or any runner whose body receives `{ page }`). */\nexport type ShellConformanceTest<P extends PageLike = PageLike> = (\n name: string,\n body: (fixtures: { page: P }) => Promise<void>,\n) => unknown;\n\nexport interface RegisterShellConformanceOptions {\n /** Default: `console.warn`, one line per case with its skips joined by \"; \". */\n onSkip?: ((caseName: string, skips: readonly ShellSkip[]) => void) | undefined;\n}\n\n/**\n * The query string for a test page that installs the VS Code stub of\n * `@miragon/modeler-shell/testing/vscode-stub` with `stubOptionsFromSearch(location.search)`:\n * `theme=dark&kontrast=hoch`, plus the `colorTheme` setting and VS Code's reduce motion.\n */\nexport function vsCodeStubSearch(\n requested: Appearance,\n extra: { colorTheme?: ColorThemeSetting | undefined; reduceMotion?: boolean | undefined } = {},\n): string {\n const query = new URLSearchParams({ theme: requested.theme });\n if (requested.kontrast) query.set(\"kontrast\", requested.kontrast);\n if (extra.colorTheme) query.set(\"colorTheme\", extra.colorTheme);\n if (extra.reduceMotion) query.set(\"reduceMotion\", \"\");\n return query.toString();\n}\n\n/** Registers every case as `shell conformance: <name>`. */\nexport function registerShellConformance<P extends PageLike>(\n harness: ShellConformanceHarness<P>,\n test: ShellConformanceTest<P>,\n options: RegisterShellConformanceOptions = {},\n): void {\n const onSkip =\n options.onSkip ??\n ((caseName: string, skips: readonly ShellSkip[]) => {\n console.warn(\n `@miragon/modeler-shell conformance: SKIPPED \"${caseName}\" (${harness.host} host): ${skips.map((skip) => skip.reason).join(\"; \")}`,\n );\n });\n for (const conformanceCase of shellConformanceCases()) {\n test(`shell conformance: ${conformanceCase.name}`, async ({ page }) => {\n const outcome = await conformanceCase.run(page, harness);\n if (outcome?.skipped && outcome.skipped.length > 0) onSkip(conformanceCase.name, outcome.skipped);\n });\n }\n}\n"],"mappings":"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","names":["name","name","startScreen","attribute","name","round","name","toasts","popover","normalize","pressed","prevented","name","round","shape","name","toasts","popover","row","target","name","facts","problems","focusTarget","opened","shape"]}