@jimka/typescript-ui 0.5.0 → 0.6.0
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.
- package/dist/lib/{AbstractInput-B10DfLOf.js → AbstractInput-sRNPzWel.js} +2 -2
- package/dist/lib/{AbstractInput-B10DfLOf.js.map → AbstractInput-sRNPzWel.js.map} +1 -1
- package/dist/lib/Anchor-CwRhdP2J.js +2 -0
- package/dist/lib/Anchor-CwRhdP2J.js.map +1 -0
- package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js +2 -0
- package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js.map +1 -0
- package/dist/lib/Border-0DJFDiij.js +2 -0
- package/dist/lib/Border-0DJFDiij.js.map +1 -0
- package/dist/lib/Button-MpMIYBYJ.js +2 -0
- package/dist/lib/Button-MpMIYBYJ.js.map +1 -0
- package/dist/lib/{Card-CD3jxshU.js → Card-QYo27r5b.js} +2 -2
- package/dist/lib/{Card-CD3jxshU.js.map → Card-QYo27r5b.js.map} +1 -1
- package/dist/lib/Checkbox-D0JYK-wc.js +2 -0
- package/dist/lib/Checkbox-D0JYK-wc.js.map +1 -0
- package/dist/lib/CheckboxMenuRow-CesLhSnp.js +2 -0
- package/dist/lib/CheckboxMenuRow-CesLhSnp.js.map +1 -0
- package/dist/lib/{CodeEditor-BGlB232h.js → CodeEditor-N1FQodcF.js} +2 -2
- package/dist/lib/CodeEditor-N1FQodcF.js.map +1 -0
- package/dist/lib/ComboBox-Dx8Tk9yg.js +2 -0
- package/dist/lib/ComboBox-Dx8Tk9yg.js.map +1 -0
- package/dist/lib/Component-B0ShfPVi.js +2 -0
- package/dist/lib/Component-B0ShfPVi.js.map +1 -0
- package/dist/lib/Container-abY5Ww3W.js +2 -0
- package/dist/lib/{Container-C7RPLQEc.js.map → Container-abY5Ww3W.js.map} +1 -1
- package/dist/lib/{DOM-Ba8YRVel.js → DOM-C-Edb3tA.js} +2 -2
- package/dist/lib/DOM-C-Edb3tA.js.map +1 -0
- package/dist/lib/Dialog-cbA9V17e.js +2 -0
- package/dist/lib/Dialog-cbA9V17e.js.map +1 -0
- package/dist/lib/{FieldDecorator-HG65hEtk.js → FieldDecorator-BlYMfZ9L.js} +2 -2
- package/dist/lib/{FieldDecorator-HG65hEtk.js.map → FieldDecorator-BlYMfZ9L.js.map} +1 -1
- package/dist/lib/{Fit-Cg3dPyZg.js → Fit-BhlB-HAo.js} +2 -2
- package/dist/lib/{Fit-Cg3dPyZg.js.map → Fit-BhlB-HAo.js.map} +1 -1
- package/dist/lib/{FloatingPanel-D5buuVrQ.js → FloatingPanel-DkJXsZ2D.js} +2 -2
- package/dist/lib/{FloatingPanel-D5buuVrQ.js.map → FloatingPanel-DkJXsZ2D.js.map} +1 -1
- package/dist/lib/{Glyph-DeJF_zsR.js → Glyph-_VeBacS2.js} +2 -2
- package/dist/lib/{Glyph-DeJF_zsR.js.map → Glyph-_VeBacS2.js.map} +1 -1
- package/dist/lib/{Grid-BYBohJIA.js → Grid-Daiz7F5d.js} +2 -2
- package/dist/lib/Grid-Daiz7F5d.js.map +1 -0
- package/dist/lib/GridConstraints-C58LuTqM.js +2 -0
- package/dist/lib/{GridConstraints-Bts284FI.js.map → GridConstraints-C58LuTqM.js.map} +1 -1
- package/dist/lib/{Header-BIFJK9nR.js → Header-Dql3Zxc6.js} +2 -2
- package/dist/lib/{Header-BIFJK9nR.js.map → Header-Dql3Zxc6.js.map} +1 -1
- package/dist/lib/{IconText-Dsb1xS-E.js → IconText-PUjhTLlp.js} +2 -2
- package/dist/lib/{IconText-Dsb1xS-E.js.map → IconText-PUjhTLlp.js.map} +1 -1
- package/dist/lib/LayoutSerialization-CMxunLfV.js +2 -0
- package/dist/lib/LayoutSerialization-CMxunLfV.js.map +1 -0
- package/dist/lib/List-nx8220Fi.js +2 -0
- package/dist/lib/{List-BPd-IXZR.js.map → List-nx8220Fi.js.map} +1 -1
- package/dist/lib/MemoryStore-DhPoU-7X.js +2 -0
- package/dist/lib/MemoryStore-DhPoU-7X.js.map +1 -0
- package/dist/lib/Menu-Q0bpXXze.js +2 -0
- package/dist/lib/Menu-Q0bpXXze.js.map +1 -0
- package/dist/lib/{MenuButton-BR4KOFld.js → MenuButton-DCXi0tsP.js} +2 -2
- package/dist/lib/{MenuButton-BR4KOFld.js.map → MenuButton-DCXi0tsP.js.map} +1 -1
- package/dist/lib/OverlayFade-3pof2AJH.js +2 -0
- package/dist/lib/OverlayFade-3pof2AJH.js.map +1 -0
- package/dist/lib/{Panel-CpNQTLNF.js → Panel-Cy1pdlWO.js} +2 -2
- package/dist/lib/{Panel-CpNQTLNF.js.map → Panel-Cy1pdlWO.js.map} +1 -1
- package/dist/lib/{Position-PBVBW1JS.js → Position-BwtxouxK.js} +2 -2
- package/dist/lib/{Position-PBVBW1JS.js.map → Position-BwtxouxK.js.map} +1 -1
- package/dist/lib/{ProgressSpinner-lAsK26C-.js → ProgressSpinner-DK8xEQ9y.js} +2 -2
- package/dist/lib/{ProgressSpinner-lAsK26C-.js.map → ProgressSpinner-DK8xEQ9y.js.map} +1 -1
- package/dist/lib/RadioButton-BEwpqg1k.js +2 -0
- package/dist/lib/{RadioButton-CCcIaL54.js.map → RadioButton-BEwpqg1k.js.map} +1 -1
- package/dist/lib/RadioMenuRow-DP5qPyFR.js +2 -0
- package/dist/lib/RadioMenuRow-DP5qPyFR.js.map +1 -0
- package/dist/lib/{RovingTabIndex-C2Vzq0IX.js → RovingTabIndex-pHEv5oLD.js} +2 -2
- package/dist/lib/{RovingTabIndex-C2Vzq0IX.js.map → RovingTabIndex-pHEv5oLD.js.map} +1 -1
- package/dist/lib/Scrollbar-t8fFrUVQ.js +2 -0
- package/dist/lib/Scrollbar-t8fFrUVQ.js.map +1 -0
- package/dist/lib/{Slider-DZ9drUxn.js → Slider-CTbwR6HR.js} +2 -2
- package/dist/lib/{Slider-DZ9drUxn.js.map → Slider-CTbwR6HR.js.map} +1 -1
- package/dist/lib/{Spacer-SDhOMp2g.js → Spacer-srdN2d2b.js} +2 -2
- package/dist/lib/{Spacer-SDhOMp2g.js.map → Spacer-srdN2d2b.js.map} +1 -1
- package/dist/lib/TabButton-DLoMQzky.js +2 -0
- package/dist/lib/TabButton-DLoMQzky.js.map +1 -0
- package/dist/lib/TabCloseButton-CY7BGitY.js +2 -0
- package/dist/lib/TabCloseButton-CY7BGitY.js.map +1 -0
- package/dist/lib/{Text-CdHf3B-1.js → Text-CMKnK9uB.js} +2 -2
- package/dist/lib/{Text-CdHf3B-1.js.map → Text-CMKnK9uB.js.map} +1 -1
- package/dist/lib/{Tooltip-B_UF5bXD.js → Tooltip-CUOJOqQi.js} +3 -3
- package/dist/lib/Tooltip-CUOJOqQi.js.map +1 -0
- package/dist/lib/Tree-C64JNPWJ.js +2 -0
- package/dist/lib/Tree-C64JNPWJ.js.map +1 -0
- package/dist/lib/VBox-DfJPWXqc.js +2 -0
- package/dist/lib/VBox-DfJPWXqc.js.map +1 -0
- package/dist/lib/VirtualScroller-DTIn19o1.js +2 -0
- package/dist/lib/VirtualScroller-DTIn19o1.js.map +1 -0
- package/dist/lib/assets/StoreWorker-B5NwRM2I.js +2 -0
- package/dist/lib/assets/StoreWorker-B5NwRM2I.js.map +1 -0
- package/dist/lib/component/button.es.js +1 -1
- package/dist/lib/component/button.es.js.map +1 -1
- package/dist/lib/component/chart.es.js +1 -1
- package/dist/lib/component/container.es.js +1 -1
- package/dist/lib/component/container.es.js.map +1 -1
- package/dist/lib/component/diagram.es.js +1 -1
- package/dist/lib/component/diagram.es.js.map +1 -1
- package/dist/lib/component/display.es.js +1 -1
- package/dist/lib/component/display.es.js.map +1 -1
- package/dist/lib/component/editor.es.js +2 -2
- package/dist/lib/component/editor.es.js.map +1 -1
- package/dist/lib/component/input.es.js +1 -1
- package/dist/lib/component/input.es.js.map +1 -1
- package/dist/lib/component/list.es.js +1 -1
- package/dist/lib/component/list.es.js.map +1 -1
- package/dist/lib/component/menubar.es.js +1 -1
- package/dist/lib/component/menubar.es.js.map +1 -1
- package/dist/lib/component/table.es.js +6 -3
- package/dist/lib/component/table.es.js.map +1 -1
- package/dist/lib/component/tree.es.js +1 -1
- package/dist/lib/core.es.js +1 -1
- package/dist/lib/core.es.js.map +1 -1
- package/dist/lib/data.es.js +1 -1
- package/dist/lib/glyphs/solid/index.es.js +1 -1
- package/dist/lib/layout.es.js +1 -1
- package/dist/lib/layout.es.js.map +1 -1
- package/dist/lib/overlay.es.js +1 -1
- package/dist/lib/overlay.es.js.map +1 -1
- package/dist/lib/primitive.es.js +1 -1
- package/dist/lib/router.es.js +1 -1
- package/dist/lib/router.es.js.map +1 -1
- package/dist/lib/selectionsEqual-gMG7gCVI.js +2 -0
- package/dist/lib/selectionsEqual-gMG7gCVI.js.map +1 -0
- package/dist/lib/types/component/button/Button.d.ts +13 -0
- package/dist/lib/types/component/button/MenuButton.d.ts +1 -0
- package/dist/lib/types/component/button/PopupButton.d.ts +22 -0
- package/dist/lib/types/component/button/TabButton.d.ts +4 -0
- package/dist/lib/types/component/button/index.d.ts +2 -0
- package/dist/lib/types/component/container/CheckboxMenuRow.d.ts +33 -0
- package/dist/lib/types/component/container/CollapseButton.d.ts +11 -3
- package/dist/lib/types/component/container/MenuItem.d.ts +15 -5
- package/dist/lib/types/component/container/MenuRow.d.ts +24 -0
- package/dist/lib/types/component/container/MenuSeparator.d.ts +4 -2
- package/dist/lib/types/component/container/RadioMenuRow.d.ts +33 -0
- package/dist/lib/types/component/container/Scrollbar.d.ts +5 -0
- package/dist/lib/types/component/container/SplitGutter.d.ts +7 -2
- package/dist/lib/types/component/container/TabBar.d.ts +2 -0
- package/dist/lib/types/component/container/WindowBorder.d.ts +1 -1
- package/dist/lib/types/component/container/index.d.ts +6 -1
- package/dist/lib/types/component/display/WebGLCanvas.d.ts +1 -0
- package/dist/lib/types/component/input/AbstractCalendarDropdown.d.ts +2 -0
- package/dist/lib/types/component/input/AbstractPickerField.d.ts +3 -2
- package/dist/lib/types/component/list/AbstractSelectableList.d.ts +1 -1
- package/dist/lib/types/component/list/MultiSelectList.d.ts +2 -1
- package/dist/lib/types/component/shared/VirtualRowView.d.ts +2 -0
- package/dist/lib/types/component/table/Body.d.ts +22 -1
- package/dist/lib/types/component/table/Column.d.ts +3 -1
- package/dist/lib/types/component/table/ColumnConfig.d.ts +2 -0
- package/dist/lib/types/component/table/ColumnFilter.d.ts +27 -0
- package/dist/lib/types/component/table/Header.d.ts +30 -3
- package/dist/lib/types/component/table/Row.d.ts +4 -0
- package/dist/lib/types/component/table/Table.d.ts +29 -0
- package/dist/lib/types/component/table/TableExporter.d.ts +4 -3
- package/dist/lib/types/component/table/TreeBody.d.ts +2 -1
- package/dist/lib/types/component/table/cell/CellText.d.ts +9 -0
- package/dist/lib/types/component/table/cell/Filter.d.ts +54 -0
- package/dist/lib/types/component/table/cell/FilterClauseBadge.d.ts +21 -0
- package/dist/lib/types/component/table/cell/GroupSeparator.d.ts +9 -0
- package/dist/lib/types/component/table/cell/Header.d.ts +1 -0
- package/dist/lib/types/component/table/cell/editor/CellEditor.d.ts +1 -0
- package/dist/lib/types/component/table/cell/renderer/CellRenderer.d.ts +1 -0
- package/dist/lib/types/component/table/cell/renderer/Combo.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Date.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/DateTime.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Filter.d.ts +16 -0
- package/dist/lib/types/component/table/cell/renderer/Glyph.d.ts +1 -0
- package/dist/lib/types/component/table/cell/renderer/Link.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Number.d.ts +3 -1
- package/dist/lib/types/component/table/cell/renderer/String.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/Time.d.ts +2 -0
- package/dist/lib/types/component/table/cell/renderer/TreeCell.d.ts +1 -0
- package/dist/lib/types/component/table/index.d.ts +6 -0
- package/dist/lib/types/component/tree/Tree.d.ts +17 -1
- package/dist/lib/types/component/tree/index.d.ts +1 -1
- package/dist/lib/types/core/AnimatedDropdown.d.ts +0 -9
- package/dist/lib/types/core/Body.d.ts +4 -0
- package/dist/lib/types/core/ClassStyleRules.d.ts +1 -0
- package/dist/lib/types/core/DOM.d.ts +10 -0
- package/dist/lib/types/core/Event.d.ts +11 -2
- package/dist/lib/types/core/OverlayFade.d.ts +12 -0
- package/dist/lib/types/core/OverlayPosition.d.ts +6 -0
- package/dist/lib/types/core/Theme.d.ts +8 -0
- package/dist/lib/types/core/index.d.ts +5 -3
- package/dist/lib/types/data/AbstractStore.d.ts +3 -0
- package/dist/lib/types/data/FilterDescriptor.d.ts +13 -0
- package/dist/lib/types/data/index.d.ts +2 -1
- package/dist/lib/types/data/temporalText.d.ts +2 -0
- package/dist/lib/types/layout/BoxLayout.d.ts +6 -1
- package/dist/lib/types/layout/Grid.d.ts +1 -0
- package/dist/lib/types/layout/HFlow.d.ts +1 -1
- package/dist/lib/types/layout/Split.d.ts +10 -1
- package/dist/lib/types/layout/Tab.d.ts +7 -1
- package/dist/lib/types/layout/VFlow.d.ts +1 -1
- package/dist/lib/types/layout/index.d.ts +1 -1
- package/dist/lib/types/overlay/Dock.d.ts +1 -0
- package/dist/lib/types/overlay/Menu.d.ts +1 -1
- package/dist/lib/types/overlay/Popover.d.ts +3 -0
- package/dist/lib/types/overlay/PopupPanel.d.ts +17 -0
- package/dist/lib/types/overlay/Window.d.ts +2 -0
- package/dist/lib/types/overlay/index.d.ts +2 -0
- package/dist/lib/types/router/RoutePattern.d.ts +7 -0
- package/dist/lib/types/router/Router.d.ts +6 -2
- package/dist/lib/types/router/index.d.ts +1 -1
- package/dist/lib/validation.es.js +1 -1
- package/llms.txt +4 -0
- package/package.json +1 -1
- package/dist/lib/AbstractBooleanInput-CbW7ZrDT.js +0 -2
- package/dist/lib/AbstractBooleanInput-CbW7ZrDT.js.map +0 -1
- package/dist/lib/Anchor-BsblS5it.js +0 -2
- package/dist/lib/Anchor-BsblS5it.js.map +0 -1
- package/dist/lib/AnimatedDropdown-kL47HPGP.js +0 -2
- package/dist/lib/AnimatedDropdown-kL47HPGP.js.map +0 -1
- package/dist/lib/Border-CNS6aEXB.js +0 -2
- package/dist/lib/Border-CNS6aEXB.js.map +0 -1
- package/dist/lib/Button-T16zSZip.js +0 -2
- package/dist/lib/Button-T16zSZip.js.map +0 -1
- package/dist/lib/CodeEditor-BGlB232h.js.map +0 -1
- package/dist/lib/ComboBox-C9FYMuLv.js +0 -2
- package/dist/lib/ComboBox-C9FYMuLv.js.map +0 -1
- package/dist/lib/Component-w65rPK75.js +0 -2
- package/dist/lib/Component-w65rPK75.js.map +0 -1
- package/dist/lib/Container-C7RPLQEc.js +0 -2
- package/dist/lib/DOM-Ba8YRVel.js.map +0 -1
- package/dist/lib/DragManager-UvPHSoRm.js +0 -2
- package/dist/lib/DragManager-UvPHSoRm.js.map +0 -1
- package/dist/lib/Grid-BYBohJIA.js.map +0 -1
- package/dist/lib/GridConstraints-Bts284FI.js +0 -2
- package/dist/lib/LayoutSerialization-ySzY1h2l.js +0 -2
- package/dist/lib/LayoutSerialization-ySzY1h2l.js.map +0 -1
- package/dist/lib/LayoutSizes-DKDK1Cle.js +0 -2
- package/dist/lib/LayoutSizes-DKDK1Cle.js.map +0 -1
- package/dist/lib/List-BPd-IXZR.js +0 -2
- package/dist/lib/MemoryStore-BgP7-Uzn.js +0 -2
- package/dist/lib/MemoryStore-BgP7-Uzn.js.map +0 -1
- package/dist/lib/Menu-C0roOCY7.js +0 -2
- package/dist/lib/Menu-C0roOCY7.js.map +0 -1
- package/dist/lib/RadioButton-CCcIaL54.js +0 -2
- package/dist/lib/Scrollbar-C3ZZyZ1e.js +0 -2
- package/dist/lib/Scrollbar-C3ZZyZ1e.js.map +0 -1
- package/dist/lib/TabButton-DNo4ZgV8.js +0 -2
- package/dist/lib/TabButton-DNo4ZgV8.js.map +0 -1
- package/dist/lib/Tooltip-B_UF5bXD.js.map +0 -1
- package/dist/lib/Tree-C7qLbIYH.js +0 -2
- package/dist/lib/Tree-C7qLbIYH.js.map +0 -1
- package/dist/lib/VBox-32fxpkDl.js +0 -2
- package/dist/lib/VBox-32fxpkDl.js.map +0 -1
- package/dist/lib/VirtualScroller-cvFNMS7U.js +0 -2
- package/dist/lib/VirtualScroller-cvFNMS7U.js.map +0 -1
- package/dist/lib/assets/StoreWorker-CgOBYoai.js +0 -2
- package/dist/lib/assets/StoreWorker-CgOBYoai.js.map +0 -1
- package/dist/lib/selectionsEqual-BrTxPMmK.js +0 -2
- package/dist/lib/selectionsEqual-BrTxPMmK.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Container-
|
|
1
|
+
{"version":3,"file":"Container-abY5Ww3W.js","names":[],"sources":["../../src/typescript/lib/core/Container.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component, ComponentOptions } from \"~/core/Component.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link Container}.\n *\n * Adds no fields over {@link ComponentOptions}; declared as a named extension\n * point so structural containers have a stable options type and so\n * {@link Panel}'s `PanelOptions` can extend it.\n *\n * @category Core\n */\nexport interface ContainerOptions extends ComponentOptions {}\n\n/**\n * A fit-parent {@link Component}: a container that fills the rect its parent's\n * layout manager allocates instead of shrinking to its content's size.\n *\n * `Component` already owns the container machinery — a layout manager, children,\n * insets, a child host. `Container`'s sole contribution is flipping the size\n * policy: it overrides `clampsToContentSize` to `false`, so its width and\n * height accept whatever the parent allocates and oversized content overflows\n * (clipped) rather than inflating the box back up to its content-derived\n * minimum. It keeps `Component`'s **zero** default insets and adds no scrolling.\n *\n * Use `Container` for structural regions that must fill their slot — a dock\n * `Split`/`Tab` region, an identity frame — without the perimeter padding or\n * native scrolling a content surface wants. For those, use\n * [`Panel`](/api/core/classes/Panel), which is a `Container` that adds a default\n * 4-pixel inset and an `autoScroll` stack on top.\n *\n * @category Core\n */\nclass Container<TOptions extends ContainerOptions = ContainerOptions> extends Component<TOptions> {\n\n /**\n * Overrides {@link Component.clampsToContentSize} to `false`: a container\n * fits whatever space its parent's layout manager allocates rather than\n * inflating up to its content-derived minimum. Oversized children clip (a\n * `Container` adds no scrolling — use [`Panel`](/api/core/classes/Panel) for\n * that). Only an explicit {@link Component.setMinSize} /\n * {@link Component.setMaxSize} remains a hard floor or ceiling.\n *\n * @returns `false`, so size clamping uses the container's own explicit\n * constraints only, not its content-derived ones.\n */\n protected clampsToContentSize(): boolean {\n return false;\n }\n}\n\nconst ContainerCallable = callable(Container);\ntype ContainerCallable<TOptions extends ContainerOptions = ContainerOptions> = Container<TOptions>;\nexport {\n Container as _Container,\n ContainerCallable as Container,\n};\n"],"mappings":"8CAmCA,IAAM,UAAN,cAA8E,CAAoB,CAa9F,qBAAyC,CACrC,MAAO,EACX,CACJ,EAEM,EAAoB,EAAS,SAAS"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=null,t=-1;function _applyProbeStyles(e,t){for(let n of Object.keys(t))e.style[n]=t[n]}var HandleRegistry=class{_forward=new Map;_reverse=new WeakMap;_next=1;_finalizer=new FinalizationRegistry(e=>{this._forward.delete(e)});retain(e){let t=this._reverse.get(e);if(t!==void 0)return t;let n=this._mint(e);return this._forward.set(n,e),n}intern(e){let t=this._reverse.get(e);if(t!==void 0)return t;let n=this._mint(e);return this._forward.set(n,new WeakRef(e)),this._finalizer.register(e,n),n}resolve(e){let t=this._forward.get(e);if(t===void 0)throw Error(`DOM handle ${e} is not registered (released or never minted).`);let n=t instanceof WeakRef?t.deref():t;if(n===void 0)throw Error(`DOM handle ${e} refers to a collected node.`);return n}release(e){let t=this._forward.get(e);if(t===void 0)return;let n=t instanceof WeakRef?t.deref():t;n&&this._reverse.delete(n),this._forward.delete(e)}get size(){return this._forward.size}_mint(e){let t=this._next;return this._next+=1,this._reverse.set(e,t),t}},n=new HandleRegistry;function writeDeclaration(e,t,n){t.includes(`-`)?n===null?e.removeProperty(t):e.setProperty(t,n):e[t]=n===null?``:n}var r=null;function scratchDeclaration(){return typeof document>`u`?null:r??=document.createElement(`div`).style}function applyPatchTo(e,t){if(t.style)for(let n of Object.keys(t.style))writeDeclaration(e.style,n,t.style[n]);if(t.removeClass)for(let n of t.removeClass)e.classList.remove(n);if(t.addClass)for(let n of t.addClass)n&&e.classList.add(n);if(t.toggleClass)for(let n of Object.keys(t.toggleClass))e.classList.toggle(n,t.toggleClass[n]);if(t.removeAttr)for(let n of t.removeAttr)e.removeAttribute(n);if(t.setAttr)for(let n of Object.keys(t.setAttr))e.setAttribute(n,t.setAttr[n]);if(t.dataset)for(let n of Object.keys(t.dataset))e.dataset[n]=t.dataset[n];t.text!==void 0&&(e.textContent=t.text),t.scrollLeft!==void 0&&(e.scrollLeft=t.scrollLeft),t.scrollTop!==void 0&&(e.scrollTop=t.scrollTop)}var PatchBuilder=class{_commit;_patch={};constructor(e){this._commit=e}style(e,t){return(this._patch.style??={})[e]=t,this}addClass(e){return(this._patch.addClass??=[]).push(e),this}attr(e,t){return(this._patch.setAttr??={})[e]=t,this}text(e){return this._patch.text=e,this}commit(){this._commit(this._patch)}};function toRect(e){return{x:e.x,y:e.y,width:e.width,height:e.height,top:e.top,left:e.left,right:e.right,bottom:e.bottom}}var ProductionDOMSink=class{_timers=new Set;_ruleIndex=new Map;_indexedSheet=null;apply(e,t){applyPatchTo(n.resolve(e),t)}edit(e){return new PatchBuilder(t=>this.apply(e,t))}release(e){n.release(e)}setRuleStyles(e,t){let n=Object.keys(t);if(n.length===0)return;let r=n.length===1?null:scratchDeclaration();if(!r){for(let r of n)writeDeclaration(e.style,r,t[r]);return}r.cssText=e.style.cssText;for(let e of n)writeDeclaration(r,e,t[e]);e.style.cssText=r.cssText}ensureStyleRule(e){let t=this.mainSheet(),n=this.ruleIndex(t),r=n.get(e);if(r)return r;let i=t.insertRule(e+`{}`,t.cssRules.length),a=t.cssRules[i];return n.set(e,a),a}deleteStyleRule(e){if(typeof document>`u`)return;let t=this.mainSheet(),n=this.ruleIndex(t),r=n.get(e);if(r){n.delete(e);for(let e=0;e<t.cssRules.length;e+=1)if(t.cssRules[e]===r){t.deleteRule(e);return}}}ensureKeyframes(e,t){let n=this.mainSheet();for(let t=0;t<n.cssRules.length;t+=1){let r=n.cssRules[t];if(r.type===CSSRule.KEYFRAMES_RULE&&r.name===e)return}n.insertRule(`@keyframes `+e+` { `+t+` }`,n.cssRules.length)}ruleIndex(e){if(this._indexedSheet===e)return this._ruleIndex;let t=new Map;for(let n=0;n<e.cssRules.length;n+=1){let r=e.cssRules[n];r.type===CSSRule.STYLE_RULE&&t.set(r.selectorText,r)}return this._ruleIndex=t,this._indexedSheet=e,t}mainSheet(){let e=document.getElementsByTagName(`head`)[0];e||(e=document.createElement(`head`),document.appendChild(e));let t=null,n=e.getElementsByTagName(`style`);for(let e=0;e<n.length;e+=1)n[e].id===`Base`&&(t=n[e]);return t||(t=document.createElement(`style`),t.id=`Base`,e.appendChild(t)),t.sheet}createElement(e){return n.retain(document.createElement(e))}createElementNS(e,t){return n.retain(document.createElementNS(e,t))}appendChild(e,t){n.resolve(e).appendChild(n.resolve(t))}removeChild(e,t){n.resolve(e).removeChild(n.resolve(t))}removeElement(e){n.resolve(e).remove()}focus(e,t){n.resolve(e).focus(t)}requestSubmit(e){n.resolve(e).requestSubmit()}blur(e){n.resolve(e).blur()}setValue(e,t){n.resolve(e).value=t}setSelectionRange(e,t,r){n.resolve(e).setSelectionRange(t,r)}setLocationHash(e){location.hash=e}replaceLocationHash(e){let t=location.href,n=t.indexOf(`#`),r=n===-1?t:t.slice(0,n);location.replace(r+e)}pushHistoryPath(e){history.pushState(null,``,e)}replaceHistoryPath(e){history.replaceState(null,``,e)}addListener(e,t,r,i){n.resolve(e).addEventListener(t,r,i)}removeListener(e,t,r,i){n.resolve(e).removeEventListener(t,r,i)}dispatchEvent(e,t){n.resolve(e).dispatchEvent(t)}dispatchCustomEvent(e,t,r){n.resolve(e).dispatchEvent(new CustomEvent(t,r))}requestAnimationFrame(e){return requestAnimationFrame(e)}cancelAnimationFrame(e){cancelAnimationFrame(e)}setTimeout(e,t){let n=setTimeout(()=>{this._timers.delete(n),e()},t);return this._timers.add(n),n}clearTimeout(e){this._timers.delete(e),clearTimeout(e)}clearAllTimeouts(){for(let e of this._timers)clearTimeout(e);this._timers.clear()}setId(e,t){n.resolve(e).id=t}insertBefore(e,t,r){n.resolve(e).insertBefore(n.resolve(t),r===null?null:n.resolve(r))}createDocumentFragment(){return n.retain(document.createDocumentFragment())}click(e){n.resolve(e).click()}setPointerCapture(e,t){n.resolve(e).setPointerCapture(t)}releasePointerCapture(e,t){n.resolve(e).releasePointerCapture(t)}getContext(e,t,r){return n.resolve(e).getContext(t,r)}mountView(e,t){return t(n.resolve(e))}mediaPlay(e){n.resolve(e).play().catch(()=>{})}mediaPause(e){n.resolve(e).pause()}setCurrentTime(e,t){n.resolve(e).currentTime=t}setVolume(e,t){n.resolve(e).volume=t}setMuted(e,t){n.resolve(e).muted=t}setPlaybackRate(e,t){n.resolve(e).playbackRate=t}requestFullscreen(e){n.resolve(e).requestFullscreen().catch(()=>{})}exitFullscreen(){document.fullscreenElement&&document.exitFullscreen().catch(()=>{})}},ProductionDOMSource=class{intern(e){return n.intern(e)}isNode(e){return e instanceof Node}isElement(e){return e instanceof Element}escapeSelector(e){return typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(e):e.replace(/[^\w-]/g,e=>`\\`+e)}getViewportRect(e){return toRect(n.resolve(e.getElement()).getBoundingClientRect())}getElementRect(e){return toRect(n.resolve(e).getBoundingClientRect())}measureText(e,t={}){let{fontFamily:n=`var(--ts-ui-font-family, system-ui, sans-serif)`,fontSize:r=`var(--ts-ui-font-size, 14px)`,fontWeight:i=`normal`,fontStyle:a=`normal`,fontVariant:o=`normal`,fontStretch:s=`normal`,lineHeight:c=`calc(1em + var(--ts-ui-line-padding, 2px))`,maxWidth:l}=t,u=document.createElement(`span`);_applyProbeStyles(u,{position:`fixed`,visibility:`hidden`,whiteSpace:l===void 0?`nowrap`:`pre-wrap`,width:l===void 0?``:`${l}px`,fontFamily:n,fontSize:r,fontWeight:i,fontStyle:a,fontVariant:o,fontStretch:s,lineHeight:c}),u.textContent=e;let d=document.createElement(`span`);_applyProbeStyles(d,{display:`inline-block`,width:`0`,height:`0`,verticalAlign:`baseline`}),u.appendChild(d),document.body.appendChild(u);let f=u.getBoundingClientRect(),p=d.getBoundingClientRect();return document.body.removeChild(u),{width:Math.ceil(f.width),height:Math.ceil(f.height),baseline:Math.round(p.top-f.top)}}measureTextWidths(e,t={}){if(e.length===0)return[];let{fontFamily:n=`var(--ts-ui-font-family, system-ui, sans-serif)`,fontSize:r=`var(--ts-ui-font-size, 14px)`,fontWeight:i=`normal`,fontStyle:a=`normal`,fontVariant:o=`normal`,fontStretch:s=`normal`}=t,c=document.createElement(`div`);_applyProbeStyles(c,{position:`fixed`,visibility:`hidden`,whiteSpace:`nowrap`});let l=e.map(e=>{let t=document.createElement(`span`);return _applyProbeStyles(t,{display:`inline-block`,whiteSpace:`nowrap`,fontFamily:n,fontSize:r,fontWeight:i,fontStyle:a,fontVariant:o,fontStretch:s}),t.textContent=e,c.appendChild(t),t});document.body.appendChild(c);let u=l.map(e=>Math.ceil(e.getBoundingClientRect().width));return document.body.removeChild(c),u}resolveFontSizePx(e){let t=document.createElement(`span`);_applyProbeStyles(t,{position:`fixed`,visibility:`hidden`,fontSize:e}),document.body.appendChild(t);let n=parseFloat(getComputedStyle(t).fontSize);return document.body.removeChild(t),isNaN(n)?14:n}measureFontMetrics(){e===null&&(e=document.createElement(`canvas`).getContext(`2d`));let t=e,n=this.getThemeVar(`--ts-ui-font-family`)||`system-ui, sans-serif`;t.font=`normal normal ${this.getThemeVar(`--ts-ui-font-size`)||`14px`} ${n}`;let r=t.measureText(`X`),i=typeof r.fontBoundingBoxAscent==`number`;return{ascent:i?r.fontBoundingBoxAscent:r.actualBoundingBoxAscent,descent:i?r.fontBoundingBoxDescent:r.actualBoundingBoxDescent,capTop:r.actualBoundingBoxAscent}}getThemeVar(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}getViewportSize(){return{width:Math.max(document.documentElement.clientWidth,window.innerWidth||0),height:Math.max(document.documentElement.clientHeight,window.innerHeight||0)}}getScrollBarWidth(){if(t>=0)return t;let e=document.createElement(`div`);_applyProbeStyles(e,{position:`absolute`,top:`-1000px`,left:`-1000px`,width:`100px`,height:`50px`,overflow:`hidden`});let n=document.createElement(`div`);_applyProbeStyles(n,{width:`100%`,height:`200px`}),e.appendChild(n),document.body.appendChild(e);let r=n.offsetWidth;_applyProbeStyles(e,{overflow:`auto`});let i=n.offsetWidth;return document.body.removeChild(e),t=r-i,t}getDevicePixelRatio(){return window.devicePixelRatio||1}isModelled(){return!1}getScrollLeft(e){return n.resolve(e).scrollLeft}getScrollTop(e){return n.resolve(e).scrollTop}getScrollMetrics(e){let t=n.resolve(e);return{scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,scrollWidth:t.scrollWidth,scrollHeight:t.scrollHeight,clientWidth:t.clientWidth,clientHeight:t.clientHeight}}getOffsetSize(e){let t=n.resolve(e);return{offsetTop:t.offsetTop,offsetHeight:t.offsetHeight}}isConnected(e){return n.resolve(e).isConnected}getValue(e){return n.resolve(e).value}getActiveElement(){let e=document.activeElement;return e===null?null:n.intern(e)}matchMedia(e){if(typeof matchMedia!=`function`)return{matches:!1,addChangeListener:()=>{}};let t=matchMedia(e);return{matches:t.matches,addChangeListener(e){t.addEventListener(`change`,e)}}}isWindow(e){return e!==null&&n.resolve(e)===window}getWindow(){return n.intern(window)}getLocationHash(){return location.hash}getLocationPathname(){return location.pathname}contains(e,t){return n.resolve(e).contains(t===null?null:n.resolve(t))}querySelector(e,t){let r=n.resolve(e).querySelector(t);return r===null?null:n.intern(r)}querySelectorAll(e,t){return Array.from(n.resolve(e).querySelectorAll(t),e=>n.intern(e))}matches(e,t){return n.resolve(e).matches(t)}getParentElement(e){let t=n.resolve(e).parentElement;return t===null?null:n.intern(t)}getParentNode(e){let t=n.resolve(e).parentNode;return t===null?null:n.intern(t)}getFirstChild(e){let t=n.resolve(e).firstChild;return t===null?null:n.intern(t)}getBorderWidths(e){let t=getComputedStyle(n.resolve(e));return{top:t.borderTopWidth,right:t.borderRightWidth,bottom:t.borderBottomWidth,left:t.borderLeftWidth}}getComputedOverflow(e){let t=getComputedStyle(n.resolve(e));return{overflow:t.overflow,overflowX:t.overflowX,overflowY:t.overflowY}}getInlineStyle(e,t){let r=n.resolve(e).style;return t.includes(`-`)?r.getPropertyValue(t):r[t]}getDocumentElement(){return n.intern(document.documentElement)}getBody(){return n.intern(document.body)}getHead(){return n.intern(document.head)}onFontsReady(e){let t=document.fonts;t&&t.addEventListener(`loadingdone`,()=>e())}startFontLoad(e){let t=document.fonts;return t?(t.load(`14px "${e}"`).catch(()=>{}),!0):!1}getElementById(e){let t=document.getElementById(e);return t===null?null:n.intern(t)}getId(e){return n.resolve(e).id}getDataset(e,t){return n.resolve(e).dataset[t]}getTagName(e){return n.resolve(e).tagName}hasAttribute(e,t){return n.resolve(e).hasAttribute(t)}getAttribute(e,t){return n.resolve(e).getAttribute(t)}getNaturalSize(e){let t=n.resolve(e);return{width:t.naturalWidth,height:t.naturalHeight}}getMediaState(e){let t=n.resolve(e);return{currentTime:t.currentTime,duration:t.duration,paused:t.paused,ended:t.ended,volume:t.volume,muted:t.muted,playbackRate:t.playbackRate}}getFullscreenElement(){let e=document.fullscreenElement;return e?n.intern(e):null}getFiles(e){return n.resolve(e).files}hasPointerCapture(e,t){return n.resolve(e).hasPointerCapture(t)}elementsFromPoint(e,t){return Array.from(document.elementsFromPoint(e,t),e=>n.intern(e))}},i={sink:new ProductionDOMSink,source:new ProductionDOMSource,install(e){e.sink&&(i.sink=e.sink),e.source&&(i.source=e.source)},reset(){i.sink.clearAllTimeouts(),n=new HandleRegistry,i.sink=new ProductionDOMSink,i.source=new ProductionDOMSource}};export{ProductionDOMSource as i,PatchBuilder as n,ProductionDOMSink as r,i as t};
|
|
2
|
-
//# sourceMappingURL=DOM-
|
|
1
|
+
var e=null,t=-1;function _applyProbeStyles(e,t){for(let n of Object.keys(t))e.style[n]=t[n]}var HandleRegistry=class{_forward=new Map;_reverse=new WeakMap;_next=1;_finalizer=new FinalizationRegistry(e=>{this._forward.delete(e)});retain(e){let t=this._reverse.get(e);if(t!==void 0)return t;let n=this._mint(e);return this._forward.set(n,e),n}intern(e){let t=this._reverse.get(e);if(t!==void 0)return t;let n=this._mint(e);return this._forward.set(n,new WeakRef(e)),this._finalizer.register(e,n),n}resolve(e){let t=this._forward.get(e);if(t===void 0)throw Error(`DOM handle ${e} is not registered (released or never minted).`);let n=t instanceof WeakRef?t.deref():t;if(n===void 0)throw Error(`DOM handle ${e} refers to a collected node.`);return n}release(e){let t=this._forward.get(e);if(t===void 0)return;let n=t instanceof WeakRef?t.deref():t;n&&this._reverse.delete(n),this._forward.delete(e)}get size(){return this._forward.size}_mint(e){let t=this._next;return this._next+=1,this._reverse.set(e,t),t}},n=new HandleRegistry;function writeDeclaration(e,t,n){t.includes(`-`)?n===null?e.removeProperty(t):e.setProperty(t,n):e[t]=n===null?``:n}var r=null;function scratchDeclaration(){return typeof document>`u`?null:r??=document.createElement(`div`).style}function applyPatchTo(e,t){if(t.style)for(let n of Object.keys(t.style))writeDeclaration(e.style,n,t.style[n]);if(t.removeClass)for(let n of t.removeClass)e.classList.remove(n);if(t.addClass)for(let n of t.addClass)n&&e.classList.add(n);if(t.toggleClass)for(let n of Object.keys(t.toggleClass))e.classList.toggle(n,t.toggleClass[n]);if(t.removeAttr)for(let n of t.removeAttr)e.removeAttribute(n);if(t.setAttr)for(let n of Object.keys(t.setAttr))e.setAttribute(n,t.setAttr[n]);if(t.dataset)for(let n of Object.keys(t.dataset))e.dataset[n]=t.dataset[n];t.text!==void 0&&(e.textContent=t.text),t.scrollLeft!==void 0&&(e.scrollLeft=t.scrollLeft),t.scrollTop!==void 0&&(e.scrollTop=t.scrollTop)}var PatchBuilder=class{_commit;_patch={};constructor(e){this._commit=e}style(e,t){return(this._patch.style??={})[e]=t,this}addClass(e){return(this._patch.addClass??=[]).push(e),this}attr(e,t){return(this._patch.setAttr??={})[e]=t,this}text(e){return this._patch.text=e,this}commit(){this._commit(this._patch)}};function toRect(e){return{x:e.x,y:e.y,width:e.width,height:e.height,top:e.top,left:e.left,right:e.right,bottom:e.bottom}}var ProductionDOMSink=class{_timers=new Set;_ruleIndex=new Map;_indexedSheet=null;apply(e,t){applyPatchTo(n.resolve(e),t)}edit(e){return new PatchBuilder(t=>this.apply(e,t))}release(e){n.release(e)}setRuleStyles(e,t){let n=Object.keys(t);if(n.length===0)return;let r=n.length===1?null:scratchDeclaration();if(!r){for(let r of n)writeDeclaration(e.style,r,t[r]);return}r.cssText=e.style.cssText;for(let e of n)writeDeclaration(r,e,t[e]);e.style.cssText=r.cssText}ensureStyleRule(e){let t=this.mainSheet(),n=this.ruleIndex(t),r=n.get(e);if(r)return r;let i=t.insertRule(e+`{}`,t.cssRules.length),a=t.cssRules[i];return n.set(e,a),a}deleteStyleRule(e){if(typeof document>`u`)return;let t=this.mainSheet(),n=this.ruleIndex(t),r=n.get(e);if(r){n.delete(e);for(let e=0;e<t.cssRules.length;e+=1)if(t.cssRules[e]===r){t.deleteRule(e);return}}}ensureKeyframes(e,t){let n=this.mainSheet();for(let t=0;t<n.cssRules.length;t+=1){let r=n.cssRules[t];if(r.type===CSSRule.KEYFRAMES_RULE&&r.name===e)return}n.insertRule(`@keyframes `+e+` { `+t+` }`,n.cssRules.length)}ruleIndex(e){if(this._indexedSheet===e)return this._ruleIndex;let t=new Map;for(let n=0;n<e.cssRules.length;n+=1){let r=e.cssRules[n];r.type===CSSRule.STYLE_RULE&&t.set(r.selectorText,r)}return this._ruleIndex=t,this._indexedSheet=e,t}mainSheet(){let e=document.getElementsByTagName(`head`)[0];e||(e=document.createElement(`head`),document.appendChild(e));let t=null,n=e.getElementsByTagName(`style`);for(let e=0;e<n.length;e+=1)n[e].id===`Base`&&(t=n[e]);return t||(t=document.createElement(`style`),t.id=`Base`,e.appendChild(t)),t.sheet}createElement(e){return n.retain(document.createElement(e))}createElementNS(e,t){return n.retain(document.createElementNS(e,t))}appendChild(e,t){n.resolve(e).appendChild(n.resolve(t))}removeChild(e,t){n.resolve(e).removeChild(n.resolve(t))}removeElement(e){n.resolve(e).remove()}focus(e,t){n.resolve(e).focus(t)}requestSubmit(e){n.resolve(e).requestSubmit()}blur(e){n.resolve(e).blur()}setValue(e,t){n.resolve(e).value=t}setSelectionRange(e,t,r){n.resolve(e).setSelectionRange(t,r)}setLocationHash(e){location.hash=e}replaceLocationHash(e){let t=location.href,n=t.indexOf(`#`),r=n===-1?t:t.slice(0,n);location.replace(r+e)}pushHistoryPath(e){history.pushState(null,``,e)}replaceHistoryPath(e){history.replaceState(null,``,e)}addListener(e,t,r,i){n.resolve(e).addEventListener(t,r,i)}removeListener(e,t,r,i){n.resolve(e).removeEventListener(t,r,i)}dispatchEvent(e,t){n.resolve(e).dispatchEvent(t)}dispatchCustomEvent(e,t,r){n.resolve(e).dispatchEvent(new CustomEvent(t,r))}requestAnimationFrame(e){return requestAnimationFrame(e)}cancelAnimationFrame(e){cancelAnimationFrame(e)}setTimeout(e,t){let n=setTimeout(()=>{this._timers.delete(n),e()},t);return this._timers.add(n),n}clearTimeout(e){this._timers.delete(e),clearTimeout(e)}clearAllTimeouts(){for(let e of this._timers)clearTimeout(e);this._timers.clear()}setId(e,t){n.resolve(e).id=t}insertBefore(e,t,r){n.resolve(e).insertBefore(n.resolve(t),r===null?null:n.resolve(r))}createDocumentFragment(){return n.retain(document.createDocumentFragment())}click(e){n.resolve(e).click()}setPointerCapture(e,t){n.resolve(e).setPointerCapture(t)}releasePointerCapture(e,t){n.resolve(e).releasePointerCapture(t)}getContext(e,t,r){return n.resolve(e).getContext(t,r)}mountView(e,t){return t(n.resolve(e))}mediaPlay(e){n.resolve(e).play().catch(()=>{})}mediaPause(e){n.resolve(e).pause()}setCurrentTime(e,t){n.resolve(e).currentTime=t}setVolume(e,t){n.resolve(e).volume=t}setMuted(e,t){n.resolve(e).muted=t}setPlaybackRate(e,t){n.resolve(e).playbackRate=t}requestFullscreen(e){n.resolve(e).requestFullscreen().catch(()=>{})}exitFullscreen(){document.fullscreenElement&&document.exitFullscreen().catch(()=>{})}},ProductionDOMSource=class{intern(e){return n.intern(e)}isNode(e){return e instanceof Node}isElement(e){return e instanceof Element}escapeSelector(e){return typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(e):e.replace(/[^\w-]/g,e=>`\\`+e)}getViewportRect(e){return toRect(n.resolve(e.getElement()).getBoundingClientRect())}getElementRect(e){return toRect(n.resolve(e).getBoundingClientRect())}measureText(e,t={}){let{fontFamily:n=`var(--ts-ui-font-family, system-ui, sans-serif)`,fontSize:r=`var(--ts-ui-font-size, 14px)`,fontWeight:i=`normal`,fontStyle:a=`normal`,fontVariant:o=`normal`,fontStretch:s=`normal`,lineHeight:c=`calc(1em + var(--ts-ui-line-padding, 2px))`,maxWidth:l}=t,u=document.createElement(`span`);_applyProbeStyles(u,{position:`fixed`,visibility:`hidden`,whiteSpace:l===void 0?`nowrap`:`pre-wrap`,width:l===void 0?``:`${l}px`,fontFamily:n,fontSize:r,fontWeight:i,fontStyle:a,fontVariant:o,fontStretch:s,lineHeight:c}),u.textContent=e;let d=document.createElement(`span`);_applyProbeStyles(d,{display:`inline-block`,width:`0`,height:`0`,verticalAlign:`baseline`}),u.appendChild(d),document.body.appendChild(u);let f=u.getBoundingClientRect(),p=d.getBoundingClientRect();return document.body.removeChild(u),{width:Math.ceil(f.width),height:Math.ceil(f.height),baseline:Math.round(p.top-f.top)}}measureTextWidths(e,t={}){if(e.length===0)return[];let{fontFamily:n=`var(--ts-ui-font-family, system-ui, sans-serif)`,fontSize:r=`var(--ts-ui-font-size, 14px)`,fontWeight:i=`normal`,fontStyle:a=`normal`,fontVariant:o=`normal`,fontStretch:s=`normal`}=t,c=document.createElement(`div`);_applyProbeStyles(c,{position:`fixed`,visibility:`hidden`,whiteSpace:`nowrap`});let l=e.map(e=>{let t=document.createElement(`span`);return _applyProbeStyles(t,{display:`inline-block`,whiteSpace:`nowrap`,fontFamily:n,fontSize:r,fontWeight:i,fontStyle:a,fontVariant:o,fontStretch:s}),t.textContent=e,c.appendChild(t),t});document.body.appendChild(c);let u=l.map(e=>Math.ceil(e.getBoundingClientRect().width));return document.body.removeChild(c),u}resolveFontSizePx(e){let t=document.createElement(`span`);_applyProbeStyles(t,{position:`fixed`,visibility:`hidden`,fontSize:e}),document.body.appendChild(t);let n=parseFloat(getComputedStyle(t).fontSize);return document.body.removeChild(t),isNaN(n)?14:n}measureFontMetrics(){e===null&&(e=document.createElement(`canvas`).getContext(`2d`));let t=e,n=this.getThemeVar(`--ts-ui-font-family`)||`system-ui, sans-serif`;t.font=`normal normal ${this.getThemeVar(`--ts-ui-font-size`)||`14px`} ${n}`;let r=t.measureText(`X`),i=typeof r.fontBoundingBoxAscent==`number`;return{ascent:i?r.fontBoundingBoxAscent:r.actualBoundingBoxAscent,descent:i?r.fontBoundingBoxDescent:r.actualBoundingBoxDescent,capTop:r.actualBoundingBoxAscent}}getThemeVar(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}getViewportSize(){return{width:Math.max(document.documentElement.clientWidth,window.innerWidth||0),height:Math.max(document.documentElement.clientHeight,window.innerHeight||0)}}getScrollBarWidth(){if(t>=0)return t;let e=document.createElement(`div`);_applyProbeStyles(e,{position:`absolute`,top:`-1000px`,left:`-1000px`,width:`100px`,height:`50px`,overflow:`hidden`});let n=document.createElement(`div`);_applyProbeStyles(n,{width:`100%`,height:`200px`}),e.appendChild(n),document.body.appendChild(e);let r=n.offsetWidth;_applyProbeStyles(e,{overflow:`auto`});let i=n.offsetWidth;return document.body.removeChild(e),t=r-i,t}getDevicePixelRatio(){return window.devicePixelRatio||1}isModelled(){return!1}getScrollLeft(e){return n.resolve(e).scrollLeft}getScrollTop(e){return n.resolve(e).scrollTop}getScrollMetrics(e){let t=n.resolve(e);return{scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,scrollWidth:t.scrollWidth,scrollHeight:t.scrollHeight,clientWidth:t.clientWidth,clientHeight:t.clientHeight}}getOffsetSize(e){let t=n.resolve(e);return{offsetTop:t.offsetTop,offsetHeight:t.offsetHeight}}isConnected(e){return n.resolve(e).isConnected}getValue(e){return n.resolve(e).value}getActiveElement(){let e=document.activeElement;return e===null?null:n.intern(e)}getDocumentSelection(){let e=window.getSelection();if(!e||e.isCollapsed||e.rangeCount===0)return null;let t=e.getRangeAt(0),r=t.startContainer.nodeType===Node.TEXT_NODE,i=t.endContainer.nodeType===Node.TEXT_NODE;return{startContainer:n.intern(t.startContainer),startOffset:r?t.startOffset:null,endContainer:n.intern(t.endContainer),endOffset:i?t.endOffset:null}}matchMedia(e){if(typeof matchMedia!=`function`)return{matches:!1,addChangeListener:()=>{}};let t=matchMedia(e);return{matches:t.matches,addChangeListener(e){t.addEventListener(`change`,e)}}}isWindow(e){return e!==null&&n.resolve(e)===window}getWindow(){return n.intern(window)}getLocationHash(){return location.hash}getLocationPathname(){return location.pathname}getLocationSearch(){return location.search}contains(e,t){return n.resolve(e).contains(t===null?null:n.resolve(t))}querySelector(e,t){let r=n.resolve(e).querySelector(t);return r===null?null:n.intern(r)}querySelectorAll(e,t){return Array.from(n.resolve(e).querySelectorAll(t),e=>n.intern(e))}matches(e,t){return n.resolve(e).matches(t)}getParentElement(e){let t=n.resolve(e).parentElement;return t===null?null:n.intern(t)}getParentNode(e){let t=n.resolve(e).parentNode;return t===null?null:n.intern(t)}getFirstChild(e){let t=n.resolve(e).firstChild;return t===null?null:n.intern(t)}getBorderWidths(e){let t=getComputedStyle(n.resolve(e));return{top:t.borderTopWidth,right:t.borderRightWidth,bottom:t.borderBottomWidth,left:t.borderLeftWidth}}getComputedOverflow(e){let t=getComputedStyle(n.resolve(e));return{overflow:t.overflow,overflowX:t.overflowX,overflowY:t.overflowY}}getInlineStyle(e,t){let r=n.resolve(e).style;return t.includes(`-`)?r.getPropertyValue(t):r[t]}getDocumentElement(){return n.intern(document.documentElement)}getBody(){return n.intern(document.body)}getHead(){return n.intern(document.head)}onFontsReady(e){let t=document.fonts;t&&t.addEventListener(`loadingdone`,()=>e())}startFontLoad(e){let t=document.fonts;return t?(t.load(`14px "${e}"`).catch(()=>{}),!0):!1}getElementById(e){let t=document.getElementById(e);return t===null?null:n.intern(t)}getId(e){return n.resolve(e).id}getDataset(e,t){return n.resolve(e).dataset[t]}getTagName(e){return n.resolve(e).tagName}hasAttribute(e,t){return n.resolve(e).hasAttribute(t)}getAttribute(e,t){return n.resolve(e).getAttribute(t)}getNaturalSize(e){let t=n.resolve(e);return{width:t.naturalWidth,height:t.naturalHeight}}getMediaState(e){let t=n.resolve(e);return{currentTime:t.currentTime,duration:t.duration,paused:t.paused,ended:t.ended,volume:t.volume,muted:t.muted,playbackRate:t.playbackRate}}getFullscreenElement(){let e=document.fullscreenElement;return e?n.intern(e):null}getFiles(e){return n.resolve(e).files}hasPointerCapture(e,t){return n.resolve(e).hasPointerCapture(t)}elementsFromPoint(e,t){return Array.from(document.elementsFromPoint(e,t),e=>n.intern(e))}},i={sink:new ProductionDOMSink,source:new ProductionDOMSource,install(e){e.sink&&(i.sink=e.sink),e.source&&(i.source=e.source)},reset(){i.sink.clearAllTimeouts(),n=new HandleRegistry,i.sink=new ProductionDOMSink,i.source=new ProductionDOMSource}};export{ProductionDOMSource as i,PatchBuilder as n,ProductionDOMSink as r,i as t};
|
|
2
|
+
//# sourceMappingURL=DOM-C-Edb3tA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DOM-C-Edb3tA.js","names":[],"sources":["../../src/typescript/lib/core/DOM.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport type { TextMeasureOptions, TextMetrics } from \"~/core/Util.js\";\nimport type { Size } from \"~/primitive/Size.js\";\nimport type { Component } from \"~/core/Component.js\";\n\n// Production measurement caches. These live here because the irreducible\n// browser-measurement leaf (the off-screen probe, the canvas metrics context,\n// the scrollbar-width probe) is the production side of the read seam — the lone\n// place the framework touches the real DOM for measurement.\nlet _metricsCtx: CanvasRenderingContext2D | null = null;\nlet _scrollBarWidth: number = -1;\n\n/**\n * Applies a set of camelCase inline-style properties to an element, used by the\n * off-screen measurement probes below. Raw `style` access is intentional — this\n * is inside the seam's production implementation.\n */\nfunction _applyProbeStyles(element: HTMLElement, styles: Record<string, string>): void {\n for (const key of Object.keys(styles)) {\n (element.style as any)[key] = styles[key];\n }\n}\n\n/**\n * Plain serialisable rectangle in viewport coordinates. Deliberately *not* a\n * live [`DOMRect`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect):\n * the read seam returns plain data so the same call can be answered by a\n * geometry model (offline tests) or, in future, across a worker boundary.\n *\n * @remarks The `top` / `left` / `right` / `bottom` edges mirror `DOMRect`'s\n * derived fields so existing anchor-positioning call sites read this as a\n * drop-in for the rect they used to get from `getBoundingClientRect()`. A live\n * `DOMRect` is structurally assignable to a `Rect`.\n *\n * @category Core\n */\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n top: number;\n left: number;\n right: number;\n bottom: number;\n}\n\n/**\n * Plain box-model snapshot — an element's native scroll offsets together with\n * its scrollable content size and visible viewport size, read in one shot.\n * Deliberately *not* a live element: like {@link Rect}, the read seam returns\n * plain data so the same call can be answered offline or across a worker\n * boundary.\n *\n * @category Core\n */\nexport interface ScrollMetrics {\n scrollTop: number;\n scrollLeft: number;\n scrollWidth: number;\n scrollHeight: number;\n clientWidth: number;\n clientHeight: number;\n}\n\n/**\n * Plain offset-box snapshot — an element's top edge and height relative to its\n * `offsetParent`. Plain data for the same reason as {@link ScrollMetrics}.\n *\n * @category Core\n */\nexport interface OffsetSize {\n offsetTop: number;\n offsetHeight: number;\n}\n\n/**\n * Plain snapshot of a media element's playback state, read in one shot through\n * {@link DOMSource.getMediaState}. Deliberately *not* a live element: like\n * {@link ScrollMetrics}, the read seam returns plain data so the same call can\n * be answered by a media model (offline tests) or across a worker boundary.\n *\n * @category Core\n */\nexport interface MediaState {\n /** Current playback position in seconds. */\n currentTime: number;\n /** Total media duration in seconds (`NaN` before metadata loads). */\n duration: number;\n /** Whether playback is currently paused. */\n paused: boolean;\n /** Whether playback has reached the end of the media. */\n ended: boolean;\n /** Current audio volume in `[0, 1]`. */\n volume: number;\n /** Whether audio is muted. */\n muted: boolean;\n /** Current playback speed multiplier (`1` is normal speed). */\n playbackRate: number;\n}\n\n/**\n * Opaque, serialisable element reference. A branded `number`, so a raw number\n * cannot be passed where a handle is expected and the reference forwards across\n * a worker boundary as plain data. The live `Node` it stands for never escapes\n * the seam — every sink/source method resolves the handle internally.\n *\n * @category Core\n */\nexport type Handle = number & { readonly __handleBrand: unique symbol };\n\n/**\n * A timer id as returned by the host's `setTimeout`. Node and the browser\n * disagree on the concrete type (`Timeout` object vs `number`), so the seam\n * carries whichever the host produces rather than committing to one.\n *\n * @category Core\n */\nexport type TimerId = ReturnType<typeof setTimeout>;\n\n/**\n * A batch of mutations applied to a single element with one handle resolve.\n * Every field is plain serialisable data — no live element, no function — so a\n * worker transport forwards an entire patch as one `postMessage`.\n *\n * Application order is fixed: styles first, then class removals before\n * additions (so a `removeClass` + `addClass` of the same name lands \"on\"),\n * attribute removals before sets, then dataset / text / scroll.\n *\n * @category Core\n */\nexport interface ElementPatch {\n /** Inline style writes. `null` removes the property. camelCase or `--custom`. */\n style?: Readonly<Record<string, string | null>>;\n /** Classes to remove (applied before {@link ElementPatch.addClass}). */\n removeClass?: readonly string[];\n /** Classes to add. */\n addClass?: readonly string[];\n /** Classes to force on/off. */\n toggleClass?: Readonly<Record<string, boolean>>;\n /** Attributes to remove (applied before {@link ElementPatch.setAttr}). */\n removeAttr?: readonly string[];\n /** Attributes to set. */\n setAttr?: Readonly<Record<string, string>>;\n /** `data-*` writes (camelCase keys). */\n dataset?: Readonly<Record<string, string>>;\n /** Text content. */\n text?: string;\n /** Native horizontal scroll offset. */\n scrollLeft?: number;\n /** Native vertical scroll offset. */\n scrollTop?: number;\n}\n\n/**\n * Canonicalising handle registry — the lone holder of live DOM references in\n * the handle design. Maps a handle to its node (forward) and a node back to its\n * handle (reverse) so a node is never assigned two handles; that reverse map is\n * what makes handle equality mirror element equality.\n *\n * Two minting modes draw the leak-safety line. {@link HandleRegistry.retain} is\n * for nodes the framework owns (it created them): a strong forward entry,\n * released explicitly at the element's dispose site. {@link HandleRegistry.intern}\n * is for browser-supplied nodes the live DOM already owns: a weak forward entry\n * (`WeakRef`) plus a finalizer that drops the handle once the node is collected,\n * so interning can never pin a dead node.\n *\n * Module-private: only the production sink and source touch it.\n */\nclass HandleRegistry {\n private readonly _forward = new Map<Handle, Node | WeakRef<Node>>();\n private readonly _reverse = new WeakMap<Node, Handle>();\n private _next = 1;\n\n /** Drops the forward entry when a weakly-interned node is garbage-collected. */\n private readonly _finalizer = new FinalizationRegistry<Handle>((handle) => {\n this._forward.delete(handle);\n });\n\n /**\n * Mints a canonical handle for a node the framework owns (a created,\n * possibly-detached element). Strongly held so a detached node survives\n * until it is mounted or explicitly released.\n *\n * @param node - The owned node.\n * @returns Its canonical handle (stable across repeated calls).\n */\n retain(node: Node): Handle {\n const existing = this._reverse.get(node);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const handle = this._mint(node);\n\n this._forward.set(handle, node);\n\n return handle;\n }\n\n /**\n * Mints a canonical handle for a node supplied by the browser (an event\n * target, a `querySelector` result, the active element). The live DOM owns\n * it, so the registry holds only a weak reference plus a finalizer — no leak\n * even if the handle is never released.\n *\n * @param node - The browser-supplied node.\n * @returns Its canonical handle (stable while the node is alive).\n */\n intern(node: Node): Handle {\n const existing = this._reverse.get(node);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const handle = this._mint(node);\n\n this._forward.set(handle, new WeakRef(node));\n this._finalizer.register(node, handle);\n\n return handle;\n }\n\n /**\n * Resolves a handle to its node. Throws on a released or collected handle —\n * a use-after-free becomes a loud failure instead of the silent no-op a\n * stale element pointer would give.\n *\n * @param handle - The handle to resolve.\n * @returns The live node.\n */\n resolve(handle: Handle): Node {\n const entry = this._forward.get(handle);\n\n if (entry === undefined) {\n throw new Error(`DOM handle ${handle} is not registered (released or never minted).`);\n }\n\n const node = entry instanceof WeakRef ? entry.deref() : entry;\n\n if (node === undefined) {\n throw new Error(`DOM handle ${handle} refers to a collected node.`);\n }\n\n return node;\n }\n\n /**\n * Releases an owned handle at its element's dispose site. Idempotent. A\n * missed release on a retained (strong) handle pins a detached element\n * forever, so the migration must place this at every created-element\n * teardown.\n *\n * @param handle - The handle to release.\n */\n release(handle: Handle): void {\n const entry = this._forward.get(handle);\n\n if (entry === undefined) {\n return;\n }\n\n const node = entry instanceof WeakRef ? entry.deref() : entry;\n\n if (node) {\n this._reverse.delete(node);\n }\n\n this._forward.delete(handle);\n }\n\n /** Live forward-map size — a test hook that verifies release / GC eviction. */\n get size(): number {\n return this._forward.size;\n }\n\n private _mint(node: Node): Handle {\n const handle = this._next as Handle;\n\n this._next += 1;\n this._reverse.set(node, handle);\n\n return handle;\n }\n}\n\n/** The shared production registry. Rebuilt together with the seams by {@link DOM.reset}. */\nlet _registry = new HandleRegistry();\n\n/** Forward-map size of the shared production registry; for tests only. @internal */\nexport function _handleRegistrySize(): number {\n return _registry.size;\n}\n\n/**\n * The single terminal style write, shared by the inline-style and patch paths.\n * A hyphenated key is either a custom property (`--foo`) or a standard\n * kebab-case name (`background-color`); both go through `setProperty` /\n * `removeProperty`. Only camelCase keys work through the indexed accessor.\n */\nfunction writeDeclaration(style: CSSStyleDeclaration, key: string, value: string | null): void {\n if (key.includes(\"-\")) {\n if (value === null) {\n style.removeProperty(key);\n } else {\n style.setProperty(key, value);\n }\n } else if (value === null) {\n (style as unknown as Record<string, string>)[key] = \"\";\n } else {\n (style as unknown as Record<string, string>)[key] = value;\n }\n}\n\n/**\n * Module-private, never appended to the document: a detached element whose\n * inline style is a real `CSSStyleDeclaration`. Writing to it costs nothing at\n * the document level, so a bag can be merged property-by-property here and\n * land on the shared sheet as one mutation.\n */\nlet _scratch: CSSStyleDeclaration | null = null;\n\nfunction scratchDeclaration(): CSSStyleDeclaration | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n return _scratch ??= document.createElement(\"div\").style;\n}\n\n/**\n * Applies an {@link ElementPatch} to a resolved element — the terminal raw-DOM\n * write for the batched {@link DOMSink.apply} path. Fixed order: styles, class\n * removals before additions, attribute removals before sets, then dataset /\n * text / scroll.\n */\nfunction applyPatchTo(element: HTMLElement, patch: ElementPatch): void {\n if (patch.style) {\n for (const key of Object.keys(patch.style)) {\n writeDeclaration(element.style, key, patch.style[key]);\n }\n }\n\n if (patch.removeClass) {\n for (const name of patch.removeClass) {\n element.classList.remove(name);\n }\n }\n\n if (patch.addClass) {\n for (const name of patch.addClass) {\n // Skip empty tokens: `classList.add(\"\")` throws a SyntaxError. A\n // stray empty class name (e.g. an anonymous class whose\n // `constructor.name` is \"\") must not abort the whole patch.\n if (name) {\n element.classList.add(name);\n }\n }\n }\n\n if (patch.toggleClass) {\n for (const name of Object.keys(patch.toggleClass)) {\n element.classList.toggle(name, patch.toggleClass[name]);\n }\n }\n\n if (patch.removeAttr) {\n for (const key of patch.removeAttr) {\n element.removeAttribute(key);\n }\n }\n\n if (patch.setAttr) {\n for (const key of Object.keys(patch.setAttr)) {\n element.setAttribute(key, patch.setAttr[key]);\n }\n }\n\n if (patch.dataset) {\n for (const key of Object.keys(patch.dataset)) {\n element.dataset[key] = patch.dataset[key];\n }\n }\n\n if (patch.text !== undefined) {\n element.textContent = patch.text;\n }\n\n if (patch.scrollLeft !== undefined) {\n element.scrollLeft = patch.scrollLeft;\n }\n\n if (patch.scrollTop !== undefined) {\n element.scrollTop = patch.scrollTop;\n }\n}\n\n/**\n * Fluent accumulator over an {@link ElementPatch}. Each method appends to the\n * pending patch; {@link PatchBuilder.commit} flushes it as one batched write.\n * The fluent form is sugar for cold call sites — the batched {@link DOMSink.apply}\n * is the real primitive — and it allocates one builder per edit.\n *\n * @category Core\n */\nexport class PatchBuilder {\n private readonly _patch: {\n style?: Record<string, string | null>;\n addClass?: string[];\n setAttr?: Record<string, string>;\n text?: string;\n } = {};\n\n /**\n * @param _commit - Flush callback that performs the single handle resolve.\n */\n constructor(private readonly _commit: (patch: ElementPatch) => void) {}\n\n /**\n * Queues an inline-style write (`null` removes).\n *\n * @param key - The CSS property name (camelCase, or `--custom-property`).\n * @param value - The value to set, or null to remove the property.\n * @returns This builder.\n */\n style(key: string, value: string | null): this {\n (this._patch.style ??= {})[key] = value;\n\n return this;\n }\n\n /**\n * Queues a class addition.\n *\n * @param name - The class name.\n * @returns This builder.\n */\n addClass(name: string): this {\n (this._patch.addClass ??= []).push(name);\n\n return this;\n }\n\n /**\n * Queues an attribute set.\n *\n * @param key - The attribute name.\n * @param value - The attribute value.\n * @returns This builder.\n */\n attr(key: string, value: string): this {\n (this._patch.setAttr ??= {})[key] = value;\n\n return this;\n }\n\n /**\n * Queues a text-content write.\n *\n * @param value - The text content.\n * @returns This builder.\n */\n text(value: string): this {\n this._patch.text = value;\n\n return this;\n }\n\n /** Flushes the accumulated patch through one batched write (one resolve). */\n commit(): void {\n this._commit(this._patch);\n }\n}\n\n/**\n * Terminal DOM-write primitive. Every structural mutation and inline-style\n * write in the framework funnels through this seam instead of touching\n * `element.style` / `element.classList` / `appendChild` directly. The\n * production implementation ({@link ProductionDOMSink}) is a thin pass-through;\n * test implementations record the writes without touching a DOM.\n *\n * @remarks Methods are one-way (no return value drives control flow), so a\n * future worker transport can forward each as a `postMessage`.\n *\n * @category Core\n */\nexport interface DOMSink {\n /**\n * Applies a batch of mutations to one element with a single handle resolve.\n * The hot-path primitive that replaces the ten per-write data setters\n * (`setStyle`, `addClass`, `removeClass`, `toggleClass`, `setAttribute`,\n * `removeAttribute`, `setDataset`, `setTextContent`, `setScrollLeft`,\n * `setScrollTop`): a layout commit (width + height + classes + an attribute)\n * costs one `Map.get`, not one per write.\n *\n * @param handle - The target element handle.\n * @param patch - The batch of mutations.\n */\n apply(handle: Handle, patch: ElementPatch): void;\n\n /**\n * Fluent convenience that accumulates a patch and flushes it through a\n * single {@link apply}. For cold call sites — it allocates one builder per\n * edit.\n *\n * @param handle - The target element handle.\n * @returns A builder whose `commit()` performs the single resolve.\n */\n edit(handle: Handle): PatchBuilder;\n\n /**\n * Releases an owned (retained) handle at its element's dispose site.\n *\n * @param handle - The handle to release.\n */\n release(handle: Handle): void;\n\n /**\n * Writes a bag of style properties onto a `CSSStyleRule`'s declaration as\n * one sheet mutation. A `CSSStyleRule` has no element, so it gets its own\n * method — mirroring how {@link apply}'s `style` patch serves both the\n * single and the bulk element-style path.\n *\n * @param rule - The target `CSSStyleRule`.\n * @param styles - Camel-cased property keys mapped to string values (or\n * null to remove the property).\n */\n setRuleStyles(rule: CSSStyleRule, styles: Record<string, string | null>): void;\n\n /**\n * Finds, or inserts, the framework's shared-stylesheet `CSSStyleRule` for a\n * selector, so callers never walk a `CSSStyleSheet` directly. The returned\n * rule is handed to {@link setRuleStyles}.\n *\n * @param selector - The CSS selector text.\n * @returns The existing or newly-inserted rule.\n */\n ensureStyleRule(selector: string): CSSStyleRule;\n\n /**\n * Removes the shared-stylesheet `CSSStyleRule` for a selector, if present.\n * The inverse of {@link ensureStyleRule}. A no-op when no rule matches.\n *\n * @param selector - The CSS selector text of the rule to remove.\n */\n deleteStyleRule(selector: string): void;\n\n /**\n * Inserts a `@keyframes` block into the shared stylesheet if one with the\n * given name does not already exist (idempotent).\n *\n * @param name - The animation name (no `@keyframes` prefix).\n * @param body - The keyframe body (the text between the braces).\n */\n ensureKeyframes(name: string, body: string): void;\n\n /**\n * Creates a detached HTML element, retained behind a handle until released.\n *\n * @param tag - The element tag name.\n * @returns The new element's handle.\n */\n createElement(tag: string): Handle;\n\n /**\n * Creates a detached namespaced element (SVG sprite / glyph construction),\n * retained behind a handle until released.\n *\n * @param ns - The element namespace URI.\n * @param tag - The element tag name.\n * @returns The new element's handle.\n */\n createElementNS(ns: string, tag: string): Handle;\n\n /**\n * Appends a child to a parent.\n *\n * @param parent - The parent handle.\n * @param child - The child handle to append.\n */\n appendChild(parent: Handle, child: Handle): void;\n\n /**\n * Removes a child from a parent.\n *\n * @param parent - The parent handle.\n * @param child - The child handle to remove.\n */\n removeChild(parent: Handle, child: Handle): void;\n\n /**\n * Detaches an element from its parent.\n *\n * @param handle - The element to remove.\n */\n removeElement(handle: Handle): void;\n\n /**\n * Moves browser focus to an element.\n *\n * @param handle - The element to focus.\n * @param options - Focus options; `preventScroll` suppresses the native\n * scroll-into-view so a host that owns its own scroll offset is not fought.\n */\n focus(handle: Handle, options?: { preventScroll?: boolean }): void;\n\n /**\n * Requests a native form submission on a `<form>` element, firing the\n * cancelable `submit` event and running constraint validation.\n *\n * @param handle - The form element to submit.\n */\n requestSubmit(handle: Handle): void;\n\n /**\n * Removes browser focus from an element.\n *\n * @param handle - The element to blur.\n */\n blur(handle: Handle): void;\n\n /**\n * Writes the value of a form control.\n *\n * @param handle - The target form control.\n * @param value - The value to set.\n */\n setValue(handle: Handle, value: string): void;\n\n /**\n * Sets the text-selection range of a form control.\n *\n * @param handle - The target form control.\n * @param start - The selection start offset.\n * @param end - The selection end offset.\n */\n setSelectionRange(handle: Handle, start: number, end: number): void;\n\n /**\n * Assigns `location.hash`, pushing a history entry.\n *\n * @param hash - The new hash, including its leading `\"#\"`.\n */\n setLocationHash(hash: string): void;\n\n /**\n * Replaces the current history entry with one carrying `hash`, instead of\n * pushing a new one.\n *\n * @param hash - The new hash, including its leading `\"#\"`.\n */\n replaceLocationHash(hash: string): void;\n\n /**\n * `history.pushState` with `url`, pushing a history entry. Fires no\n * event — the caller is responsible for applying the new route.\n *\n * @param url - The new path (and optional query/fragment) to push.\n */\n pushHistoryPath(url: string): void;\n\n /**\n * `history.replaceState` with `url`, replacing the current history\n * entry. Fires no event — the caller is responsible for applying the new\n * route.\n *\n * @param url - The new path (and optional query/fragment) to write.\n */\n replaceHistoryPath(url: string): void;\n\n /**\n * Registers a native event listener on a target. The framework's\n * {@link Event} class is the component-level routing layer; this seam covers\n * the low-level native hook it (and a few primitives) sits on.\n *\n * @param target - The event target handle (element, window, media-query list).\n * @param type - The event type.\n * @param handler - The listener.\n * @param options - Optional capture/passive/once options.\n */\n addListener<T extends Event = Event>(target: Handle, type: string, handler: (event: T) => void, options?: boolean | AddEventListenerOptions): void;\n\n /**\n * Removes a native event listener previously registered with {@link addListener}.\n *\n * @param target - The event target handle.\n * @param type - The event type.\n * @param handler - The listener to remove.\n * @param options - Optional capture options matching the registration.\n */\n removeListener<T extends Event = Event>(target: Handle, type: string, handler: (event: T) => void, options?: boolean | EventListenerOptions): void;\n\n /**\n * Dispatches an event on a target.\n *\n * @param target - The event target handle.\n * @param event - The event to dispatch.\n */\n dispatchEvent(target: Handle, event: Event): void;\n\n /**\n * Builds and dispatches a custom event of `type` with the given init on a\n * target. The framework's sole construction site for fired custom events:\n * the production sink mints a native `CustomEvent`, while the modelled sink\n * builds a plain sentinel event, so production code never names the global\n * `CustomEvent` constructor. `init` is a `CustomEventInit`, so `init.detail`\n * surfaces as the event's `detail` exactly as the inline `new CustomEvent`\n * it replaces did.\n *\n * @param target - The event target handle.\n * @param type - The event type (e.g. `\"keydown\"`).\n * @param init - Optional `CustomEventInit` (carries `detail`).\n */\n dispatchCustomEvent(target: Handle, type: string, init?: CustomEventInit): void;\n\n /**\n * Schedules a callback for the next animation frame.\n *\n * @param callback - The frame callback.\n * @returns The request handle, for {@link cancelAnimationFrame}.\n */\n requestAnimationFrame(callback: FrameRequestCallback): number;\n\n /**\n * Cancels a previously scheduled animation-frame callback.\n *\n * @param handle - The handle returned by {@link requestAnimationFrame}.\n */\n cancelAnimationFrame(handle: number): void;\n\n /**\n * Schedules `callback` to run after `delayMs`.\n *\n * @param callback - The timer callback.\n * @param delayMs - Delay before the callback runs, in milliseconds.\n * @returns The timer id, for {@link clearTimeout}.\n */\n setTimeout(callback: () => void, delayMs: number): TimerId;\n\n /**\n * Cancels a timer scheduled through {@link setTimeout}. A timer that has\n * already fired, or an id already cleared, is ignored.\n *\n * @param id - The id returned by {@link setTimeout}.\n */\n clearTimeout(id: TimerId): void;\n\n /**\n * Cancels every timer this sink scheduled that has not yet fired. Called by\n * `DOM.reset()` so a torn-down environment cannot be reached by a callback\n * scheduled against the previous one.\n */\n clearAllTimeouts(): void;\n\n /**\n * Sets an element's `id`.\n *\n * @param handle - The target element.\n * @param id - The id to set.\n */\n setId(handle: Handle, id: string): void;\n\n /**\n * Inserts a node before a reference child of a parent.\n *\n * @param parent - The parent handle.\n * @param node - The node to insert.\n * @param reference - The child to insert before, or null to append.\n */\n insertBefore(parent: Handle, node: Handle, reference: Handle | null): void;\n\n /**\n * Creates an empty document fragment for batched insertion, retained behind\n * a handle until released.\n *\n * @returns The new fragment's handle.\n */\n createDocumentFragment(): Handle;\n\n /**\n * Synthesises a click on an element (file-input open, download anchor).\n *\n * @param handle - The element to click.\n */\n click(handle: Handle): void;\n\n /**\n * Routes subsequent pointer events for a pointer id to an element.\n *\n * @param handle - The capturing element.\n * @param pointerId - The pointer id to capture.\n */\n setPointerCapture(handle: Handle, pointerId: number): void;\n\n /**\n * Releases a pointer capture previously set on an element.\n *\n * @param handle - The element holding the capture.\n * @param pointerId - The pointer id to release.\n */\n releasePointerCapture(handle: Handle, pointerId: number): void;\n\n /**\n * Obtains a drawing context from a `<canvas>` element. Generic over\n * `contextId` (`\"2d\"`, `\"webgl\"`, `\"webgl2\"`) so a single seam entry serves\n * both the raster and WebGL components, each narrowing the returned union\n * itself.\n *\n * @remarks Unlike every other sink method this returns a live object rather\n * than a forwardable one-way write: a rendering context cannot cross a worker\n * boundary, so a modelled sink returns `null` and the caller no-ops offline.\n * This is the single, named escape from the seam's one-way contract — the\n * reason a canvas is a live-only component.\n *\n * @param handle - The `<canvas>` element handle.\n * @param contextId - The context identifier (`\"2d\"`, `\"webgl\"`, …).\n * @param options - Optional context attributes (e.g. `{ alpha: false }`).\n * @returns The rendering context, or `null` when unavailable (offline, or the\n * element does not support the requested context).\n */\n getContext(handle: Handle, contextId: string, options?: unknown): RenderingContext | null;\n\n /**\n * Resolves `handle` to its real element and hands it to `factory`, which\n * mounts a foreign live widget (a third-party library that takes a parent\n * element and mutates a whole DOM region it owns) into it — the second\n * named escape from the seam's one-way contract, after {@link getContext}.\n *\n * @remarks Like `getContext`, this returns a live object rather than a\n * forwardable one-way write: the mounted widget instance cannot cross a\n * worker boundary, so a modelled sink returns `null` and the caller no-ops\n * offline. This is the reason a component built on `mountView` (e.g.\n * `CodeEditor` on CodeMirror's `EditorView`) is live-only. `factory`'s\n * parameter is deliberately left unannotated at call sites outside this\n * seam — its type is inferred from this signature — so no call site names\n * a DOM element type and trips `no-raw-dom`'s *hold* clause.\n *\n * @param handle - The element handle to mount the foreign widget into.\n * @param factory - Builds and returns the foreign widget given the\n * resolved parent element.\n * @returns Whatever `factory` returns, or `null` offline / when the handle\n * does not resolve.\n */\n mountView<T>(handle: Handle, factory: (parent: HTMLElement) => T): T | null;\n\n /**\n * Starts (or resumes) playback of a media element. Wraps the `play()` IDL\n * method, whose returned promise is intentionally dropped — playback state is\n * observed through media events, not the promise.\n *\n * @param handle - The `<video>` / `<audio>` element handle.\n */\n mediaPlay(handle: Handle): void;\n\n /**\n * Pauses playback of a media element.\n *\n * @param handle - The media element handle.\n */\n mediaPause(handle: Handle): void;\n\n /**\n * Seeks a media element to a playback position.\n *\n * @param handle - The media element handle.\n * @param seconds - The target position in seconds.\n */\n setCurrentTime(handle: Handle, seconds: number): void;\n\n /**\n * Sets a media element's audio volume.\n *\n * @param handle - The media element handle.\n * @param value - The volume in `[0, 1]`.\n */\n setVolume(handle: Handle, value: number): void;\n\n /**\n * Sets a media element's muted state (the IDL property, which the boolean\n * attribute alone cannot toggle after load).\n *\n * @param handle - The media element handle.\n * @param muted - Whether audio is muted.\n */\n setMuted(handle: Handle, muted: boolean): void;\n\n /**\n * Sets a media element's playback speed multiplier.\n *\n * @param handle - The media element handle.\n * @param rate - The playback rate (`1` is normal speed).\n */\n setPlaybackRate(handle: Handle, rate: number): void;\n\n /**\n * Requests that an element enter fullscreen. Must be called from a user\n * gesture handler; the returned promise is dropped — the transition is\n * observed through the `fullscreenchange` event.\n *\n * @param handle - The element to display fullscreen.\n */\n requestFullscreen(handle: Handle): void;\n\n /**\n * Exits fullscreen for the document. No-op when nothing is fullscreen.\n */\n exitFullscreen(): void;\n}\n\n/**\n * Read seam. Geometry is keyed on the owning {@link Component} (so a model can\n * reproduce it from committed state); text metrics, theme variables, and\n * environment constants funnel through the remaining methods. The production\n * implementation ({@link ProductionDOMSource}) reads the live DOM; test\n * implementations answer from a geometry model and a baked metrics table.\n *\n * @category Core\n */\nexport interface DOMSource {\n /**\n * Converts a raw browser node arriving at an event boundary into a (weak)\n * handle. The one place a raw target legitimately enters the seam from\n * outside — the event system hands it `evnt.target`, and the handle is\n * interned so no call site downstream holds the raw node.\n *\n * @param target - The browser-supplied event target.\n * @returns Its canonical handle.\n */\n intern(target: EventTarget): Handle;\n\n /**\n * Whether a raw value arriving at an event boundary is a DOM node. Replaces\n * call-site `value instanceof Node` guards (which name a global constructor)\n * so an `EventTarget | null` field can be narrowed before {@link intern}.\n *\n * @param value - The raw value to test (typically `e.relatedTarget` / `e.target`).\n * @returns `true` when the value is a node; production matches `instanceof Node`.\n * The `EventTarget` type guard lets a nullable event field narrow for\n * the subsequent {@link intern}.\n */\n isNode(value: unknown): value is EventTarget;\n\n /**\n * Whether a raw value is a DOM element — {@link isNode} narrowed to elements.\n * Replaces call-site `value instanceof Element`.\n *\n * @param value - The raw value to test.\n * @returns `true` when the value is an element; production matches `instanceof Element`.\n */\n isElement(value: unknown): value is EventTarget;\n\n /**\n * Escapes a string for safe use inside a CSS selector. Replaces call-site\n * `CSS.escape`, which names a global the offline harness does not ship.\n *\n * @param value - The raw string (e.g. a glyph id).\n * @returns The escaped string; production uses `CSS.escape`.\n */\n escapeSelector(value: string): string;\n\n /**\n * Returns the viewport-space rectangle of a component's root element.\n *\n * @param component - The component to measure.\n * @returns The component's bounding rectangle as plain data.\n */\n getViewportRect(component: Component): Rect;\n\n /**\n * Returns the viewport-space rectangle of an arbitrary element. Escape\n * hatch for non-component nodes (anchor elements, ancestor scroll boxes).\n *\n * @param handle - The element to measure.\n * @returns The element's bounding rectangle as plain data.\n */\n getElementRect(handle: Handle): Rect;\n\n /**\n * Measures the rendered size and baseline of a text string.\n *\n * @param text - The string to measure.\n * @param options - Font properties; default to the active theme variables.\n * @returns The measured `{width, height, baseline}` in pixels.\n */\n measureText(text: string, options?: TextMeasureOptions): TextMetrics;\n\n /**\n * Measures many strings under one font in a single document reflow.\n *\n * @param texts - The strings to measure.\n * @param options - Font properties; default to the active theme variables.\n * @returns One width per input, in input order; an empty input list\n * touches the DOM not at all and returns an empty array.\n */\n measureTextWidths(texts: string[], options?: TextMeasureOptions): number[];\n\n /**\n * Resolves a CSS `font-size` value (possibly a `calc()`/`var()`) to a pixel\n * number by evaluating it on an off-screen probe.\n *\n * @param fontSizeCSS - A CSS font-size value.\n * @returns The resolved size in pixels (14 when unresolvable).\n */\n resolveFontSizePx(fontSizeCSS: string): number;\n\n /**\n * Returns the active font's vertical metrics in pixels.\n *\n * @returns The font `{ascent, descent, capTop}` in pixels.\n */\n measureFontMetrics(): { ascent: number; descent: number; capTop: number };\n\n /**\n * Resolves a theme CSS variable (e.g. `--ts-ui-font-size`) to its value.\n *\n * @param name - The CSS custom-property name, including the leading `--`.\n * @returns The resolved value, trimmed; empty string when unset.\n */\n getThemeVar(name: string): string;\n\n /**\n * Returns the current viewport size in pixels.\n *\n * @returns The viewport `{width, height}`.\n */\n getViewportSize(): Size;\n\n /**\n * Returns the native scrollbar width in pixels.\n *\n * @returns The scrollbar width.\n */\n getScrollBarWidth(): number;\n\n /**\n * Returns the display's device-pixel ratio — the factor by which a\n * `<canvas>` backing store must be scaled above its CSS size to stay crisp\n * on a HiDPI display. Reads the flagged `window.devicePixelRatio` global\n * behind the seam; a modelled source reports `1` so offline backing-store\n * math stays deterministic.\n *\n * @returns The device-pixel ratio (`1` or greater); `1` when unavailable.\n */\n getDevicePixelRatio(): number;\n\n /**\n * Whether this is a modelled (no-browser) source. Lets the few\n * irreducibly-browser reads short-circuit to a fallback offline.\n *\n * @returns `true` for a modelled source, `false` for production.\n */\n isModelled(): boolean;\n\n /**\n * Reads an element's native horizontal scroll offset (browser-clamped).\n *\n * @param handle - The element to read.\n * @returns The current `scrollLeft` in pixels.\n */\n getScrollLeft(handle: Handle): number;\n\n /**\n * Reads an element's native vertical scroll offset (browser-clamped).\n *\n * @param handle - The element to read.\n * @returns The current `scrollTop` in pixels.\n */\n getScrollTop(handle: Handle): number;\n\n /**\n * Reads an element's scroll offsets, scrollable content size, and visible\n * viewport size in one shot.\n *\n * @param handle - The element to measure.\n * @returns The element's {@link ScrollMetrics} as plain data.\n */\n getScrollMetrics(handle: Handle): ScrollMetrics;\n\n /**\n * Reads an element's offset-box top edge and height.\n *\n * @param handle - The element to measure.\n * @returns The element's {@link OffsetSize} as plain data.\n */\n getOffsetSize(handle: Handle): OffsetSize;\n\n /**\n * Whether an element is currently attached to a document.\n *\n * @param handle - The element to test.\n * @returns `true` when the element is connected.\n */\n isConnected(handle: Handle): boolean;\n\n /**\n * Reads the value of a form control.\n *\n * @param handle - The form control to read.\n * @returns The control's current value.\n */\n getValue(handle: Handle): string;\n\n /**\n * Returns the element that currently has focus, or null.\n *\n * @returns The active element handle, or null when nothing is focused.\n */\n getActiveElement(): Handle | null;\n\n /**\n * Reads the document's current text selection as plain data, boxed\n * through handles so the live `Selection`/`Range` never escapes the seam.\n *\n * @returns The selection's start/end containers and character offsets,\n * or `null` when nothing is selected (no ranges, or a collapsed one).\n */\n getDocumentSelection(): DocumentSelectionRange | null;\n\n /**\n * Evaluates a media query, returning its current match state and a\n * change-subscription hook. The live `MediaQueryList` never escapes the seam.\n *\n * @param query - The media-query string.\n * @returns The match state and a `change` subscription.\n */\n matchMedia(query: string): MediaQueryResult;\n\n /**\n * Whether an event target is the global `window` (identity check that keeps\n * the raw global out of call sites).\n *\n * @param target - The target handle to test, or null.\n * @returns `true` when the target is `window`.\n */\n isWindow(target: Handle | null): boolean;\n\n /**\n * Returns the global `window` interned to a handle, so window-level\n * listeners can be registered without a call site naming the raw global.\n *\n * @returns The `window` handle.\n */\n getWindow(): Handle;\n\n /**\n * The current `location.hash`, boxed so the raw global never escapes the\n * seam.\n *\n * @returns The hash including its leading `\"#\"`, or `\"\"` when empty.\n */\n getLocationHash(): string;\n\n /**\n * The current `location.pathname`, boxed so the raw global never escapes\n * the seam.\n *\n * @returns The path, always starting with `\"/\"`.\n */\n getLocationPathname(): string;\n\n /**\n * The current `location.search`, boxed so the raw global never escapes\n * the seam.\n *\n * @returns The query string including its leading `\"?\"`, or `\"\"` when empty.\n */\n getLocationSearch(): string;\n\n /**\n * Whether a node is the ancestor of (or equal to) another node.\n *\n * @param ancestor - The candidate ancestor handle.\n * @param node - The node handle to test, or null.\n * @returns `true` when `ancestor` contains `node`.\n */\n contains(ancestor: Handle, node: Handle | null): boolean;\n\n /**\n * Finds the first descendant of `root` matching a selector.\n *\n * @param root - The subtree root handle.\n * @param selector - The CSS selector.\n * @returns The first match handle, or null.\n */\n querySelector(root: Handle, selector: string): Handle | null;\n\n /**\n * Finds all descendants of `root` matching a selector, as a plain array.\n *\n * @param root - The subtree root handle.\n * @param selector - The CSS selector.\n * @returns The match handles (a snapshot array, never a live `NodeList`).\n */\n querySelectorAll(root: Handle, selector: string): Handle[];\n\n /**\n * Whether an element itself matches a selector. The self-test counterpart to\n * {@link DOMSource.querySelector}, which only sees descendants — needed when\n * a component's own root element is the candidate (a `TextField` renders as\n * the `<input>` itself, with no focusable descendant to find).\n *\n * @param handle - The element to test.\n * @param selector - The CSS selector.\n * @returns `true` when the element matches.\n */\n matches(handle: Handle, selector: string): boolean;\n\n /**\n * Returns an element's parent element, or null.\n *\n * @param handle - The element to read.\n * @returns The parent element handle, or null.\n */\n getParentElement(handle: Handle): Handle | null;\n\n /**\n * Returns a node's parent node, or null.\n *\n * @param handle - The node to read.\n * @returns The parent node handle, or null.\n */\n getParentNode(handle: Handle): Handle | null;\n\n /**\n * Returns a node's first child, or null.\n *\n * @param handle - The node to read.\n * @returns The first child handle, or null.\n */\n getFirstChild(handle: Handle): Handle | null;\n\n /**\n * Returns an element's resolved border widths as computed-style strings\n * (e.g. `\"1px\"`), one per side.\n *\n * @param handle - The element to measure.\n * @returns The four border-width strings.\n */\n getBorderWidths(handle: Handle): { top: string; right: string; bottom: string; left: string };\n\n /**\n * Returns an element's resolved `overflow` / `overflow-x` / `overflow-y`\n * computed-style strings.\n *\n * @param handle - The element to read.\n * @returns The three overflow strings.\n */\n getComputedOverflow(handle: Handle): { overflow: string; overflowX: string; overflowY: string };\n\n /**\n * Reads a single inline style property off an element.\n *\n * @param handle - The element to read.\n * @param key - The CSS property name (camelCase, or `--custom-property`).\n * @returns The inline value (empty string when unset).\n */\n getInlineStyle(handle: Handle, key: string): string;\n\n /**\n * Returns the document's root `<html>` element — the mount point for\n * top-layer overlays.\n *\n * @returns The document element handle.\n */\n getDocumentElement(): Handle;\n\n /**\n * Returns the document `<body>` element.\n *\n * @returns The body element handle.\n */\n getBody(): Handle;\n\n /**\n * Returns the document `<head>` element.\n *\n * @returns The head element handle.\n */\n getHead(): Handle;\n\n /**\n * Registers a callback fired each time the document's web fonts finish a\n * batch of loading. Text whose preferred size was measured against a\n * fallback font before a `font-display: swap` web font swapped in must\n * re-measure once the real font is available, or its stale\n * (fallback-derived) size clips the now-wider glyphs. Offline sources\n * measure against baked fonts with no async swap, so they never invoke it.\n *\n * @param callback - Invoked whenever a batch of font loads settles; never\n * invoked on a document that loads no web fonts at all, since no\n * measurement can go stale there. Implementations must not fire it merely\n * because the font set is momentarily idle — see the production\n * implementation for why that is the trap this contract exists to avoid.\n */\n onFontsReady(callback: () => void): void;\n\n /**\n * Starts downloading and activating `family` now, rather than leaving the\n * fetch to be triggered by the first text that renders in it.\n *\n * An `@font-face` rule on its own downloads nothing: the browser fetches\n * and activates a face only once rendered content actually uses it, which\n * puts that work *after* the whole first layout instead of alongside it.\n * Starting it as soon as the rules are installed lets the face arrive while\n * the component tree is still being built.\n *\n * @param family - The `font-family` name to start loading, as it appears in\n * the `@font-face` rule.\n *\n * @returns `true` when an asynchronous load was actually started, so the\n * caller can expect {@link onFontsReady} to follow; `false` when this\n * source cannot load fonts asynchronously at all — an engine with no CSS\n * Font Loading API, or an offline source measuring against baked fonts.\n * A caller that defers work until the font settles must not defer on\n * `false`, or it would be waiting for a callback that never comes.\n *\n * @remarks Best-effort and fire-and-forget: a failed load is not an error\n * (the `font-display: swap` fallback stands, and {@link onFontsReady}\n * still settles the measurements).\n */\n startFontLoad(family: string): boolean;\n\n /**\n * Looks up an element by its `id`.\n *\n * @param id - The element id (no `#` prefix).\n * @returns The matching element handle, or null.\n */\n getElementById(id: string): Handle | null;\n\n /**\n * Reads an element's `id`.\n *\n * @param handle - The element to read.\n * @returns The element's id (empty string when unset).\n */\n getId(handle: Handle): string;\n\n /**\n * Reads a `data-*` attribute via the element's dataset.\n *\n * @param handle - The element to read.\n * @param key - The dataset key (camelCase).\n * @returns The value, or undefined when unset.\n */\n getDataset(handle: Handle, key: string): string | undefined;\n\n /**\n * Reads an element's tag name (uppercase).\n *\n * @param handle - The element to read.\n * @returns The tag name.\n */\n getTagName(handle: Handle): string;\n\n /**\n * Whether an element has a given attribute.\n *\n * @param handle - The element to test.\n * @param key - The attribute name.\n * @returns `true` when the attribute is present.\n */\n hasAttribute(handle: Handle, key: string): boolean;\n\n /**\n * Reads an attribute value.\n *\n * @param handle - The element to read.\n * @param key - The attribute name.\n * @returns The value, or null when unset.\n */\n getAttribute(handle: Handle, key: string): string | null;\n\n /**\n * Reads an image's intrinsic pixel size.\n *\n * @param handle - The image element.\n * @returns The natural `{width, height}` in pixels.\n */\n getNaturalSize(handle: Handle): { width: number; height: number };\n\n /**\n * Reads a media element's playback state in one shot as plain data.\n *\n * @param handle - The `<video>` / `<audio>` element handle.\n * @returns The element's {@link MediaState}.\n */\n getMediaState(handle: Handle): MediaState;\n\n /**\n * Returns the element currently displayed fullscreen, or `null` when nothing\n * is. Reads `document.fullscreenElement` behind the seam so no call site\n * names the global.\n *\n * @returns The fullscreen element handle, or `null`.\n */\n getFullscreenElement(): Handle | null;\n\n /**\n * Reads the selected files of a file input.\n *\n * @param handle - The file-input element.\n * @returns The selected `FileList`, or null.\n */\n getFiles(handle: Handle): FileList | null;\n\n /**\n * Whether an element currently holds a given pointer capture.\n *\n * @param handle - The element to test.\n * @param pointerId - The pointer id.\n * @returns `true` when the element captures the pointer.\n */\n hasPointerCapture(handle: Handle, pointerId: number): boolean;\n\n /**\n * Returns the stack of elements at a viewport point (hit-testing).\n *\n * @param x - The viewport x coordinate.\n * @param y - The viewport y coordinate.\n * @returns The element handles at the point, topmost first.\n */\n elementsFromPoint(x: number, y: number): Handle[];\n}\n\n/**\n * Seam-friendly result of {@link DOMSource.getDocumentSelection}: the\n * selection's start/end containers and character offsets, boxed through\n * handles so the live `Selection`/`Range` never escapes the seam.\n *\n * @category Core\n */\nexport interface DocumentSelectionRange {\n /** The node the selection starts in. */\n startContainer: Handle;\n /** Character offset into {@link startContainer}, or `null` when it is not a text node. */\n startOffset: number | null;\n /** The node the selection ends in. */\n endContainer: Handle;\n /** Character offset into {@link endContainer}, or `null` when it is not a text node. */\n endOffset: number | null;\n}\n\n/**\n * Seam-friendly result of {@link DOMSource.matchMedia}: the current match state\n * plus a change subscription, so the live `MediaQueryList` stays behind the seam.\n *\n * @category Core\n */\nexport interface MediaQueryResult {\n /** Whether the query currently matches. */\n matches: boolean;\n /**\n * Subscribes to match-state changes.\n *\n * @param handler - Called on each `change` of the query.\n */\n addChangeListener(handler: (event: MediaQueryListEvent) => void): void;\n}\n\n/**\n * Boxes a live `DOMRect` into a plain {@link Rect}, preserving every edge.\n */\nfunction toRect(domRect: DOMRect): Rect {\n return {\n x: domRect.x,\n y: domRect.y,\n width: domRect.width,\n height: domRect.height,\n top: domRect.top,\n left: domRect.left,\n right: domRect.right,\n bottom: domRect.bottom\n };\n}\n\n/**\n * Production {@link DOMSink}: every method is a one-line pass-through to the\n * native DOM, behaving bit-for-bit like the pre-seam direct writes.\n *\n * @category Core\n */\nexport class ProductionDOMSink implements DOMSink {\n /**\n * Timers scheduled through this sink that have not yet fired. Tracked so\n * `DOM.reset()` can disarm them: a pending `setTimeout` lives in the host's\n * scheduler, so discarding the sink object leaves it running.\n */\n private readonly _timers = new Set<TimerId>();\n\n /** Selector → rule for the sheet in `_indexedSheet`. Empty until first use. */\n private _ruleIndex: Map<string, CSSStyleRule> = new Map();\n\n /** The sheet `_ruleIndex` describes; `null` before the first build. */\n private _indexedSheet: CSSStyleSheet | null = null;\n\n /**\n * Applies a batch of mutations to one element with a single handle resolve.\n * The hot-path primitive — a layout commit (width + height + classes + an\n * attribute) costs one `Map.get`, not one per write.\n *\n * @param handle - The target element handle.\n * @param patch - The batch of mutations.\n */\n apply(handle: Handle, patch: ElementPatch): void {\n applyPatchTo(_registry.resolve(handle) as HTMLElement, patch);\n }\n\n /**\n * Fluent convenience that accumulates a patch and flushes it through a\n * single {@link ProductionDOMSink.apply}. For cold call sites — it allocates\n * one builder per edit.\n *\n * @param handle - The target element handle.\n * @returns A builder whose `commit()` performs the single resolve.\n */\n edit(handle: Handle): PatchBuilder {\n return new PatchBuilder((patch) => this.apply(handle, patch));\n }\n\n /**\n * Releases an owned (retained) handle at its element's dispose site.\n *\n * @param handle - The handle to release.\n */\n release(handle: Handle): void {\n _registry.release(handle);\n }\n\n /** @inheritDoc */\n setRuleStyles(rule: CSSStyleRule, styles: Record<string, string | null>): void {\n const keys = Object.keys(styles);\n\n if (keys.length === 0) {\n return;\n }\n\n const scratch = keys.length === 1 ? null : scratchDeclaration();\n\n // One declaration is already one mutation, and the headless path (no\n // document, so no scratch element) falls back to the same direct writes.\n if (!scratch) {\n for (const key of keys) {\n writeDeclaration(rule.style, key, styles[key]);\n }\n\n return;\n }\n\n scratch.cssText = rule.style.cssText;\n\n for (const key of keys) {\n writeDeclaration(scratch, key, styles[key]);\n }\n\n rule.style.cssText = scratch.cssText;\n }\n\n /** @inheritDoc */\n ensureStyleRule(selector: string): CSSStyleRule {\n const sheet = this.mainSheet();\n const index = this.ruleIndex(sheet);\n const cached = index.get(selector);\n\n if (cached) {\n return cached;\n }\n\n const insertedAt = sheet.insertRule(selector + \"{}\", sheet.cssRules.length);\n const rule = sheet.cssRules[insertedAt] as CSSStyleRule;\n\n index.set(selector, rule);\n\n return rule;\n }\n\n /** @inheritDoc */\n deleteStyleRule(selector: string): void {\n // Best-effort cleanup reached from the component GC finalizer, which runs\n // decoupled from the DOM lifecycle: at GC time this production sink may be\n // active in a headless environment (the node test env, or after a\n // DOM.reset()). With no document there is no shared sheet and nothing to\n // delete, so no-op rather than dereference `document` in `mainSheet()`.\n if (typeof document === \"undefined\") {\n return;\n }\n\n const sheet = this.mainSheet();\n const index = this.ruleIndex(sheet);\n const rule = index.get(selector);\n\n if (!rule) {\n return;\n }\n\n index.delete(selector);\n\n for (let idx = 0; idx < sheet.cssRules.length; idx += 1) {\n if (sheet.cssRules[idx] === rule) {\n sheet.deleteRule(idx);\n return;\n }\n }\n }\n\n /** @inheritDoc */\n ensureKeyframes(name: string, body: string): void {\n const sheet = this.mainSheet();\n\n for (let idx = 0; idx < sheet.cssRules.length; idx += 1) {\n const rule = sheet.cssRules[idx] as CSSKeyframesRule;\n\n if (rule.type === CSSRule.KEYFRAMES_RULE && rule.name === name) {\n return;\n }\n }\n\n sheet.insertRule('@keyframes ' + name + ' { ' + body + ' }', sheet.cssRules.length);\n }\n\n /**\n * Returns the selector → rule index for `sheet`, building it with one walk\n * of `cssRules` the first time this sheet is seen and reusing it on every\n * later call while `sheet` stays the same object. Building from the live\n * sheet — rather than starting empty — is what keeps a fresh sink (e.g.\n * after `DOM.reset()`, which replaces the sink but not the `<style\n * id=\"Base\">` element) honest about rules a previous sink already left on\n * it. Assumes a single writer: a second `ProductionDOMSink` concurrently\n * writing the same sheet would keep its own index and not see this one's\n * inserts.\n *\n * @param sheet - The sheet to index.\n */\n private ruleIndex(sheet: CSSStyleSheet): Map<string, CSSStyleRule> {\n if (this._indexedSheet === sheet) {\n return this._ruleIndex;\n }\n\n const index = new Map<string, CSSStyleRule>();\n\n for (let idx = 0; idx < sheet.cssRules.length; idx += 1) {\n const rule = sheet.cssRules[idx];\n\n if (rule.type === CSSRule.STYLE_RULE) {\n index.set((rule as CSSStyleRule).selectorText, rule as CSSStyleRule);\n }\n }\n\n this._ruleIndex = index;\n this._indexedSheet = sheet;\n\n return index;\n }\n\n /**\n * Returns the framework's shared `<style id=\"Base\">` stylesheet, creating\n * the `<head>` and `<style>` element on first call. The lone place the\n * framework touches a `CSSStyleSheet` — relocated here from `StyleTarget`\n * so the stylesheet plumbing lives behind the seam.\n */\n private mainSheet(): CSSStyleSheet {\n let head = document.getElementsByTagName(\"head\")[0] as HTMLHeadElement;\n\n if (!head) {\n head = document.createElement(\"head\");\n document.appendChild(head);\n }\n\n let style: HTMLStyleElement | null = null;\n const styles = head.getElementsByTagName(\"style\");\n\n for (let idx = 0; idx < styles.length; idx += 1) {\n if (styles[idx].id === \"Base\") {\n style = styles[idx];\n }\n }\n\n if (!style) {\n style = document.createElement(\"style\");\n style.id = \"Base\";\n head.appendChild(style);\n }\n\n return style.sheet as CSSStyleSheet;\n }\n\n /** @inheritDoc */\n createElement(tag: string): Handle {\n return _registry.retain(document.createElement(tag));\n }\n\n /** @inheritDoc */\n createElementNS(ns: string, tag: string): Handle {\n return _registry.retain(document.createElementNS(ns, tag));\n }\n\n /** @inheritDoc */\n appendChild(parent: Handle, child: Handle): void {\n _registry.resolve(parent).appendChild(_registry.resolve(child));\n }\n\n /** @inheritDoc */\n removeChild(parent: Handle, child: Handle): void {\n _registry.resolve(parent).removeChild(_registry.resolve(child));\n }\n\n /** @inheritDoc */\n removeElement(handle: Handle): void {\n (_registry.resolve(handle) as Element).remove();\n }\n\n /** @inheritDoc */\n focus(handle: Handle, options?: { preventScroll?: boolean }): void {\n (_registry.resolve(handle) as HTMLElement).focus(options);\n }\n\n /** @inheritDoc */\n requestSubmit(handle: Handle): void {\n (_registry.resolve(handle) as HTMLFormElement).requestSubmit();\n }\n\n /** @inheritDoc */\n blur(handle: Handle): void {\n (_registry.resolve(handle) as HTMLElement).blur();\n }\n\n /** @inheritDoc */\n setValue(handle: Handle, value: string): void {\n (_registry.resolve(handle) as HTMLInputElement).value = value;\n }\n\n /** @inheritDoc */\n setSelectionRange(handle: Handle, start: number, end: number): void {\n (_registry.resolve(handle) as HTMLInputElement).setSelectionRange(start, end);\n }\n\n /** @inheritDoc */\n setLocationHash(hash: string): void {\n location.hash = hash;\n }\n\n /** @inheritDoc */\n replaceLocationHash(hash: string): void {\n const href = location.href;\n const hashIndex = href.indexOf('#');\n const base = hashIndex === -1 ? href : href.slice(0, hashIndex);\n\n location.replace(base + hash);\n }\n\n /** @inheritDoc */\n pushHistoryPath(url: string): void {\n history.pushState(null, \"\", url);\n }\n\n /** @inheritDoc */\n replaceHistoryPath(url: string): void {\n history.replaceState(null, \"\", url);\n }\n\n /** @inheritDoc */\n addListener<T extends Event = Event>(target: Handle, type: string, handler: (event: T) => void, options?: boolean | AddEventListenerOptions): void {\n _registry.resolve(target).addEventListener(type, handler as EventListener, options);\n }\n\n /** @inheritDoc */\n removeListener<T extends Event = Event>(target: Handle, type: string, handler: (event: T) => void, options?: boolean | EventListenerOptions): void {\n _registry.resolve(target).removeEventListener(type, handler as EventListener, options);\n }\n\n /** @inheritDoc */\n dispatchEvent(target: Handle, event: Event): void {\n _registry.resolve(target).dispatchEvent(event);\n }\n\n /** @inheritDoc */\n dispatchCustomEvent(target: Handle, type: string, init?: CustomEventInit): void {\n _registry.resolve(target).dispatchEvent(new CustomEvent(type, init));\n }\n\n /** @inheritDoc */\n requestAnimationFrame(callback: FrameRequestCallback): number {\n return requestAnimationFrame(callback);\n }\n\n /** @inheritDoc */\n cancelAnimationFrame(handle: number): void {\n cancelAnimationFrame(handle);\n }\n\n /** @inheritDoc */\n setTimeout(callback: () => void, delayMs: number): TimerId {\n const id = setTimeout(() => {\n this._timers.delete(id);\n callback();\n }, delayMs);\n\n this._timers.add(id);\n\n return id;\n }\n\n /** @inheritDoc */\n clearTimeout(id: TimerId): void {\n this._timers.delete(id);\n clearTimeout(id);\n }\n\n /** @inheritDoc */\n clearAllTimeouts(): void {\n for (const id of this._timers) {\n clearTimeout(id);\n }\n\n this._timers.clear();\n }\n\n /** @inheritDoc */\n setId(handle: Handle, id: string): void {\n (_registry.resolve(handle) as Element).id = id;\n }\n\n /** @inheritDoc */\n insertBefore(parent: Handle, node: Handle, reference: Handle | null): void {\n _registry.resolve(parent).insertBefore(\n _registry.resolve(node),\n reference === null ? null : _registry.resolve(reference)\n );\n }\n\n /** @inheritDoc */\n createDocumentFragment(): Handle {\n return _registry.retain(document.createDocumentFragment());\n }\n\n /** @inheritDoc */\n click(handle: Handle): void {\n (_registry.resolve(handle) as HTMLElement).click();\n }\n\n /** @inheritDoc */\n setPointerCapture(handle: Handle, pointerId: number): void {\n (_registry.resolve(handle) as Element).setPointerCapture(pointerId);\n }\n\n /** @inheritDoc */\n releasePointerCapture(handle: Handle, pointerId: number): void {\n (_registry.resolve(handle) as Element).releasePointerCapture(pointerId);\n }\n\n /** @inheritDoc */\n getContext(handle: Handle, contextId: string, options?: unknown): RenderingContext | null {\n return (_registry.resolve(handle) as HTMLCanvasElement).getContext(contextId, options);\n }\n\n /** @inheritDoc */\n mountView<T>(handle: Handle, factory: (parent: HTMLElement) => T): T | null {\n return factory(_registry.resolve(handle) as HTMLElement);\n }\n\n /** @inheritDoc */\n mediaPlay(handle: Handle): void {\n // The play() promise rejects on an autoplay-policy block; playback state\n // is observed through media events, so the promise is intentionally void.\n void (_registry.resolve(handle) as HTMLMediaElement).play().catch(() => {});\n }\n\n /** @inheritDoc */\n mediaPause(handle: Handle): void {\n (_registry.resolve(handle) as HTMLMediaElement).pause();\n }\n\n /** @inheritDoc */\n setCurrentTime(handle: Handle, seconds: number): void {\n (_registry.resolve(handle) as HTMLMediaElement).currentTime = seconds;\n }\n\n /** @inheritDoc */\n setVolume(handle: Handle, value: number): void {\n (_registry.resolve(handle) as HTMLMediaElement).volume = value;\n }\n\n /** @inheritDoc */\n setMuted(handle: Handle, muted: boolean): void {\n (_registry.resolve(handle) as HTMLMediaElement).muted = muted;\n }\n\n /** @inheritDoc */\n setPlaybackRate(handle: Handle, rate: number): void {\n (_registry.resolve(handle) as HTMLMediaElement).playbackRate = rate;\n }\n\n /** @inheritDoc */\n requestFullscreen(handle: Handle): void {\n // The transition is observed through fullscreenchange; a rejected request\n // (no user gesture) is swallowed rather than surfaced as an unhandled reject.\n void (_registry.resolve(handle) as HTMLElement).requestFullscreen().catch(() => {});\n }\n\n /** @inheritDoc */\n exitFullscreen(): void {\n if (document.fullscreenElement) {\n void document.exitFullscreen().catch(() => {});\n }\n }\n}\n\n/**\n * Production {@link DOMSource}: reads the live DOM and delegates text\n * measurement to the existing {@link Util} canvas/probe code.\n *\n * @category Core\n */\nexport class ProductionDOMSource implements DOMSource {\n /**\n * Converts a raw browser node arriving at an event boundary into a (weak)\n * handle. The one place a raw target legitimately enters the seam from\n * outside — the event system hands it `evnt.target`, and the handle is\n * interned so no call site downstream holds the raw node.\n *\n * @param target - The browser-supplied event target.\n * @returns Its canonical handle.\n */\n intern(target: EventTarget): Handle {\n return _registry.intern(target as Node);\n }\n\n /** @inheritDoc */\n isNode(value: unknown): value is EventTarget {\n return value instanceof Node;\n }\n\n /** @inheritDoc */\n isElement(value: unknown): value is EventTarget {\n return value instanceof Element;\n }\n\n /** @inheritDoc */\n escapeSelector(value: string): string {\n // Real browsers always ship `CSS.escape`; guard for environments that\n // don't (jsdom, some SSR contexts) with an equivalent backslash escape\n // of every non-identifier character.\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") {\n return CSS.escape(value);\n }\n\n return value.replace(/[^\\w-]/g, ch => \"\\\\\" + ch);\n }\n\n /** @inheritDoc */\n getViewportRect(component: Component): Rect {\n return toRect((_registry.resolve(component.getElement()!) as HTMLElement).getBoundingClientRect());\n }\n\n /** @inheritDoc */\n getElementRect(handle: Handle): Rect {\n return toRect((_registry.resolve(handle) as Element).getBoundingClientRect());\n }\n\n /** @inheritDoc */\n measureText(text: string, options: TextMeasureOptions = {}): TextMetrics {\n const {\n fontFamily = \"var(--ts-ui-font-family, system-ui, sans-serif)\",\n fontSize = \"var(--ts-ui-font-size, 14px)\",\n fontWeight = \"normal\",\n fontStyle = \"normal\",\n fontVariant = \"normal\",\n fontStretch = \"normal\",\n lineHeight = \"calc(1em + var(--ts-ui-line-padding, 2px))\",\n maxWidth,\n } = options;\n\n const probe = document.createElement(\"span\");\n\n _applyProbeStyles(probe, {\n position: \"fixed\",\n visibility: \"hidden\",\n // With a wrap width the probe must honour `\\n` and soft-wrap so the\n // measured height covers every visual line; otherwise stay on a\n // single `nowrap` line for the natural-size measurement.\n whiteSpace: maxWidth === undefined ? \"nowrap\" : \"pre-wrap\",\n width: maxWidth === undefined ? \"\" : `${maxWidth}px`,\n fontFamily, fontSize, fontWeight, fontStyle, fontVariant, fontStretch, lineHeight,\n });\n\n probe.textContent = text;\n\n const ref = document.createElement(\"span\");\n\n _applyProbeStyles(ref, {\n display: \"inline-block\",\n width: \"0\",\n height: \"0\",\n verticalAlign: \"baseline\",\n });\n\n probe.appendChild(ref);\n document.body.appendChild(probe);\n\n const probeRect = probe.getBoundingClientRect();\n const refRect = ref.getBoundingClientRect();\n\n document.body.removeChild(probe);\n\n return {\n width: Math.ceil(probeRect.width),\n height: Math.ceil(probeRect.height),\n baseline: Math.round(refRect.top - probeRect.top),\n };\n }\n\n /** @inheritDoc */\n measureTextWidths(texts: string[], options: TextMeasureOptions = {}): number[] {\n if (texts.length === 0) {\n return [];\n }\n\n const {\n fontFamily = \"var(--ts-ui-font-family, system-ui, sans-serif)\",\n fontSize = \"var(--ts-ui-font-size, 14px)\",\n fontWeight = \"normal\",\n fontStyle = \"normal\",\n fontVariant = \"normal\",\n fontStretch = \"normal\",\n } = options;\n\n const wrapper = document.createElement(\"div\");\n\n _applyProbeStyles(wrapper, { position: \"fixed\", visibility: \"hidden\", whiteSpace: \"nowrap\" });\n\n const probes = texts.map(text => {\n const probe = document.createElement(\"span\");\n\n _applyProbeStyles(probe, {\n display: \"inline-block\", whiteSpace: \"nowrap\",\n fontFamily, fontSize, fontWeight, fontStyle, fontVariant, fontStretch,\n });\n\n probe.textContent = text;\n wrapper.appendChild(probe);\n\n return probe;\n });\n\n document.body.appendChild(wrapper);\n\n // One layout flush: the first read forces it, and nothing mutates the\n // DOM between reads, so the rest are served from the same computed layout.\n const widths = probes.map(p => Math.ceil(p.getBoundingClientRect().width));\n\n document.body.removeChild(wrapper);\n\n return widths;\n }\n\n /** @inheritDoc */\n resolveFontSizePx(fontSizeCSS: string): number {\n const probe = document.createElement(\"span\");\n\n _applyProbeStyles(probe, { position: \"fixed\", visibility: \"hidden\", fontSize: fontSizeCSS });\n\n document.body.appendChild(probe);\n const px = parseFloat(getComputedStyle(probe).fontSize);\n document.body.removeChild(probe);\n\n return isNaN(px) ? 14 : px; // 14 mirrors the base font fallback\n }\n\n /** @inheritDoc */\n measureFontMetrics(): { ascent: number; descent: number; capTop: number } {\n if (_metricsCtx === null) {\n _metricsCtx = document.createElement(\"canvas\").getContext(\"2d\");\n }\n\n const ctx = _metricsCtx as CanvasRenderingContext2D;\n\n // 14px / system-ui mirror the `--ts-ui-font-*` defaults shipped by the\n // themes; they only apply when the computed value is empty (pre-apply).\n const family = this.getThemeVar(\"--ts-ui-font-family\") || \"system-ui, sans-serif\";\n const size = this.getThemeVar(\"--ts-ui-font-size\") || \"14px\";\n\n ctx.font = `normal normal ${size} ${family}`;\n\n const m = ctx.measureText(\"X\");\n\n const hasFontBox = typeof m.fontBoundingBoxAscent === \"number\";\n const ascent = hasFontBox ? m.fontBoundingBoxAscent : m.actualBoundingBoxAscent;\n const descent = hasFontBox ? m.fontBoundingBoxDescent : m.actualBoundingBoxDescent;\n\n return { ascent, descent, capTop: m.actualBoundingBoxAscent };\n }\n\n /** @inheritDoc */\n getThemeVar(name: string): string {\n return getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n }\n\n /** @inheritDoc */\n getViewportSize(): Size {\n const width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n const height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n\n return { width, height };\n }\n\n /** @inheritDoc */\n getScrollBarWidth(): number {\n if (_scrollBarWidth >= 0) {\n return _scrollBarWidth;\n }\n\n const outer = document.createElement(\"div\");\n\n _applyProbeStyles(outer, {\n position: \"absolute\",\n top: \"-1000px\",\n left: \"-1000px\",\n width: \"100px\",\n height: \"50px\",\n overflow: \"hidden\",\n });\n\n const inner = document.createElement(\"div\");\n\n _applyProbeStyles(inner, { width: \"100%\", height: \"200px\" });\n\n outer.appendChild(inner);\n document.body.appendChild(outer);\n\n const widthNoScroll = inner.offsetWidth;\n\n _applyProbeStyles(outer, { overflow: \"auto\" });\n\n const widthScroll = inner.offsetWidth;\n\n document.body.removeChild(outer);\n\n _scrollBarWidth = widthNoScroll - widthScroll;\n\n return _scrollBarWidth;\n }\n\n /** @inheritDoc */\n getDevicePixelRatio(): number {\n return window.devicePixelRatio || 1;\n }\n\n /** @inheritDoc */\n isModelled(): boolean {\n return false;\n }\n\n /** @inheritDoc */\n getScrollLeft(handle: Handle): number {\n return (_registry.resolve(handle) as Element).scrollLeft;\n }\n\n /** @inheritDoc */\n getScrollTop(handle: Handle): number {\n return (_registry.resolve(handle) as Element).scrollTop;\n }\n\n /** @inheritDoc */\n getScrollMetrics(handle: Handle): ScrollMetrics {\n const element = _registry.resolve(handle) as Element;\n\n return {\n scrollTop: element.scrollTop,\n scrollLeft: element.scrollLeft,\n scrollWidth: element.scrollWidth,\n scrollHeight: element.scrollHeight,\n clientWidth: element.clientWidth,\n clientHeight: element.clientHeight\n };\n }\n\n /** @inheritDoc */\n getOffsetSize(handle: Handle): OffsetSize {\n const el = _registry.resolve(handle) as HTMLElement;\n\n return {\n offsetTop: el.offsetTop,\n offsetHeight: el.offsetHeight\n };\n }\n\n /** @inheritDoc */\n isConnected(handle: Handle): boolean {\n return (_registry.resolve(handle) as Element).isConnected;\n }\n\n /** @inheritDoc */\n getValue(handle: Handle): string {\n return (_registry.resolve(handle) as HTMLInputElement).value;\n }\n\n /** @inheritDoc */\n getActiveElement(): Handle | null {\n const active = document.activeElement;\n\n return active === null ? null : _registry.intern(active);\n }\n\n /** @inheritDoc */\n getDocumentSelection(): DocumentSelectionRange | null {\n const sel = window.getSelection();\n if (!sel || sel.isCollapsed || sel.rangeCount === 0) {\n return null;\n }\n\n const range = sel.getRangeAt(0);\n const startIsText = range.startContainer.nodeType === Node.TEXT_NODE;\n const endIsText = range.endContainer.nodeType === Node.TEXT_NODE;\n\n return {\n startContainer: _registry.intern(range.startContainer),\n startOffset: startIsText ? range.startOffset : null,\n endContainer: _registry.intern(range.endContainer),\n endOffset: endIsText ? range.endOffset : null,\n };\n }\n\n /** @inheritDoc */\n matchMedia(query: string): MediaQueryResult {\n // Non-browser environments (SSR, workers, bare Node) have no\n // `matchMedia`; degrade to an inert result so callers need no\n // environment guard of their own — the capability check lives here, in\n // the seam, rather than leaking a raw `window` probe into call sites.\n if (typeof matchMedia !== \"function\") {\n return { matches: false, addChangeListener: (): void => {} };\n }\n\n const mql = matchMedia(query);\n\n return {\n matches: mql.matches,\n addChangeListener(handler: (event: MediaQueryListEvent) => void): void {\n mql.addEventListener(\"change\", handler);\n }\n };\n }\n\n /** @inheritDoc */\n isWindow(target: Handle | null): boolean {\n return target !== null && _registry.resolve(target) === (window as unknown as Node);\n }\n\n /** @inheritDoc */\n getWindow(): Handle {\n return _registry.intern(window as unknown as Node);\n }\n\n /** @inheritDoc */\n getLocationHash(): string {\n return location.hash;\n }\n\n /** @inheritDoc */\n getLocationPathname(): string {\n return location.pathname;\n }\n\n /** @inheritDoc */\n getLocationSearch(): string {\n return location.search;\n }\n\n /** @inheritDoc */\n contains(ancestor: Handle, node: Handle | null): boolean {\n return _registry.resolve(ancestor).contains(node === null ? null : _registry.resolve(node));\n }\n\n /** @inheritDoc */\n querySelector(root: Handle, selector: string): Handle | null {\n const found = (_registry.resolve(root) as ParentNode).querySelector(selector);\n\n return found === null ? null : _registry.intern(found);\n }\n\n /** @inheritDoc */\n querySelectorAll(root: Handle, selector: string): Handle[] {\n return Array.from((_registry.resolve(root) as ParentNode).querySelectorAll(selector), (node) => _registry.intern(node));\n }\n\n /** @inheritDoc */\n matches(handle: Handle, selector: string): boolean {\n return (_registry.resolve(handle) as Element).matches(selector);\n }\n\n /** @inheritDoc */\n getParentElement(handle: Handle): Handle | null {\n const parent = (_registry.resolve(handle) as Element).parentElement;\n\n return parent === null ? null : _registry.intern(parent);\n }\n\n /** @inheritDoc */\n getParentNode(handle: Handle): Handle | null {\n const parent = _registry.resolve(handle).parentNode;\n\n return parent === null ? null : _registry.intern(parent);\n }\n\n /** @inheritDoc */\n getFirstChild(handle: Handle): Handle | null {\n const child = _registry.resolve(handle).firstChild;\n\n return child === null ? null : _registry.intern(child);\n }\n\n /** @inheritDoc */\n getBorderWidths(handle: Handle): { top: string; right: string; bottom: string; left: string } {\n const cs = getComputedStyle(_registry.resolve(handle) as Element);\n\n return {\n top: cs.borderTopWidth,\n right: cs.borderRightWidth,\n bottom: cs.borderBottomWidth,\n left: cs.borderLeftWidth\n };\n }\n\n /** @inheritDoc */\n getComputedOverflow(handle: Handle): { overflow: string; overflowX: string; overflowY: string } {\n const cs = getComputedStyle(_registry.resolve(handle) as Element);\n\n return {\n overflow: cs.overflow,\n overflowX: cs.overflowX,\n overflowY: cs.overflowY\n };\n }\n\n /** @inheritDoc */\n getInlineStyle(handle: Handle, key: string): string {\n const style = (_registry.resolve(handle) as HTMLElement).style;\n\n if (key.includes(\"-\")) {\n return style.getPropertyValue(key);\n }\n\n return (style as any)[key];\n }\n\n /** @inheritDoc */\n getDocumentElement(): Handle {\n return _registry.intern(document.documentElement);\n }\n\n /** @inheritDoc */\n getBody(): Handle {\n return _registry.intern(document.body);\n }\n\n /** @inheritDoc */\n getHead(): Handle {\n return _registry.intern(document.head);\n }\n\n /** @inheritDoc */\n onFontsReady(callback: () => void): void {\n const fonts = document.fonts;\n\n // Older engines without the CSS Font Loading API: the fallback\n // measurement is the only one we get, so leave it standing.\n if (!fonts) {\n return;\n }\n\n // `loadingdone`, deliberately not `fonts.ready`: `ready` is a snapshot\n // of the set's *current* state, and the set is idle at the moment the\n // framework subscribes — `ensureFontLoaded` injected the `@font-face`\n // rules microseconds earlier and no text has been laid out with them\n // yet, so the browser has not begun fetching. A lone `ready.then`\n // therefore resolves on the very next microtask, hundreds of ms before\n // the real face arrives, and re-measures against the same fallback it\n // exists to replace. `loadingdone` fires once each batch of faces\n // settles (loaded or errored), so it catches the swap-in itself — and\n // any later batch, such as a second subset or a lazily used family.\n fonts.addEventListener('loadingdone', () => callback());\n }\n\n /** @inheritDoc */\n startFontLoad(family: string): boolean {\n const fonts = document.fonts;\n\n if (!fonts) {\n return false;\n }\n\n // `load` matches faces by the CSS font shorthand and by the characters\n // its second argument needs; the default (a single space) selects the\n // subset covering the Basic Latin range, which is the one virtually all\n // UI text renders from. Any further subset stays lazy and is picked up\n // by the `loadingdone` batch it settles in.\n //\n // The size in the shorthand is required syntax, not a constraint: one\n // variable face covers every size and the 200-800 weight range, so this\n // activates the same file the first laid-out text would have. A\n // rejection means the face is unavailable, which the `swap` fallback\n // already covers — swallow it rather than surfacing an unhandled\n // rejection for a purely opportunistic fetch.\n fonts.load(`14px \"${family}\"`).catch(() => {});\n\n return true;\n }\n\n /** @inheritDoc */\n getElementById(id: string): Handle | null {\n const found = document.getElementById(id);\n\n return found === null ? null : _registry.intern(found);\n }\n\n /** @inheritDoc */\n getId(handle: Handle): string {\n return (_registry.resolve(handle) as Element).id;\n }\n\n /** @inheritDoc */\n getDataset(handle: Handle, key: string): string | undefined {\n return (_registry.resolve(handle) as HTMLElement).dataset[key];\n }\n\n /** @inheritDoc */\n getTagName(handle: Handle): string {\n return (_registry.resolve(handle) as Element).tagName;\n }\n\n /** @inheritDoc */\n hasAttribute(handle: Handle, key: string): boolean {\n return (_registry.resolve(handle) as Element).hasAttribute(key);\n }\n\n /** @inheritDoc */\n getAttribute(handle: Handle, key: string): string | null {\n return (_registry.resolve(handle) as Element).getAttribute(key);\n }\n\n /** @inheritDoc */\n getNaturalSize(handle: Handle): { width: number; height: number } {\n const image = _registry.resolve(handle) as HTMLImageElement;\n\n return { width: image.naturalWidth, height: image.naturalHeight };\n }\n\n /** @inheritDoc */\n getMediaState(handle: Handle): MediaState {\n const media = _registry.resolve(handle) as HTMLMediaElement;\n\n return {\n currentTime: media.currentTime,\n duration: media.duration,\n paused: media.paused,\n ended: media.ended,\n volume: media.volume,\n muted: media.muted,\n playbackRate: media.playbackRate,\n };\n }\n\n /** @inheritDoc */\n getFullscreenElement(): Handle | null {\n const element = document.fullscreenElement;\n\n return element ? _registry.intern(element) : null;\n }\n\n /** @inheritDoc */\n getFiles(handle: Handle): FileList | null {\n return (_registry.resolve(handle) as HTMLInputElement).files;\n }\n\n /** @inheritDoc */\n hasPointerCapture(handle: Handle, pointerId: number): boolean {\n return (_registry.resolve(handle) as Element).hasPointerCapture(pointerId);\n }\n\n /** @inheritDoc */\n elementsFromPoint(x: number, y: number): Handle[] {\n return Array.from(document.elementsFromPoint(x, y), (node) => _registry.intern(node));\n }\n}\n\n/**\n * The shape of the global {@link DOM} swap point.\n *\n * @category Core\n */\nexport interface DOMSeams {\n /** The active write seam. Defaults to a {@link ProductionDOMSink}. */\n sink: DOMSink;\n /** The active read seam. Defaults to a {@link ProductionDOMSource}. */\n source: DOMSource;\n /**\n * Swaps in test implementations. Omitted seams keep their current value.\n *\n * @param impls - The sink and/or source to install.\n */\n install(impls: { sink?: DOMSink; source?: DOMSource }): void;\n /** Restores the production implementations. */\n reset(): void;\n}\n\n/**\n * Global swap point for the DOM seams, mirroring `ThemeManager`'s active-theme\n * singleton. Production code reads {@link DOM.sink} / {@link DOM.source}; test\n * setup swaps them via {@link DOM.install} and restores via {@link DOM.reset}.\n *\n * @remarks A mutable-property `const` object rather than a `namespace` with\n * `export let`: the latter is not supported by the Oxc transformer the Vite\n * build uses. The binding is stable; the `sink` / `source` properties are the\n * swappable state.\n *\n * @category Core\n */\nexport const DOM: DOMSeams = {\n sink: new ProductionDOMSink(),\n source: new ProductionDOMSource(),\n\n install(impls: { sink?: DOMSink; source?: DOMSource }): void {\n if (impls.sink) {\n DOM.sink = impls.sink;\n }\n\n if (impls.source) {\n DOM.source = impls.source;\n }\n },\n\n reset(): void {\n // Disarm before anything is rebuilt. A pending timer lives in the host\n // scheduler and reads the *current* seams when it fires, so one left\n // armed here would run against the fresh registry with a handle minted\n // against the old one — the use-after-free `resolve` throws on.\n DOM.sink.clearAllTimeouts();\n\n // Rebuild the shared registry alongside the seams so a test never\n // resolves a handle minted against the previous DOM.\n _registry = new HandleRegistry();\n DOM.sink = new ProductionDOMSink();\n DOM.source = new ProductionDOMSource();\n },\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./DOM-C-Edb3tA.js";import{l as t,n,t as r}from"./Position-BwtxouxK.js";import{S as i,h as a,t as o,v as s}from"./Component-B0ShfPVi.js";import{t as c}from"./Container-abY5Ww3W.js";import{t as l}from"./Glyph-_VeBacS2.js";import{t as u}from"./Panel-Cy1pdlWO.js";import{a as d}from"./Tooltip-CUOJOqQi.js";import{n as f,t as p}from"./OverlayFade-3pof2AJH.js";import{t as ee}from"./Fit-BhlB-HAo.js";import{t as m}from"./Text-CMKnK9uB.js";import{n as h,r as g}from"./VBox-DfJPWXqc.js";import{c as _,l as v}from"./CheckboxMenuRow-CesLhSnp.js";import{t as y}from"./Placement-7kqdaK4Z.js";import{t as b}from"./Border-0DJFDiij.js";import{t as x}from"./Button-MpMIYBYJ.js";import{xmark as S}from"./glyphs/solid/xmark.es.js";import{circle_check as C}from"./glyphs/solid/circle_check.es.js";import{circle_info as w}from"./glyphs/solid/circle_info.es.js";import{triangle_exclamation as T}from"./glyphs/solid/triangle_exclamation.es.js";import{circle_exclamation as E}from"./glyphs/solid/circle_exclamation.es.js";var D=14,O=D/2*Math.SQRT2,k=Math.ceil(O)+2,A=6,j=5,M=120,N={insets:new n(5,5,5,5),placement:`auto`,dismissOn:`click-outside`,showArrow:!0,backgroundColor:`var(--ts-ui-popover-bg, rgb(255, 255, 255))`,foregroundColor:`var(--ts-ui-popover-color, rgb(0, 0, 0))`,border:{border:`1px solid var(--ts-ui-popover-border, rgb(200, 200, 200))`},borderRadius:`var(--ts-ui-popover-radius, 6px)`,shadow:`var(--ts-ui-popover-shadow, 2px 4px 12px rgba(0, 0, 0, 0.18))`},Popover=class extends c{_resolvedPlacement=`bottom`;_bodyComponent=null;_actionsRow=null;_fadeShowAnimation=null;_fadeHideAnimation=null;_anchorElement=null;_arrowComponent=null;_isOpen=!1;_scrollAncestors=[];_onWindowResize;_onScroll;constructor(e,t){super(e,{...N,...t??{}});let n=new h;n.setStretching(!0),this.setLayoutManager(n),this.setPosition(r.FIXED),this.setVisible(!1),this.setContain(`layout`),this.setOverflow(`visible`),this.getAria().setRole(`dialog`),this._onWindowResize=()=>this._reposition(),this._onScroll=()=>this._reposition(),this._title??=null,this._titleComponent??=null,this._onClose??=null}applyOptions(e){return super.applyOptions(e),this.setPlacement(e.placement??this.getPlacement()),this.setDismissOn(e.dismissOn??this.getDismissOn()),this.setShowArrow(e.showArrow??this.isShowArrow()),e.title!==void 0&&this.setTitle(e.title),e.onClose!==void 0&&(this._onClose=e.onClose),this}setPlacement(e){return this._placement=e,this}getPlacement(){return this._placement??this._defaultOptions.placement}setDismissOn(e){return this._dismissOn=e,this}getDismissOn(){return this._dismissOn??this._defaultOptions.dismissOn}setShowArrow(e){return this._showArrow=e,this._arrowComponent&&this._arrowComponent.setVisible(e),this}isShowArrow(){return this._showArrow??this._defaultOptions.showArrow}setTitle(e){return e===null?this.clearTitle():(this._title=e,this._titleComponent?this._titleComponent.setText(e):(this._titleComponent=new m(e),this._titleComponent.setFontWeight(`bold`),this.insertComponent(this._titleComponent,0)),this._reflowIfOpen(),this)}getTitle(){return this._title}clearTitle(){return this._titleComponent&&=(this.removeComponent(this._titleComponent),null),this._title=null,this._reflowIfOpen(),this}setBody(e){this._bodyComponent&&=(this.removeComponent(this._bodyComponent),null);let t=typeof e==`string`?new m(e):e;this._bodyComponent=t;let n=+!!this._titleComponent;return this.insertComponent(t,n),this._reflowIfOpen(),this}getBody(){return this._bodyComponent}addAction(e,t){this._actionsRow||(this._actionsRow=new o,this._actionsRow.setLayoutManager(new g),this.addComponent(this._actionsRow));let n=new x(e);return n.on(`action`,t),this._actionsRow.addComponent(n),this}clearActions(){return this._actionsRow&&=(this.removeComponent(this._actionsRow),null),this}_attachToElement(e){return this._anchorElement=e,this}attachToComponent(e){return this._attachToElement(e.getElement(!0))}show(){if(!this._anchorElement)return console.warn(`Popover.show(): no anchor attached; call attachToComponent first.`),this;this._isOpen=!0,d.register(this),this.setZIndex(d.getZIndex(this));let e=this.getElement(!0);return d.mount(e),_(this),this.ensureArrow(),this.setVisible(!0),this.doLayout(),this._reposition(),this._fadeShowAnimation?.cancel(),this._fadeShowAnimation=f(this,{durationMs:M}),this.attachRepositionListeners(),this}hide(){return this._isOpen?(this._isOpen=!1,this.detachRepositionListeners(),d.unregister(this),v(this),this._fadeHideAnimation?.cancel(),this._fadeHideAnimation=p(this,{durationMs:M}),this._onClose?.(),this):this}isOpen(){return this._isOpen}getLayerElement(){return this.getElement()??null}getDismissMode(){return this._dismissOn??this._defaultOptions.dismissOn}requestClose(){this.hide()}getAnchorElement(){return this._anchorElement}getBand(){return d.Band.Popover}doLayout(){return super.doLayout(),this._arrowComponent&&this._showArrow&&this._anchorElement&&this.positionArrow(),this}destructor(){this._isOpen&&this.hide(),this._fadeShowAnimation?.cancel(),this._fadeShowAnimation=null,this._fadeHideAnimation?.cancel(),this._fadeHideAnimation=null,this._arrowComponent?.dispose(),this._anchorElement=null,this._titleComponent=null,this._bodyComponent=null,this._actionsRow=null,this._arrowComponent=null,this._onClose=null,super.destructor()}_reflowIfOpen(){this._isOpen&&(this.doLayout(),this._reposition())}_reposition(){if(!this._anchorElement)return;let n=e.source.getElementRect(this._anchorElement);if(n.width===0&&n.height===0){this.hide();return}let r=this.getPreferredSize(),i=r?.width??this.getWidth(),a=r?.height??this.getHeight(),o=e.source.getViewportSize(),s=this.resolvePlacement(n,i,a,o);this._resolvedPlacement=s;let c=0,l=0;s===`top`?(c=n.left+(n.width-i)/2,l=n.top-a-k):s===`bottom`?(c=n.left+(n.width-i)/2,l=n.bottom+k):s===`left`?(c=n.left-i-k,l=n.top+(n.height-a)/2):(c=n.right+k,l=n.top+(n.height-a)/2);let u=j,d=o.width-i-j,f=j,p=o.height-a-j;s===`right`?u+=O:s===`left`?d-=O:s===`bottom`?f+=O:p-=O,c=t.clamp(c,u,d),l=t.clamp(l,f,p),this.setX(c),this.setY(l),this.setWidth(i),this.setHeight(a),this._arrowComponent&&this._showArrow&&this.positionArrow()}resolvePlacement(e,t,n,r){let i=e.top,a=r.height-e.bottom,o=e.left,s=r.width-e.right;if(this._placement===`auto`){let e=n+k,r=t+k,c=[{side:`bottom`,space:a,need:e},{side:`top`,space:i,need:e},{side:`right`,space:s,need:r},{side:`left`,space:o,need:r}],l=c.filter(e=>e.space>=e.need),u=l.length>0?l:c;return u.sort((e,t)=>t.space-e.space),u[0].side}let fits=e=>e===`top`?i>=n+k:e===`bottom`?a>=n+k:e===`left`?o>=t+k:s>=t+k;if(fits(this._placement))return this._placement;let c={top:`bottom`,bottom:`top`,left:`right`,right:`left`}[this._placement];return console.warn(`Popover: explicit placement "${this._placement}" overflows the viewport; falling back to "${c}".`),c}ensureArrow(){if(this._arrowComponent)return;let t=new o,n=D;t.setBackgroundColor(`var(--ts-ui-popover-bg, rgb(255, 255, 255))`),t.setWidth(n),t.setHeight(n),t.setTransform(`rotate(45deg)`),t.setPointerEvents(`none`),t.setVisible(this._showArrow),this._arrowComponent=t;let r=this.getElement(!0);e.sink.insertBefore(r,t.getElement(!0),e.source.getFirstChild(r))}positionArrow(){if(!this._anchorElement||!this._arrowComponent)return;let t=e.source.getElementRect(this._anchorElement),n=D,r=n/2,i=this.getX(),a=this.getY(),o=this.getWidth(),s=this.getHeight(),clamp=(e,t,n)=>Math.max(t,Math.min(e,n)),c=`var(--ts-ui-popover-border, rgb(200, 200, 200))`,l;l=this._resolvedPlacement===`bottom`?`inset 1px 0 0 ${c}, inset 0 1px 0 ${c}`:this._resolvedPlacement===`top`?`inset -1px 0 0 ${c}, inset 0 -1px 0 ${c}`:this._resolvedPlacement===`right`?`inset 1px 0 0 ${c}, inset 0 -1px 0 ${c}`:`inset 0 1px 0 ${c}, inset -1px 0 0 ${c}`,this._arrowComponent.setShadow(l);let u=e.source.getViewportSize(),d=this.getBorderSize();if(this._resolvedPlacement===`top`||this._resolvedPlacement===`bottom`){let e=t.left+t.width/2,a=Math.max(A,j-i+O-r),c=Math.min(o-n-A,u.width-j-i-r-O),l=clamp(e-i-r-d.left,a,c);this._arrowComponent.setX(l),this._resolvedPlacement===`bottom`?this._arrowComponent.setY(-7-d.top):this._arrowComponent.setY(s-r-d.top)}else{let e=t.top+t.height/2,i=Math.max(A,j-a+O-r),c=Math.min(s-n-A,u.height-j-a-r-O),l=clamp(e-a-r-d.top,i,c);this._arrowComponent.setY(l),this._resolvedPlacement===`right`?this._arrowComponent.setX(-7-d.left):this._arrowComponent.setX(o-r-d.left)}}attachRepositionListeners(){if(i.addViewportListener(this,`resize`,this._onWindowResize),this._anchorElement){this._scrollAncestors=this.collectScrollAncestors(this._anchorElement);for(let t of this._scrollAncestors)e.sink.addListener(t,`scroll`,this._onScroll,{passive:!0})}}detachRepositionListeners(){i.removeViewportListener(this,`resize`,this._onWindowResize);for(let t of this._scrollAncestors)e.sink.removeListener(t,`scroll`,this._onScroll);this._scrollAncestors=[]}collectScrollAncestors(t){let n=[],r=e.source.getParentElement(t);for(;r&&r!==e.source.getDocumentElement();){let t=e.source.getComputedOverflow(r),i=t.overflow+t.overflowX+t.overflowY;/(auto|scroll|overlay)/.test(i)&&n.push(r),r=e.source.getParentElement(r)}return n.push(e.source.getDocumentElement()),n}},P=a(Popover),F={},DialogBackdrop=class extends o{constructor(t,n){super(t,{...F,...n??{}});let i=e.source.getViewportSize();this.setPosition(r.FIXED),this.setX(0),this.setY(0),this.setWidth(i.width),this.setHeight(i.height),this.setZIndex(10100),this.setBackgroundColor(`var(--ts-ui-dialog-backdrop-bg)`)}addClickListener(e){return i.addListener(this,`click`,e),this}resize(){let t=e.source.getViewportSize();this.setWidth(t.width),this.setHeight(t.height)}destroy(){this.removeElement(),this.destructor()}},I=a(DialogBackdrop);l.register(S,C,w,T,E);var L=36,R=52,z=90,B=8,V=11,H=20,U=12,W=320,G=160,K=80,q={info:`circle-info`,success:`circle-check`,warning:`triangle-exclamation`,error:`circle-exclamation`},J=150,Y=`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`,te=4,X=4,ne=8,DialogTitleBar=class extends o{_titleText;_closeButton=null;_titleGlyph=null;constructor(e,t,r){super(),this.setBackgroundColor(`var(--ts-ui-body-bg)`),this.setBorder({border:`none`,borderBottom:`1px solid var(--ts-ui-dialog-border)`}),this.setPreferredSize({width:0,height:L}),this._titleText=new m(e),this._titleText.setFontWeight(`bold`),this._titleText.setOverflow(`hidden`),this._titleText.setTextOverflow(`ellipsis`),this._titleText.setWhiteSpace(`nowrap`),this._titleText.centerInHeight(28),this.addComponent(this._titleText),r&&(this._closeButton=new x({glyph:`xmark`}),this._closeButton.setInsets(new n(0,0,0,0)),this._closeButton.setBorder(`none`),this._closeButton.clearBackgroundImage(),this._closeButton.setBackgroundColor(`transparent`),this._closeButton.clearShadow(),this._closeButton.clearPressedShadow(),this._closeButton.clearHoverShadow(),this._closeButton.setHoverBackgroundColor(`var(--ts-ui-titlebar-btn-hover-bg, rgba(0, 0, 0, 0.08))`),this._closeButton.setPressedBackgroundColor(`var(--ts-ui-titlebar-btn-active-bg, rgba(0, 0, 0, 0.16))`),this._closeButton.clearHoverBackgroundImage(),this._closeButton.clearPressedBackgroundImage(),this._closeButton.setPreferredSize({width:H,height:H}),this.addComponent(this._closeButton),this._closeButton.on(`action`,t))}getCloseButton(){return this._closeButton}getTitleText(){return this._titleText}setGlyph(e){this._titleGlyph&&=(this.removeComponent(this._titleGlyph),null);let t=new l(e);return t.setPointerEvents(`none`),t.setPreferredSize({width:16,height:16}),this._titleGlyph=t,this.addComponent(t),this.doLayout(),this}clearGlyph(){return this._titleGlyph&&(this.removeComponent(this._titleGlyph),this._titleGlyph=null,this.doLayout()),this}getGlyph(){return this._titleGlyph}doLayout(){super.doLayout();let e=this.getContentBounds();if(!e)return this;let t=e.width,n=e.height,r=t-H-X,i=Math.floor((n-H)/2),a=this._closeButton?r:t-U,o=U;if(this._titleGlyph){let t=this._titleGlyph.getPreferredSize()??{width:16,height:16},r=Math.max(0,Math.floor((n-t.height)/2));this._titleGlyph.setX(e.x+U),this._titleGlyph.setY(e.y+r),this._titleGlyph.setWidth(t.width),this._titleGlyph.setHeight(t.height),o=U+t.width+ne}let s=Math.max(0,a-o-X),c=n-8;return this._titleText.setX(e.x+o),this._titleText.setY(e.y+te),this._titleText.setWidth(s),this._titleText.setHeight(c),this._closeButton&&(this._closeButton.setX(e.x+r),this._closeButton.setY(e.y+i),this._closeButton.setWidth(H),this._closeButton.setHeight(H),this._closeButton.doLayout()),this}},DialogButtonRow=class extends o{_buttons=[];constructor(e,t){super(),this.setBorder({border:`none`,borderTop:`1px solid var(--ts-ui-dialog-border)`}),this.setBackgroundColor(`var(--ts-ui-body-bg)`),this.setPreferredSize({width:0,height:R});for(let n of e){let e=new x(n.text,n.glyph===void 0?void 0:{glyph:n.glyph}),r=n.result??`cancel`;if(n.primary&&e.setBackgroundImage(`var(--ts-ui-toggle-selected-bg, rgb(200, 200, 200))`),n.glyph!==void 0){let t=e.getGlyph(),r=n.tint;t!==null&&r&&t.setForegroundColor(r)}e.on(`action`,()=>t(r)),this._buttons.push(e),this.addComponent(e)}}doLayout(){super.doLayout();let e=this.getContentBounds();if(!e)return this;let t=e.height-22,n=this._buttons.length*z+(this._buttons.length-1)*B,r=Math.round((e.width-n)/2);for(let n of this._buttons)n.setX(e.x+r),n.setY(e.y+V),n.setWidth(z),n.setHeight(t),n.doLayout(),r+=98;return this}},Z={Confirm:{text:`Confirm`,result:`confirm`,glyph:`circle-check`,tint:`var(--ts-ui-dialog-confirm-color)`},Ok:{text:`Ok`,result:`confirm`,glyph:`circle-check`,tint:`var(--ts-ui-dialog-confirm-color)`},Cancel:{text:`Cancel`,result:`cancel`,glyph:`xmark`,tint:`var(--ts-ui-dialog-cancel-color)`},Close:{text:`Close`,result:`close`,glyph:`xmark`,tint:`var(--ts-ui-dialog-cancel-color)`}},Q=[{...Z.Ok,primary:!0}],$=class Dialog extends o{_titleBar;_contentContainer;_buttonRow;_backdrop;_config;_resolvePromise=null;_previousFocus=null;_boundKeyHandler;_boundResizeHandler;_panelInAnimation=null;_backdropInAnimation=null;_panelOutAnimation=null;_backdropOutAnimation=null;_finalizing=!1;constructor(e){super(),this._config=e;let t=Math.max(W,e.width??480),i=e.buttons??Q,a=Math.max(K,this.computeContentHeight(e)),o=Math.max(G,e.height??L+a+R);this.setPosition(r.FIXED),this.setWidth(t),this.setHeight(o),this.setBackgroundColor(`var(--ts-ui-body-bg)`),this.setBorderRadius(`var(--ts-ui-border-radius, 4px)`),this.setShadow(`var(--ts-ui-dialog-shadow)`),this.setOverflow(`hidden`),this.setContain(`strict`);let s=new b;if(s.setComponentSpacing(0),this.setLayoutManager(s),this._titleBar=new DialogTitleBar(e.title,()=>this.hide(`close`),e.dismissable!==!1),this.addComponent(this._titleBar,{placement:y.NORTH}),e.severity?this.applySeverityHeader(e.severity):this.applyHeaderVariant(this.computeHeaderVariant(i)),this._contentContainer=new u({autoScroll:`y`,layoutManager:new ee,insets:new n(0,0,0,0)}),e.contentComponent)this._contentContainer.addComponent(e.contentComponent);else{let t=new m(e.message??``);t.setWhiteSpace(`normal`),t.setWordBreak(`break-word`),t.setPadding(new n(16,16,16,16)),t.setUserSelect(`text`),t.setCursor(`text`),this._contentContainer.addComponent(t)}this.addComponent(this._contentContainer,{placement:y.CENTER}),this._buttonRow=new DialogButtonRow(i,e=>this.hide(e)),this.addComponent(this._buttonRow,{placement:y.SOUTH}),this._backdrop=new I,this._boundKeyHandler=e=>this.onKeyDown(e),this._boundResizeHandler=()=>this.onViewportResize()}computeHeaderVariant(e){let t=new Set(e.map(e=>e.result??`cancel`));return t.size===1&&t.has(`confirm`)?`info`:t.has(`confirm`)&&t.has(`cancel`)?`affirm`:`plain`}applyHeaderVariant(e){if(e===`plain`)return;let t=e===`info`?`var(--ts-ui-dialog-info-bg)`:`var(--ts-ui-dialog-affirm-bg)`,n=e===`info`?`var(--ts-ui-dialog-info-fg)`:`var(--ts-ui-dialog-affirm-fg)`;if(this._titleBar.setBackgroundColor(t),this._titleBar.getTitleText().setForegroundColor(n),e===`info`){this._titleBar.setGlyph(`circle-info`);let e=this._titleBar.getGlyph();e!==null&&e.setForegroundColor(n)}}applySeverityHeader(e){let t=`var(--ts-ui-notification-${e}-bg)`,n=`var(--ts-ui-notification-${e}-border)`;this._titleBar.setBackgroundColor(t),this._titleBar.getTitleText().setForegroundColor(n),this._titleBar.setGlyph(q[e]);let r=this._titleBar.getGlyph();r!==null&&r.setForegroundColor(n)}computeContentHeight(e){if(e.contentComponent){let t=e.contentComponent.getPreferredSize();if(t)return t.height}return 100}show(){return new Promise(e=>{this._resolvePromise=e,this.open()})}resizeToContent(){if(!this.getElement())return this;let t=Math.max(K,this.computeContentHeight(this._config)),n=Math.max(G,L+t+R),r=e.source.getViewportSize(),i=Math.min(n,Math.max(G,r.height-48));return i===this.getHeight()?this:(this.setHeight(i),this.scheduleLayout(),this.center(),this)}open(){this._previousFocus=e.source.getActiveElement(),this._config.closeOnBackdrop&&this._config.dismissable!==!1&&this._backdrop.addClickListener(()=>{this.hide(`close`)}),d.register(this);let t=d.getZIndex(this);this.setZIndex(t),this._backdrop.setZIndex(t-1);let n=this._backdrop.getElement(!0);d.mount(n);let r=this.getElement(!0);d.mount(r),_(this),this.scheduleLayout(),this.center(),this.animateIn(),o.afterNextLayout(()=>this.resizeToContent()),i.addViewportListener(this,`keydown`,this._boundKeyHandler),i.addViewportListener(this,`resize`,this._boundResizeHandler),o.afterNextLayout(()=>this.focusFirst())}animateIn(){let e=this.getElement(),t=this._backdrop.getElement();e&&(this._panelInAnimation?.cancel(),this._panelInAnimation=s.play(e,{from:{opacity:`0`,transform:`scale(0.97)`},to:{opacity:`1`,transform:`scale(1)`},durationMs:J,properties:[`opacity`,`transform`]}),t&&(this._backdropInAnimation?.cancel(),this._backdropInAnimation=s.play(t,{from:{opacity:`0`},to:{opacity:`1`},durationMs:J,properties:[`opacity`]})))}center(){let t=e.source.getViewportSize(),n=Math.max(0,Math.round((t.width-this.getWidth())/2)),r=Math.max(0,Math.round((t.height-this.getHeight())/2));this.setX(n),this.setY(r)}focusFirst(){let t=this.requestedFocusElement();if(t){e.sink.focus(t);return}let n=this._contentContainer.getElement(),r=n?e.source.querySelectorAll(n,Y):[];if(r.length>0){e.sink.focus(r[0]);return}let i=this.primaryButtonElement();if(i){e.sink.focus(i);return}let a=this.getElement(),o=a?e.source.querySelectorAll(a,Y):[];o.length>0&&e.sink.focus(o[0])}requestedFocusElement(){let t=this._config.initialFocus?.getElement();return t?e.source.matches(t,Y)?t:e.source.querySelector(t,Y):null}primaryButtonElement(){let t=(this._config.buttons??Q).findIndex(e=>e.primary);if(t<0)return null;let n=this._buttonRow.getElement();return(n?e.source.querySelectorAll(n,Y):[])[t]??null}getFocusable(){let t=this.getElement();return t?e.source.querySelectorAll(t,Y).filter(t=>!e.source.hasAttribute(t,`disabled`)):[]}onKeyDown(t){if(t.key===`Enter`)return this.onEnter(t);if(t.key===`Tab`){let n=this.getFocusable();if(n.length===0)return{stop:!0,prevent:!0};let r=n[0],i=n[n.length-1];if(t.shiftKey){if(e.source.getActiveElement()===r)return e.sink.focus(i),{stop:!0,prevent:!0}}else if(e.source.getActiveElement()===i)return e.sink.focus(r),{stop:!0,prevent:!0}}}onEnter(t){let n=e.source.getActiveElement(),r=n?e.source.getTagName(n).toLowerCase():null;if(r===`textarea`||r===`button`)return;let i=this.primaryResult();if(i!==null)return this.hide(i),{stop:!0,prevent:!0}}primaryResult(){let e=(this._config.buttons??Q).find(e=>e.primary);return e?e.result??`cancel`:null}onViewportResize(){this._backdrop.resize(),this.resizeToContent(),this.center()}hide(t){i.removeViewportListener(this,`keydown`,this._boundKeyHandler),i.removeViewportListener(this,`resize`,this._boundResizeHandler);let finalize=()=>{this._finalizing=!0,this._backdrop.destroy(),this.removeElement(),this.destructor(),d.unregister(this),v(this),this._previousFocus!==null&&e.sink.focus(this._previousFocus),this._resolvePromise&&=(this._resolvePromise(t),null)},n=this.getElement(),r=this._backdrop.getElement();return n?(this._panelOutAnimation?.cancel(),this._panelOutAnimation=s.play(n,{to:{opacity:`0`,transform:`scale(0.97)`},durationMs:J,properties:[`opacity`,`transform`],onComplete:finalize}),r&&(this._backdropOutAnimation?.cancel(),this._backdropOutAnimation=s.play(r,{to:{opacity:`0`},durationMs:J,properties:[`opacity`]})),this):(finalize(),this)}destructor(){this._panelInAnimation?.cancel(),this._panelInAnimation=null,this._backdropInAnimation?.cancel(),this._backdropInAnimation=null,this._panelOutAnimation?.cancel(),this._panelOutAnimation=null,this._backdropOutAnimation?.cancel(),this._backdropOutAnimation=null,this._finalizing||(this._backdrop.destroy(),d.unregister(this),v(this),this._resolvePromise&&=(this._resolvePromise(`close`),null)),super.destructor()}getContentComponent(){return this._contentContainer}clampsToContentSize(){return!1}getTitleBar(){return this._titleBar}getLayerElement(){return this.getElement()??null}getDismissMode(){return`modal`}requestClose(){this._config.dismissable!==!1&&this.hide(`close`)}getBand(){return d.Band.Dialog}static show(e){return new Dialog(e).show()}static async confirm(e,t){return await Dialog.show({title:e,message:t,buttons:[{...Z.Cancel,primary:!0},Z.Confirm]})===`confirm`}static async alert(e,t,n){await Dialog.show({title:t,message:n,severity:e,buttons:[{...Z.Ok,primary:!0}]})}static info(e,t){return Dialog.alert(`info`,e,t)}static success(e,t){return Dialog.alert(`success`,e,t)}static warning(e,t){return Dialog.alert(`warning`,e,t)}static error(e,t){return Dialog.alert(`error`,e,t)}},re=a($);export{I as a,DialogTitleBar as i,Z as n,P as o,re as r,$ as t};
|
|
2
|
+
//# sourceMappingURL=Dialog-cbA9V17e.js.map
|