@vielzeug/ore 26.10.7 → 26.10.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +7 -0
  2. package/dist/define.cjs +1 -1
  3. package/dist/define.cjs.map +1 -1
  4. package/dist/define.d.ts.map +1 -1
  5. package/dist/define.js +1 -1
  6. package/dist/define.js.map +1 -1
  7. package/dist/directives/classMap.cjs +1 -1
  8. package/dist/directives/classMap.cjs.map +1 -1
  9. package/dist/directives/classMap.d.ts.map +1 -1
  10. package/dist/directives/classMap.js +1 -1
  11. package/dist/directives/classMap.js.map +1 -1
  12. package/dist/directives/each.cjs +1 -1
  13. package/dist/directives/each.cjs.map +1 -1
  14. package/dist/directives/each.d.ts.map +1 -1
  15. package/dist/directives/each.js +1 -1
  16. package/dist/directives/each.js.map +1 -1
  17. package/dist/directives/model.cjs +2 -0
  18. package/dist/directives/model.cjs.map +1 -0
  19. package/dist/directives/model.d.ts +47 -0
  20. package/dist/directives/model.d.ts.map +1 -0
  21. package/dist/directives/model.js +2 -0
  22. package/dist/directives/model.js.map +1 -0
  23. package/dist/directives/styleMap.cjs +1 -1
  24. package/dist/directives/styleMap.cjs.map +1 -1
  25. package/dist/directives/styleMap.d.ts.map +1 -1
  26. package/dist/directives/styleMap.js +1 -1
  27. package/dist/directives/styleMap.js.map +1 -1
  28. package/dist/errors.cjs +1 -1
  29. package/dist/errors.cjs.map +1 -1
  30. package/dist/errors.d.ts +3 -1
  31. package/dist/errors.d.ts.map +1 -1
  32. package/dist/errors.js +1 -1
  33. package/dist/errors.js.map +1 -1
  34. package/dist/forms/field.cjs +1 -1
  35. package/dist/forms/field.cjs.map +1 -1
  36. package/dist/forms/field.d.ts +18 -5
  37. package/dist/forms/field.d.ts.map +1 -1
  38. package/dist/forms/field.js +1 -1
  39. package/dist/forms/field.js.map +1 -1
  40. package/dist/host-bind.cjs +1 -1
  41. package/dist/host-bind.cjs.map +1 -1
  42. package/dist/host-bind.d.ts.map +1 -1
  43. package/dist/host-bind.js +1 -1
  44. package/dist/host-bind.js.map +1 -1
  45. package/dist/index.cjs +1 -1
  46. package/dist/index.d.ts +2 -1
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +1 -1
  49. package/dist/ore.cjs +2 -2
  50. package/dist/ore.cjs.map +1 -1
  51. package/dist/ore.iife.js +2 -2
  52. package/dist/ore.iife.js.map +1 -1
  53. package/dist/ore.js +2 -2
  54. package/dist/ore.js.map +1 -1
  55. package/dist/props.cjs +1 -1
  56. package/dist/props.cjs.map +1 -1
  57. package/dist/props.d.ts +16 -5
  58. package/dist/props.d.ts.map +1 -1
  59. package/dist/props.js +1 -1
  60. package/dist/props.js.map +1 -1
  61. package/dist/template/binding-types.d.ts +26 -5
  62. package/dist/template/binding-types.d.ts.map +1 -1
  63. package/dist/template/bindings.cjs +1 -1
  64. package/dist/template/bindings.cjs.map +1 -1
  65. package/dist/template/bindings.d.ts +3 -3
  66. package/dist/template/bindings.d.ts.map +1 -1
  67. package/dist/template/bindings.js +1 -1
  68. package/dist/template/bindings.js.map +1 -1
  69. package/dist/template/compiler.cjs +1 -1
  70. package/dist/template/compiler.cjs.map +1 -1
  71. package/dist/template/compiler.d.ts +13 -0
  72. package/dist/template/compiler.d.ts.map +1 -1
  73. package/dist/template/compiler.js +1 -1
  74. package/dist/template/compiler.js.map +1 -1
  75. package/dist/template/instantiator.cjs +1 -1
  76. package/dist/template/instantiator.cjs.map +1 -1
  77. package/dist/template/instantiator.d.ts.map +1 -1
  78. package/dist/template/instantiator.js +1 -1
  79. package/dist/template/instantiator.js.map +1 -1
  80. package/dist/testing/index.d.ts +2 -13
  81. package/dist/testing/index.d.ts.map +1 -1
  82. package/dist/testing.cjs +1 -1
  83. package/dist/testing.cjs.map +1 -1
  84. package/dist/testing.js +1 -1
  85. package/dist/testing.js.map +1 -1
  86. package/dist/utils/brand.cjs.map +1 -1
  87. package/dist/utils/brand.d.ts +3 -2
  88. package/dist/utils/brand.d.ts.map +1 -1
  89. package/dist/utils/brand.js.map +1 -1
  90. package/dist/utils/dom.cjs +1 -1
  91. package/dist/utils/dom.cjs.map +1 -1
  92. package/dist/utils/dom.d.ts +19 -0
  93. package/dist/utils/dom.d.ts.map +1 -1
  94. package/dist/utils/dom.js +1 -1
  95. package/dist/utils/dom.js.map +1 -1
  96. package/package.json +5 -5
  97. package/dist/_component-class.cjs +0 -2
  98. package/dist/_component-class.cjs.map +0 -1
  99. package/dist/_component-class.d.ts +0 -2
  100. package/dist/_component-class.d.ts.map +0 -1
  101. package/dist/_component-class.js +0 -2
  102. package/dist/_component-class.js.map +0 -1
  103. package/dist/testing/dom.cjs +0 -2
  104. package/dist/testing/dom.cjs.map +0 -1
  105. package/dist/testing/dom.d.ts +0 -22
  106. package/dist/testing/dom.d.ts.map +0 -1
  107. package/dist/testing/dom.js +0 -2
  108. package/dist/testing/dom.js.map +0 -1
  109. package/dist/testing/form-internals-polyfill.cjs +0 -2
  110. package/dist/testing/form-internals-polyfill.cjs.map +0 -1
  111. package/dist/testing/form-internals-polyfill.d.ts +0 -19
  112. package/dist/testing/form-internals-polyfill.d.ts.map +0 -1
  113. package/dist/testing/form-internals-polyfill.js +0 -2
  114. package/dist/testing/form-internals-polyfill.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dom.js","names":[],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { ORE_ERRORS } from '../errors';\n\n/**\n * A value that may be a plain value, a reactive signal, or a getter function :\n * the shape `when()`, `each()`, `classMap()`, and `bind()` accept.\n * Exported so consumers can annotate their own composable parameters with it.\n */\nexport type MaybeReactive<T> = T | Readable<T> | (() => T);\n\n/**\n * Resolves a value that may be a plain value, a getter function, or a reactive\n * signal: the one shared three-way branch used by `classMap`/`styleMap`/`bind()`.\n */\nexport const resolveMaybeReactive = <T>(value: MaybeReactive<T>): T =>\n typeof value === 'function' ? (value as () => T)() : isReactive(value) ? value.value : value;\n\n/**\n * Characters that can break out of a CSS declaration in an inline style value or property name.\n * Semicolons end the current declaration; braces are meaningful in stylesheet rules but not\n * inline style values, and signal an injection attempt there.\n */\nexport const UNSAFE_CSS_CHARS = /[;{}]/g;\n\nexport const sanitizeCssToken = (value: string): string => value.replace(UNSAFE_CSS_CHARS, '');\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]?.();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * Tracks \"whatever is currently rendered in one spot\": a list of live DOM nodes plus the\n * cleanup functions that were registered while mounting them. `clear()` tears both down and\n * resets to empty, ready for the next render.\n *\n * Every directive/binding that swaps its rendered content when a reactive source changes\n * (`when()`, `unsafeHtml()`, `each()`'s empty-list fallback, `applyHtmlBinding()`) needs exactly this\n * bookkeeping: this is the one shared implementation instead of four independently-maintained\n * `currentNodes`/`currentCleanups` variable pairs.\n */\nexport type ReplaceableSlot = {\n /** Tears down every registered cleanup and removes every tracked node, then resets to empty. */\n clear(): void;\n /** Currently tracked nodes: read after mounting to know what's live. */\n readonly nodes: Node[];\n /** Pass as the `registerCleanup` callback to whatever mounts the next render. */\n registerCleanup(fn: () => void): void;\n /** Replace the tracked node list (call once mounting the next render is complete). */\n setNodes(nodes: Node[]): void;\n};\n\nexport const createReplaceableSlot = (): ReplaceableSlot => {\n let nodes: Node[] = [];\n let cleanups: (() => void)[] = [];\n\n return {\n clear() {\n runAll(cleanups);\n removeNodes(nodes);\n cleanups = [];\n nodes = [];\n },\n get nodes() {\n return nodes;\n },\n registerCleanup(fn) {\n cleanups.push(fn);\n },\n setNodes(next) {\n nodes = next;\n },\n };\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply: it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...): inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...): \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding. Sanitize untrusted content, then use unsafeHtml() if HTML injection is required.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n\n return;\n }\n\n const strVal = val === true ? 'true' : String(val);\n\n if (URL_ATTRS.has(lowerName) && DANGEROUS_SCHEME_RE.test(strVal)) {\n warn(\n `Blocked dangerous URL scheme in attribute \"${name}\". Only safe URLs are permitted in URL-accepting attributes.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n el.setAttribute(name, strVal);\n};\n\nexport const listen = (\n el: EventTarget | null | undefined,\n name: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n): (() => void) => {\n if (!el) {\n warn(ORE_ERRORS.listenNullTarget(name));\n\n return () => {};\n }\n\n const listener: EventListener = handler;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\nexport const isStructuredValue = (value: unknown): value is object =>\n Array.isArray(value) || (typeof value === 'object' && value !== null);\n"],"mappings":"2GAoBA,IAAa,EAA2B,GACtC,OAAO,GAAU,WAAc,EAAkB,EAAI,EAAW,CAAK,EAAI,EAAM,MAAQ,EAO5E,EAAmB,SAEnB,EAAoB,GAA0B,EAAM,QAAQ,EAAkB,EAAE,EAEhF,EAAU,GAA8B,CACnD,IAAK,IAAI,EAAI,EAAI,OAAS,EAAG,GAAK,EAAG,IAAK,EAAI,EAAE,GAAG,CACrD,EAEa,EAAe,GAAwB,CAClD,IAAK,IAAM,KAAQ,EACjB,EAAoB,OAAO,CAE/B,EAuBa,MAA+C,CAC1D,IAAI,EAAgB,CAAC,EACjB,EAA2B,CAAC,EAEhC,MAAO,CACL,OAAQ,CACN,EAAO,CAAQ,EACf,EAAY,CAAK,EACjB,EAAW,CAAC,EACZ,EAAQ,CAAC,CACX,EACA,IAAI,OAAQ,CACV,OAAO,CACT,EACA,gBAAgB,EAAI,CAClB,EAAS,KAAK,CAAE,CAClB,EACA,SAAS,EAAM,CACb,EAAQ,CACV,CACF,CACF,EASM,EAAY,IAAI,IAAI,CACxB,SACA,OACA,WACA,OACA,aACA,OACA,WACA,OACA,SACA,MACA,YACF,CAAC,EASK,EACJ,sGAEW,GAAW,EAAa,EAAc,IAAuB,CACxE,IAAM,EAAY,EAAK,YAAY,EAEnC,GAAI,YAAY,KAAK,CAAI,EAAG,CAExB,GAAyB,EAAzB,EAAiG,EAAK,MAAM,CAAC,EAA7G,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,IAAc,SAAU,CAI1B,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,GAAO,MAAQ,IAAQ,GAAO,CAChC,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,IAAM,EAAS,IAAQ,GAAO,OAAS,OAAO,CAAG,EAEjD,GAAI,EAAU,IAAI,CAAS,GAAK,EAAoB,KAAK,CAAM,EAAG,CAE9D,GAA8C,EAA9C,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,EAAG,aAAa,EAAM,CAAM,CAC9B,EAEa,GACX,EACA,EACA,EACA,IACiB,CACjB,GAAI,CAAC,EAGH,OAFK,EAAW,iBAAiB,CAAI,MAExB,CAAC,EAGhB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,CAAO,MAE9B,EAAG,oBAAoB,EAAM,EAAU,CAAO,CAC7D,EAEa,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,YAAY,GAAG,EAErF,EAAqB,GAChC,MAAM,QAAQ,CAAK,GAAM,OAAO,GAAU,YAAY"}
1
+ {"version":3,"file":"dom.js","names":[],"sources":["../../src/utils/dom.ts"],"sourcesContent":["/**\n * Low-level DOM utilities used throughout the runtime and binding layers.\n */\n\nimport { isReactive, type Readable } from '@vielzeug/ripple';\n\nimport { warn } from '../_dev';\nimport { ORE_ERRORS } from '../errors';\n\n/**\n * A value that may be a plain value, a reactive signal, or a getter function :\n * the shape `when()`, `each()`, `classMap()`, and `bind()` accept.\n * Exported so consumers can annotate their own composable parameters with it.\n */\nexport type MaybeReactive<T> = T | Readable<T> | (() => T);\n\n/**\n * Resolves a value that may be a plain value, a getter function, or a reactive\n * signal: the one shared three-way branch used by `classMap`/`styleMap`/`bind()`.\n */\nexport const resolveMaybeReactive = <T>(value: MaybeReactive<T>): T =>\n typeof value === 'function' ? (value as () => T)() : isReactive(value) ? value.value : value;\n\n/**\n * Characters that can break out of a CSS declaration in an inline style value or property name.\n * Semicolons end the current declaration; braces are meaningful in stylesheet rules but not\n * inline style values, and signal an injection attempt there.\n */\nexport const UNSAFE_CSS_CHARS = /[;{}]/g;\n\nexport const sanitizeCssToken = (value: string): string => value.replace(UNSAFE_CSS_CHARS, '');\n\nexport const runAll = (fns: (() => void)[]): void => {\n for (let i = fns.length - 1; i >= 0; i--) fns[i]?.();\n};\n\nexport const removeNodes = (nodes: Node[]): void => {\n for (const node of nodes) {\n (node as ChildNode).remove();\n }\n};\n\n/**\n * Tracks \"whatever is currently rendered in one spot\": a list of live DOM nodes plus the\n * cleanup functions that were registered while mounting them. `clear()` tears both down and\n * resets to empty, ready for the next render.\n *\n * Every directive/binding that swaps its rendered content when a reactive source changes\n * (`when()`, `unsafeHtml()`, `each()`'s empty-list fallback, `applyHtmlBinding()`) needs exactly this\n * bookkeeping: this is the one shared implementation instead of four independently-maintained\n * `currentNodes`/`currentCleanups` variable pairs.\n */\nexport type ReplaceableSlot = {\n /** Tears down every registered cleanup and removes every tracked node, then resets to empty. */\n clear(): void;\n /** Currently tracked nodes: read after mounting to know what's live. */\n readonly nodes: Node[];\n /** Pass as the `registerCleanup` callback to whatever mounts the next render. */\n registerCleanup(fn: () => void): void;\n /** Replace the tracked node list (call once mounting the next render is complete). */\n setNodes(nodes: Node[]): void;\n};\n\nexport const createReplaceableSlot = (): ReplaceableSlot => {\n let nodes: Node[] = [];\n let cleanups: (() => void)[] = [];\n\n return {\n clear() {\n runAll(cleanups);\n removeNodes(nodes);\n cleanups = [];\n nodes = [];\n },\n get nodes() {\n return nodes;\n },\n registerCleanup(fn) {\n cleanups.push(fn);\n },\n setNodes(next) {\n nodes = next;\n },\n };\n};\n\n/**\n * HTML attributes that accept URLs. Values bound to these attributes are\n * checked for dangerous schemes before being set.\n *\n * `srcdoc` is deliberately excluded: it holds raw HTML (not a URL), so scheme\n * checking doesn't apply: it's blocked unconditionally below, alongside `on*`.\n */\nconst URL_ATTRS = new Set([\n 'action',\n 'cite',\n 'codebase',\n 'data',\n 'formaction',\n 'href',\n 'manifest',\n 'ping',\n 'poster',\n 'src',\n 'xlink:href',\n]);\n\n/**\n * Schemes that execute JavaScript or can embed arbitrary HTML. Blocked\n * unconditionally in URL-accepting attributes.\n * Covers: javascript:, vbscript:, blob:, and data: variants that carry HTML/XML\n * or script-capable SVG. Plain data: image URIs (e.g. data:image/png) are\n * intentionally allowed.\n */\nconst DANGEROUS_SCHEME_RE =\n /^\\s*(?:(?:javascript|vbscript|blob):|data:(?:[^,]*\\/(?:html|svg\\+xml)|application\\/(?:xhtml|xml)))/i;\n\nexport const setAttr = (el: Element, name: string, val: unknown): void => {\n const lowerName = name.toLowerCase();\n\n if (/^on[a-z]/i.test(name)) {\n warn(\n `Blocked setAttribute(\"${name}\", ...): inline event handler attributes are not supported. Use @${name.slice(2)} binding syntax instead.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (lowerName === 'srcdoc') {\n warn(\n `Blocked setAttribute(\"srcdoc\", ...): \"srcdoc\" holds raw HTML, not a URL, and is not supported via attribute binding. Sanitize untrusted content, then use unsafeHtml() if HTML injection is required.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n if (val == null || val === false) {\n el.removeAttribute(name);\n\n return;\n }\n\n const strVal = val === true ? 'true' : String(val);\n\n if (URL_ATTRS.has(lowerName) && DANGEROUS_SCHEME_RE.test(strVal)) {\n warn(\n `Blocked dangerous URL scheme in attribute \"${name}\". Only safe URLs are permitted in URL-accepting attributes.`,\n );\n el.removeAttribute(name);\n\n return;\n }\n\n el.setAttribute(name, strVal);\n};\n\nexport const listen = (\n el: EventTarget | null | undefined,\n name: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n): (() => void) => {\n if (!el) {\n warn(ORE_ERRORS.listenNullTarget(name));\n\n return () => {};\n }\n\n const listener: EventListener = handler;\n\n el.addEventListener(name, listener, options);\n\n return () => el.removeEventListener(name, listener, options);\n};\n\nexport const toKebab = (str: string): string => str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\n/**\n * Normalize a CSS property name for use in a declaration (camelCase → kebab-case,\n * injection characters stripped). Custom properties (`--*`) are case-sensitive, so\n * they skip the kebab conversion. Shared by `styleMap()` (template side) and\n * `bind({ style })` (host side) so both sanitize identically.\n */\nexport const cssDeclarationName = (name: string): string =>\n sanitizeCssToken(name.startsWith('--') ? name : toKebab(name));\n\n/**\n * Resolve a style value to its declaration text ('' for null/false/empty).\n * Shared by `styleMap()` and `bind({ style })`.\n */\nexport const cssDeclarationValue = (value: unknown): string => {\n const resolved = resolveMaybeReactive(value as MaybeReactive<string | number | null | undefined | false>);\n\n if (resolved == null || resolved === false) return '';\n\n return sanitizeCssToken(String(resolved));\n};\n\n/**\n * Resolve a class map to the set of active class tokens: keys with truthy\n * (possibly reactive) values, whitespace stripped from each key (spaces would\n * inject extra class tokens). Shared by `classMap()` (joins the set into a\n * class attribute) and `bind({ class })` (diffs the set against classList).\n */\nexport const resolveClassTokens = (record: Record<string, MaybeReactive<boolean>>): Set<string> => {\n const tokens = new Set<string>();\n\n for (const [key, value] of Object.entries(record)) {\n if (!resolveMaybeReactive(value)) continue;\n\n const token = key.replace(/\\s+/g, '');\n\n if (token) tokens.add(token);\n }\n\n return tokens;\n};\n\nexport const isStructuredValue = (value: unknown): value is object =>\n Array.isArray(value) || (typeof value === 'object' && value !== null);\n"],"mappings":"2GAoBA,IAAa,EAA2B,GACtC,OAAO,GAAU,WAAc,EAAkB,EAAI,EAAW,CAAK,EAAI,EAAM,MAAQ,EAO5E,EAAmB,SAEnB,EAAoB,GAA0B,EAAM,QAAQ,EAAkB,EAAE,EAEhF,EAAU,GAA8B,CACnD,IAAK,IAAI,EAAI,EAAI,OAAS,EAAG,GAAK,EAAG,IAAK,EAAI,EAAE,GAAG,CACrD,EAEa,EAAe,GAAwB,CAClD,IAAK,IAAM,KAAQ,EACjB,EAAoB,OAAO,CAE/B,EAuBa,MAA+C,CAC1D,IAAI,EAAgB,CAAC,EACjB,EAA2B,CAAC,EAEhC,MAAO,CACL,OAAQ,CACN,EAAO,CAAQ,EACf,EAAY,CAAK,EACjB,EAAW,CAAC,EACZ,EAAQ,CAAC,CACX,EACA,IAAI,OAAQ,CACV,OAAO,CACT,EACA,gBAAgB,EAAI,CAClB,EAAS,KAAK,CAAE,CAClB,EACA,SAAS,EAAM,CACb,EAAQ,CACV,CACF,CACF,EASM,EAAY,IAAI,IAAI,CACxB,SACA,OACA,WACA,OACA,aACA,OACA,WACA,OACA,SACA,MACA,YACF,CAAC,EASK,EACJ,sGAEW,GAAW,EAAa,EAAc,IAAuB,CACxE,IAAM,EAAY,EAAK,YAAY,EAEnC,GAAI,YAAY,KAAK,CAAI,EAAG,CAExB,GAAyB,EAAzB,EAAiG,EAAK,MAAM,CAAC,EAA7G,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,IAAc,SAAU,CAI1B,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,GAAI,GAAO,MAAQ,IAAQ,GAAO,CAChC,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,IAAM,EAAS,IAAQ,GAAO,OAAS,OAAO,CAAG,EAEjD,GAAI,EAAU,IAAI,CAAS,GAAK,EAAoB,KAAK,CAAM,EAAG,CAE9D,GAA8C,EAA9C,EAEF,EAAG,gBAAgB,CAAI,EAEvB,MACF,CAEA,EAAG,aAAa,EAAM,CAAM,CAC9B,EAEa,GACX,EACA,EACA,EACA,IACiB,CACjB,GAAI,CAAC,EAGH,OAFK,EAAW,iBAAiB,CAAI,MAExB,CAAC,EAGhB,IAAM,EAA0B,EAIhC,OAFA,EAAG,iBAAiB,EAAM,EAAU,CAAO,MAE9B,EAAG,oBAAoB,EAAM,EAAU,CAAO,CAC7D,EAEa,EAAW,GAAwB,EAAI,QAAQ,SAAW,GAAM,IAAI,EAAE,YAAY,GAAG,EAQrF,EAAsB,GACjC,EAAiB,EAAK,WAAW,IAAI,EAAI,EAAO,EAAQ,CAAI,CAAC,EAMlD,EAAuB,GAA2B,CAC7D,IAAM,EAAW,EAAqB,CAAkE,EAIxG,OAFI,GAAY,MAAQ,IAAa,GAAc,GAE5C,EAAiB,OAAO,CAAQ,CAAC,CAC1C,EAQa,EAAsB,GAAgE,CACjG,IAAM,EAAS,IAAI,IAEnB,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAM,EAAG,CACjD,GAAI,CAAC,EAAqB,CAAK,EAAG,SAElC,IAAM,EAAQ,EAAI,QAAQ,OAAQ,EAAE,EAEhC,GAAO,EAAO,IAAI,CAAK,CAC7B,CAEA,OAAO,CACT,EAEa,EAAqB,GAChC,MAAM,QAAQ,CAAK,GAAM,OAAO,GAAU,YAAY"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielzeug/ore",
3
- "version": "26.10.7",
3
+ "version": "26.10.10",
4
4
  "description": "Functional web-component authoring on top of ripple",
5
5
  "repository": {
6
6
  "type": "git",
@@ -53,8 +53,8 @@
53
53
  "test:types": "tsc -p tsconfig.json --noEmit"
54
54
  },
55
55
  "peerDependencies": {
56
- "@vielzeug/assay": "^26.10.7",
57
- "@vielzeug/ripple": "^26.10.7"
56
+ "@vielzeug/assay": "^26.10.10",
57
+ "@vielzeug/ripple": "^26.10.10"
58
58
  },
59
59
  "peerDependenciesMeta": {
60
60
  "@vielzeug/assay": {
@@ -63,8 +63,8 @@
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/node": "^26.6.2",
66
- "@vielzeug/assay": "26.10.7",
67
- "@vielzeug/ripple": "26.10.7",
66
+ "@vielzeug/assay": "26.10.10",
67
+ "@vielzeug/ripple": "26.10.10",
68
68
  "axe-core": "^4.13.0",
69
69
  "jsdom": "^30.1.1",
70
70
  "typescript": "^6.0.3",
@@ -1,2 +0,0 @@
1
- const e=require("./errors.cjs"),t=require("./utils/dom.cjs"),n=require("./props.cjs"),r=require("./base-element.cjs");function i(i,a){let{props:o}=a,s=(()=>{if(!o)return;let t=n.validatePropDefs(o);if(t.length>0)throw new e.OreApiError(e.ORE_ERRORS.validationFailed(i,t));let r={};for(let[e,t]of Object.entries(o))r[e]=n.normalizePropDefinition(t,e);return r})(),c=s?Object.keys(s).map(t.toKebab):[];return class extends r.BaseElement{static _definition=a;static _normalizedPropDefs=s;static formAssociated=a.formAssociated??!1;static observedAttributes=c}}exports.createComponentClass=i;
2
- //# sourceMappingURL=_component-class.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_component-class.cjs","names":[],"sources":["../src/_component-class.ts"],"sourcesContent":["import { BaseElement } from './base-element';\nimport type { ComponentDefinition } from './component-types';\nimport { ORE_ERRORS, OreApiError } from './errors';\nimport { normalizePropDefinition, type PropInputDefs, type PropsDef, validatePropDefs } from './props';\nimport { toKebab } from './utils/dom';\n\n/**\n * Builds the element class without touching the browser registry. Keeping\n * declaration work separate from registration makes the latter the only\n * irreversible global side effect in the component-definition path.\n *\n * @internal\n */\nexport function createComponentClass<Props extends Record<string, unknown>>(\n tag: string,\n definition: ComponentDefinition<Props>,\n): CustomElementConstructor {\n const { props: propDefs } = definition;\n\n const normalizedPropDefs: PropsDef<Props> | undefined = (() => {\n if (!propDefs) return undefined;\n\n const errors = validatePropDefs(propDefs as Record<string, unknown>);\n\n if (errors.length > 0) throw new OreApiError(ORE_ERRORS.validationFailed(tag, errors));\n\n const normalized: PropInputDefs = {};\n\n for (const [key, def] of Object.entries(propDefs)) {\n normalized[key] = normalizePropDefinition(def, key);\n }\n\n return normalized as PropsDef<Props>;\n })();\n\n const observedAttrs = normalizedPropDefs ? Object.keys(normalizedPropDefs).map(toKebab) : [];\n\n const ComponentClass = class extends BaseElement {\n static override _definition = definition as unknown as ComponentDefinition;\n static override _normalizedPropDefs = normalizedPropDefs as PropsDef<Record<never, never>> | undefined;\n static override formAssociated = definition.formAssociated ?? false;\n static override observedAttributes = observedAttrs;\n };\n\n return ComponentClass;\n}\n"],"mappings":"sHAaA,SAAgB,EACd,EACA,EAC0B,CAC1B,GAAM,CAAE,MAAO,GAAa,EAEtB,OAAyD,CAC7D,GAAI,CAAC,EAAU,OAEf,IAAM,EAAS,EAAA,iBAAiB,CAAmC,EAEnE,GAAI,EAAO,OAAS,EAAG,MAAM,IAAI,EAAA,YAAY,EAAA,WAAW,iBAAiB,EAAK,CAAM,CAAC,EAErF,IAAM,EAA4B,CAAC,EAEnC,IAAK,GAAM,CAAC,EAAK,KAAQ,OAAO,QAAQ,CAAQ,EAC9C,EAAW,GAAO,EAAA,wBAAwB,EAAK,CAAG,EAGpD,OAAO,CACT,EAAA,CAAG,EAEG,EAAgB,EAAqB,OAAO,KAAK,CAAkB,CAAC,CAAC,IAAI,EAAA,OAAO,EAAI,CAAC,EAS3F,OAAO,cAP8B,EAAA,WAAY,CAC/C,OAAgB,YAAc,EAC9B,OAAgB,oBAAsB,EACtC,OAAgB,eAAiB,EAAW,gBAAkB,GAC9D,OAAgB,mBAAqB,CACvC,CAGF"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=_component-class.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_component-class.d.ts","sourceRoot":"","sources":["../src/_component-class.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{ORE_ERRORS as e,OreApiError as t}from"./errors.js";import{toKebab as n}from"./utils/dom.js";import{normalizePropDefinition as r,validatePropDefs as i}from"./props.js";import{BaseElement as a}from"./base-element.js";function o(o,s){let{props:c}=s,l=(()=>{if(!c)return;let n=i(c);if(n.length>0)throw new t(e.validationFailed(o,n));let a={};for(let[e,t]of Object.entries(c))a[e]=r(t,e);return a})(),u=l?Object.keys(l).map(n):[];return class extends a{static _definition=s;static _normalizedPropDefs=l;static formAssociated=s.formAssociated??!1;static observedAttributes=u}}export{o as createComponentClass};
2
- //# sourceMappingURL=_component-class.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_component-class.js","names":[],"sources":["../src/_component-class.ts"],"sourcesContent":["import { BaseElement } from './base-element';\nimport type { ComponentDefinition } from './component-types';\nimport { ORE_ERRORS, OreApiError } from './errors';\nimport { normalizePropDefinition, type PropInputDefs, type PropsDef, validatePropDefs } from './props';\nimport { toKebab } from './utils/dom';\n\n/**\n * Builds the element class without touching the browser registry. Keeping\n * declaration work separate from registration makes the latter the only\n * irreversible global side effect in the component-definition path.\n *\n * @internal\n */\nexport function createComponentClass<Props extends Record<string, unknown>>(\n tag: string,\n definition: ComponentDefinition<Props>,\n): CustomElementConstructor {\n const { props: propDefs } = definition;\n\n const normalizedPropDefs: PropsDef<Props> | undefined = (() => {\n if (!propDefs) return undefined;\n\n const errors = validatePropDefs(propDefs as Record<string, unknown>);\n\n if (errors.length > 0) throw new OreApiError(ORE_ERRORS.validationFailed(tag, errors));\n\n const normalized: PropInputDefs = {};\n\n for (const [key, def] of Object.entries(propDefs)) {\n normalized[key] = normalizePropDefinition(def, key);\n }\n\n return normalized as PropsDef<Props>;\n })();\n\n const observedAttrs = normalizedPropDefs ? Object.keys(normalizedPropDefs).map(toKebab) : [];\n\n const ComponentClass = class extends BaseElement {\n static override _definition = definition as unknown as ComponentDefinition;\n static override _normalizedPropDefs = normalizedPropDefs as PropsDef<Record<never, never>> | undefined;\n static override formAssociated = definition.formAssociated ?? false;\n static override observedAttributes = observedAttrs;\n };\n\n return ComponentClass;\n}\n"],"mappings":"8NAaA,SAAgB,EACd,EACA,EAC0B,CAC1B,GAAM,CAAE,MAAO,GAAa,EAEtB,OAAyD,CAC7D,GAAI,CAAC,EAAU,OAEf,IAAM,EAAS,EAAiB,CAAmC,EAEnE,GAAI,EAAO,OAAS,EAAG,MAAM,IAAI,EAAY,EAAW,iBAAiB,EAAK,CAAM,CAAC,EAErF,IAAM,EAA4B,CAAC,EAEnC,IAAK,GAAM,CAAC,EAAK,KAAQ,OAAO,QAAQ,CAAQ,EAC9C,EAAW,GAAO,EAAwB,EAAK,CAAG,EAGpD,OAAO,CACT,EAAA,CAAG,EAEG,EAAgB,EAAqB,OAAO,KAAK,CAAkB,CAAC,CAAC,IAAI,CAAO,EAAI,CAAC,EAS3F,OAAO,cAP8B,CAAY,CAC/C,OAAgB,YAAc,EAC9B,OAAgB,oBAAsB,EACtC,OAAgB,eAAiB,EAAW,gBAAkB,GAC9D,OAAgB,mBAAqB,CACvC,CAGF"}
@@ -1,2 +0,0 @@
1
- var e=(t,n)=>{let r=t instanceof HTMLSlotElement?t.assignedElements({flatten:!0}):t.children;for(let t of Array.from(r))t instanceof HTMLSlotElement||n(t),e(t,n)};exports.walkFlatTree=e;
2
- //# sourceMappingURL=dom.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dom.cjs","names":[],"sources":["../../src/testing/dom.ts"],"sourcesContent":["/**\n * DOM traversal helpers for tests running under jsdom, which only implements the *light* DOM\n * tree: `Element.children`/`querySelectorAll()` never cross a `<slot>` into its assigned\n * elements. Real browsers use the *flat tree* (light DOM with each `<slot>` transparently\n * replaced by what's actually assigned to it) for this: it's what \"form owner\" resolution,\n * `:has()`, and plenty of other DOM algorithms are specified against.\n */\n\n/**\n * Walks the flat tree starting at `root`, calling `visit` for every element encountered :\n * expanding each `<slot>` via `assignedElements()` instead of descending into its (always\n * empty, in jsdom) literal children.\n *\n * @example\n * ```ts\n * // Find every form-associated element slotted (possibly through nested slots) under `form`,\n * // something `form.querySelectorAll('[name]')` can't do once a shadow boundary is involved.\n * const named: HTMLElement[] = [];\n * walkFlatTree(form, (el) => { if (el.hasAttribute('name')) named.push(el); });\n * ```\n */\nexport const walkFlatTree = (root: Element, visit: (element: HTMLElement) => void): void => {\n const children = root instanceof HTMLSlotElement ? root.assignedElements({ flatten: true }) : root.children;\n\n for (const child of Array.from(children)) {\n if (!(child instanceof HTMLSlotElement)) visit(child as HTMLElement);\n\n walkFlatTree(child, visit);\n }\n};\n"],"mappings":"AAqBA,IAAa,GAAgB,EAAe,IAAgD,CAC1F,IAAM,EAAW,aAAgB,gBAAkB,EAAK,iBAAiB,CAAE,QAAS,EAAK,CAAC,EAAI,EAAK,SAEnG,IAAK,IAAM,KAAS,MAAM,KAAK,CAAQ,EAC/B,aAAiB,iBAAkB,EAAM,CAAoB,EAEnE,EAAa,EAAO,CAAK,CAE7B"}
@@ -1,22 +0,0 @@
1
- /**
2
- * DOM traversal helpers for tests running under jsdom, which only implements the *light* DOM
3
- * tree: `Element.children`/`querySelectorAll()` never cross a `<slot>` into its assigned
4
- * elements. Real browsers use the *flat tree* (light DOM with each `<slot>` transparently
5
- * replaced by what's actually assigned to it) for this: it's what "form owner" resolution,
6
- * `:has()`, and plenty of other DOM algorithms are specified against.
7
- */
8
- /**
9
- * Walks the flat tree starting at `root`, calling `visit` for every element encountered :
10
- * expanding each `<slot>` via `assignedElements()` instead of descending into its (always
11
- * empty, in jsdom) literal children.
12
- *
13
- * @example
14
- * ```ts
15
- * // Find every form-associated element slotted (possibly through nested slots) under `form`,
16
- * // something `form.querySelectorAll('[name]')` can't do once a shadow boundary is involved.
17
- * const named: HTMLElement[] = [];
18
- * walkFlatTree(form, (el) => { if (el.hasAttribute('name')) named.push(el); });
19
- * ```
20
- */
21
- export declare const walkFlatTree: (root: Element, visit: (element: HTMLElement) => void) => void;
22
- //# sourceMappingURL=dom.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/testing/dom.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,KAAG,IAQnF,CAAC"}
@@ -1,2 +0,0 @@
1
- var e=(t,n)=>{let r=t instanceof HTMLSlotElement?t.assignedElements({flatten:!0}):t.children;for(let t of Array.from(r))t instanceof HTMLSlotElement||n(t),e(t,n)};export{e as walkFlatTree};
2
- //# sourceMappingURL=dom.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dom.js","names":[],"sources":["../../src/testing/dom.ts"],"sourcesContent":["/**\n * DOM traversal helpers for tests running under jsdom, which only implements the *light* DOM\n * tree: `Element.children`/`querySelectorAll()` never cross a `<slot>` into its assigned\n * elements. Real browsers use the *flat tree* (light DOM with each `<slot>` transparently\n * replaced by what's actually assigned to it) for this: it's what \"form owner\" resolution,\n * `:has()`, and plenty of other DOM algorithms are specified against.\n */\n\n/**\n * Walks the flat tree starting at `root`, calling `visit` for every element encountered :\n * expanding each `<slot>` via `assignedElements()` instead of descending into its (always\n * empty, in jsdom) literal children.\n *\n * @example\n * ```ts\n * // Find every form-associated element slotted (possibly through nested slots) under `form`,\n * // something `form.querySelectorAll('[name]')` can't do once a shadow boundary is involved.\n * const named: HTMLElement[] = [];\n * walkFlatTree(form, (el) => { if (el.hasAttribute('name')) named.push(el); });\n * ```\n */\nexport const walkFlatTree = (root: Element, visit: (element: HTMLElement) => void): void => {\n const children = root instanceof HTMLSlotElement ? root.assignedElements({ flatten: true }) : root.children;\n\n for (const child of Array.from(children)) {\n if (!(child instanceof HTMLSlotElement)) visit(child as HTMLElement);\n\n walkFlatTree(child, visit);\n }\n};\n"],"mappings":"AAqBA,IAAa,GAAgB,EAAe,IAAgD,CAC1F,IAAM,EAAW,aAAgB,gBAAkB,EAAK,iBAAiB,CAAE,QAAS,EAAK,CAAC,EAAI,EAAK,SAEnG,IAAK,IAAM,KAAS,MAAM,KAAK,CAAQ,EAC/B,aAAiB,iBAAkB,EAAM,CAAoB,EAEnE,EAAa,EAAO,CAAK,CAE7B"}
@@ -1,2 +0,0 @@
1
- const e=require("./dom.cjs");var t=()=>{if(typeof ElementInternals>`u`)return()=>{};let t=Symbol.for(`vielzeug.ore.testing.formInternalsPolyfillInstalled`),n=globalThis;if(n[t])return()=>{};n[t]=!0;let r=[],i=ElementInternals.prototype,a=new WeakMap,o=new WeakMap,s=new WeakMap,c=(e,t)=>{e in i||(Object.defineProperty(i,e,t),r.push(()=>delete i[e]))},l=e=>{let t=a.get(e);return!t||!Object.values(t.flags).some(Boolean)};c(`setFormValue`,{configurable:!0,value:function(e){let t=s.get(this);t&&o.set(t,e)},writable:!0}),c(`setValidity`,{configurable:!0,value:function(e={},t=``){if(Object.values(e).some(Boolean)&&!t)throw TypeError(`Failed to execute 'setValidity' on 'ElementInternals': The second argument must not be empty if one or more flags in the first argument are true.`);a.set(this,{flags:e,message:t})},writable:!0}),c(`checkValidity`,{configurable:!0,value:function(){return l(this)},writable:!0}),c(`reportValidity`,{configurable:!0,value:function(){return l(this)},writable:!0}),c(`validationMessage`,{configurable:!0,get(){return l(this)?``:a.get(this)?.message??``}}),c(`validity`,{configurable:!0,get(){let e=a.get(this);return{badInput:!1,customError:!1,patternMismatch:!1,rangeOverflow:!1,rangeUnderflow:!1,stepMismatch:!1,tooLong:!1,tooShort:!1,typeMismatch:!1,valid:l(this),valueMissing:!1,...e?.flags??{}}}}),c(`states`,{configurable:!0,get:function(){return this._states??=new Set,this._states}});let u=HTMLElement.prototype.attachInternals;HTMLElement.prototype.attachInternals=function(...e){let t=u.apply(this,e);return s.set(t,this),Object.defineProperties(this,{checkValidity:{configurable:!0,value:()=>t.checkValidity()},reportValidity:{configurable:!0,value:()=>t.reportValidity()},validationMessage:{configurable:!0,get:()=>t.validationMessage},validity:{configurable:!0,get:()=>t.validity}}),t},r.push(()=>{HTMLElement.prototype.attachInternals=u});let d=(e,t,n)=>{if(n instanceof FormData){for(let[t,r]of n.entries())e.append(t,r);return}e.append(t,n)},f=globalThis.FormData;globalThis.FormData=class extends f{constructor(t,n){super(t,n),t instanceof HTMLFormElement&&e.walkFlatTree(t,e=>{let t=e.getAttribute(`name`),n=o.get(e);t&&n!=null&&!e.hasAttribute(`disabled`)&&d(this,t,n)})}},r.push(()=>{globalThis.FormData=f});let p=HTMLFormElement.prototype.reset;return HTMLFormElement.prototype.reset=function(...t){p.apply(this,t),e.walkFlatTree(this,e=>{e.formResetCallback?.()})},r.push(()=>{HTMLFormElement.prototype.reset=p}),()=>{for(let e of r)e();r.length=0,n[t]=!1}};exports.installFormInternalsPolyfill=t;
2
- //# sourceMappingURL=form-internals-polyfill.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"form-internals-polyfill.cjs","names":[],"sources":["../../src/testing/form-internals-polyfill.ts"],"sourcesContent":["import { walkFlatTree } from './dom';\n\n/**\n * jsdom implements none of the `ElementInternals` form-association API: not `setFormValue`,\n * not `setValidity`, not the `checkValidity`/`reportValidity`/`validity`/`validationMessage`\n * mixin real browsers put on every `formAssociated: true` element, not even `FormData`\n * collecting a form-associated element's set value, or `<form>.reset()` invoking\n * `formResetCallback()`. Every one of those gaps is exercised by `useField()` (`@vielzeug/ore`),\n * so any package testing a form-associated component needs all of them, not just one.\n *\n * Opt-in via `install(afterEach, { formInternals: true })` (or call this directly) :\n * the patches are global monkey-patches, so suites without form-associated components\n * shouldn't pay for them. Returns an `uninstall()` that restores every patched global.\n *\n * Deliberately lives here rather than in each consuming package's own `vitest.setup.ts`: the\n * gap is in `ore`'s own form-association feature, not in any one consumer, so the fix belongs\n * with the feature. `walkFlatTree` handles form-associated custom elements across shadow\n * boundaries, so consumer packages do not need package-local copies of this polyfill.\n */\nexport const installFormInternalsPolyfill = (): (() => void) => {\n // Checked *before* consuming the flag below: an environment without `ElementInternals`\n // installs nothing and should stay eligible to install for real later (e.g. a differently\n // configured environment in the same process), not get marked \"already installed\" for having\n // done nothing.\n if (typeof ElementInternals === 'undefined') return () => {};\n\n const INSTALLED_FLAG = Symbol.for('vielzeug.ore.testing.formInternalsPolyfillInstalled');\n const flagHost = globalThis as Record<symbol, boolean | undefined>;\n\n if (flagHost[INSTALLED_FLAG]) return () => {};\n\n flagHost[INSTALLED_FLAG] = true;\n\n // Every patch pushes its inverse here, so uninstall() restores the environment exactly.\n const restorers: Array<() => void> = [];\n\n const proto = ElementInternals.prototype as unknown as Record<string, unknown>;\n const validityState = new WeakMap<ElementInternals, { flags: ValidityStateFlags; message: string }>();\n const formValueByHost = new WeakMap<HTMLElement, File | FormData | string | null>();\n const hostByInternals = new WeakMap<ElementInternals, HTMLElement>();\n\n const patchProto = (name: string, descriptor: PropertyDescriptor): void => {\n if (name in proto) return;\n\n Object.defineProperty(proto, name, descriptor);\n restorers.push(() => delete proto[name]);\n };\n\n const isValid = (internals: ElementInternals): boolean => {\n const state = validityState.get(internals);\n\n return !state || !Object.values(state.flags).some(Boolean);\n };\n\n patchProto('setFormValue', {\n configurable: true,\n value: function (this: ElementInternals, value: File | FormData | string | null) {\n const host = hostByInternals.get(this);\n\n if (host) formValueByHost.set(host, value);\n },\n writable: true,\n });\n\n patchProto('setValidity', {\n configurable: true,\n // Matches the real platform contract: throws if any flag is true and message is empty.\n // `useField()` itself already guards against triggering this: see forms/field.ts, but\n // the polyfill enforcing it too means a test would still catch a *different* caller doing\n // the same thing wrong, instead of that bug only surfacing in a real browser.\n value: function (this: ElementInternals, flags: ValidityStateFlags = {}, message = '') {\n if (Object.values(flags).some(Boolean) && !message) {\n throw new TypeError(\n \"Failed to execute 'setValidity' on 'ElementInternals': The second argument must not be empty if \" +\n 'one or more flags in the first argument are true.',\n );\n }\n\n validityState.set(this, { flags, message });\n },\n writable: true,\n });\n\n patchProto('checkValidity', {\n configurable: true,\n value: function (this: ElementInternals) {\n return isValid(this);\n },\n writable: true,\n });\n\n patchProto('reportValidity', {\n configurable: true,\n value: function (this: ElementInternals) {\n return isValid(this);\n },\n writable: true,\n });\n\n patchProto('validationMessage', {\n configurable: true,\n get(this: ElementInternals) {\n return isValid(this) ? '' : (validityState.get(this)?.message ?? '');\n },\n });\n\n // A ValidityState-shaped view of the flags passed to setValidity: every known\n // flag defaults to false, `valid` reflects whether any flag is set.\n patchProto('validity', {\n configurable: true,\n get(this: ElementInternals): ValidityState {\n const state = validityState.get(this);\n\n return {\n badInput: false,\n customError: false,\n patternMismatch: false,\n rangeOverflow: false,\n rangeUnderflow: false,\n stepMismatch: false,\n tooLong: false,\n tooShort: false,\n typeMismatch: false,\n valid: isValid(this),\n valueMissing: false,\n ...(state?.flags ?? {}),\n } as ValidityState;\n },\n });\n\n patchProto('states', {\n configurable: true,\n get: function (this: ElementInternals & { _states?: Set<string> }) {\n this._states ??= new Set();\n\n return this._states;\n },\n });\n\n // Real browsers mix `checkValidity`/`reportValidity`/`validity`/`validationMessage` onto any\n // `formAssociated: true` custom element itself (delegating to its internals): not just onto\n // `ElementInternals`. jsdom does neither; mirror it here so a component's own\n // `checkValidity()`/`reportValidity()`, and a test asserting against the element directly,\n // behave the same as they would in a real browser.\n const originalAttachInternals = HTMLElement.prototype.attachInternals;\n\n HTMLElement.prototype.attachInternals = function (this: HTMLElement, ...args: []): ElementInternals {\n const internals = originalAttachInternals.apply(this, args);\n\n hostByInternals.set(internals, this);\n\n Object.defineProperties(this, {\n checkValidity: { configurable: true, value: () => internals.checkValidity() },\n reportValidity: { configurable: true, value: () => internals.reportValidity() },\n validationMessage: { configurable: true, get: () => internals.validationMessage },\n validity: { configurable: true, get: () => internals.validity },\n });\n\n return internals;\n };\n restorers.push(() => {\n HTMLElement.prototype.attachInternals = originalAttachInternals;\n });\n\n const appendFormValue = (formData: FormData, name: string, value: File | FormData | string): void => {\n if (value instanceof FormData) {\n for (const [entryName, entryValue] of value.entries()) formData.append(entryName, entryValue);\n\n return;\n }\n\n formData.append(name, value);\n };\n\n // jsdom's `FormData` constructor never collects a form-associated custom element's set form\n // value: real browsers walk the flat tree for every form-associated element with a `name`.\n const NativeFormData = globalThis.FormData;\n\n globalThis.FormData = class FormDataWithFormAssociatedElements extends NativeFormData {\n constructor(form?: HTMLFormElement, submitter?: HTMLElement | null) {\n super(form as HTMLFormElement | undefined, submitter as HTMLElement | null | undefined);\n\n if (!(form instanceof HTMLFormElement)) return;\n\n walkFlatTree(form, (element) => {\n const name = element.getAttribute('name');\n const value = formValueByHost.get(element);\n\n if (!name || value == null || element.hasAttribute('disabled')) return;\n\n appendFormValue(this, name, value);\n });\n }\n };\n restorers.push(() => {\n globalThis.FormData = NativeFormData;\n });\n\n // jsdom never invokes the native `formResetCallback` lifecycle method on form-associated\n // custom elements when their form resets: patch `reset()` to do it (via the same flat-tree\n // walk, since a reset field can be nested behind a shadow boundary too), so `onFormReset()`\n // (see `@vielzeug/ore`'s runtime.ts) is testable against a real `<form>.reset()` call instead\n // of only by calling `element.formResetCallback()` directly.\n const originalReset = HTMLFormElement.prototype.reset;\n\n HTMLFormElement.prototype.reset = function (this: HTMLFormElement, ...args: []) {\n originalReset.apply(this, args);\n\n walkFlatTree(this, (element) => {\n (element as Partial<{ formResetCallback: () => void }>).formResetCallback?.();\n });\n };\n restorers.push(() => {\n HTMLFormElement.prototype.reset = originalReset;\n });\n\n return () => {\n for (const restore of restorers) restore();\n\n restorers.length = 0;\n flagHost[INSTALLED_FLAG] = false;\n };\n};\n"],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- /**
2
- * jsdom implements none of the `ElementInternals` form-association API: not `setFormValue`,
3
- * not `setValidity`, not the `checkValidity`/`reportValidity`/`validity`/`validationMessage`
4
- * mixin real browsers put on every `formAssociated: true` element, not even `FormData`
5
- * collecting a form-associated element's set value, or `<form>.reset()` invoking
6
- * `formResetCallback()`. Every one of those gaps is exercised by `useField()` (`@vielzeug/ore`),
7
- * so any package testing a form-associated component needs all of them, not just one.
8
- *
9
- * Opt-in via `install(afterEach, { formInternals: true })` (or call this directly) :
10
- * the patches are global monkey-patches, so suites without form-associated components
11
- * shouldn't pay for them. Returns an `uninstall()` that restores every patched global.
12
- *
13
- * Deliberately lives here rather than in each consuming package's own `vitest.setup.ts`: the
14
- * gap is in `ore`'s own form-association feature, not in any one consumer, so the fix belongs
15
- * with the feature. `walkFlatTree` handles form-associated custom elements across shadow
16
- * boundaries, so consumer packages do not need package-local copies of this polyfill.
17
- */
18
- export declare const installFormInternalsPolyfill: () => (() => void);
19
- //# sourceMappingURL=form-internals-polyfill.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"form-internals-polyfill.d.ts","sourceRoot":"","sources":["../../src/testing/form-internals-polyfill.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,4BAA4B,QAAO,CAAC,MAAM,IAAI,CA2M1D,CAAC"}
@@ -1,2 +0,0 @@
1
- import{walkFlatTree as e}from"./dom.js";var t=()=>{if(typeof ElementInternals>`u`)return()=>{};let t=Symbol.for(`vielzeug.ore.testing.formInternalsPolyfillInstalled`),n=globalThis;if(n[t])return()=>{};n[t]=!0;let r=[],i=ElementInternals.prototype,a=new WeakMap,o=new WeakMap,s=new WeakMap,c=(e,t)=>{e in i||(Object.defineProperty(i,e,t),r.push(()=>delete i[e]))},l=e=>{let t=a.get(e);return!t||!Object.values(t.flags).some(Boolean)};c(`setFormValue`,{configurable:!0,value:function(e){let t=s.get(this);t&&o.set(t,e)},writable:!0}),c(`setValidity`,{configurable:!0,value:function(e={},t=``){if(Object.values(e).some(Boolean)&&!t)throw TypeError(`Failed to execute 'setValidity' on 'ElementInternals': The second argument must not be empty if one or more flags in the first argument are true.`);a.set(this,{flags:e,message:t})},writable:!0}),c(`checkValidity`,{configurable:!0,value:function(){return l(this)},writable:!0}),c(`reportValidity`,{configurable:!0,value:function(){return l(this)},writable:!0}),c(`validationMessage`,{configurable:!0,get(){return l(this)?``:a.get(this)?.message??``}}),c(`validity`,{configurable:!0,get(){let e=a.get(this);return{badInput:!1,customError:!1,patternMismatch:!1,rangeOverflow:!1,rangeUnderflow:!1,stepMismatch:!1,tooLong:!1,tooShort:!1,typeMismatch:!1,valid:l(this),valueMissing:!1,...e?.flags??{}}}}),c(`states`,{configurable:!0,get:function(){return this._states??=new Set,this._states}});let u=HTMLElement.prototype.attachInternals;HTMLElement.prototype.attachInternals=function(...e){let t=u.apply(this,e);return s.set(t,this),Object.defineProperties(this,{checkValidity:{configurable:!0,value:()=>t.checkValidity()},reportValidity:{configurable:!0,value:()=>t.reportValidity()},validationMessage:{configurable:!0,get:()=>t.validationMessage},validity:{configurable:!0,get:()=>t.validity}}),t},r.push(()=>{HTMLElement.prototype.attachInternals=u});let d=(e,t,n)=>{if(n instanceof FormData){for(let[t,r]of n.entries())e.append(t,r);return}e.append(t,n)},f=globalThis.FormData;globalThis.FormData=class extends f{constructor(t,n){super(t,n),t instanceof HTMLFormElement&&e(t,e=>{let t=e.getAttribute(`name`),n=o.get(e);t&&n!=null&&!e.hasAttribute(`disabled`)&&d(this,t,n)})}},r.push(()=>{globalThis.FormData=f});let p=HTMLFormElement.prototype.reset;return HTMLFormElement.prototype.reset=function(...t){p.apply(this,t),e(this,e=>{e.formResetCallback?.()})},r.push(()=>{HTMLFormElement.prototype.reset=p}),()=>{for(let e of r)e();r.length=0,n[t]=!1}};export{t as installFormInternalsPolyfill};
2
- //# sourceMappingURL=form-internals-polyfill.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"form-internals-polyfill.js","names":[],"sources":["../../src/testing/form-internals-polyfill.ts"],"sourcesContent":["import { walkFlatTree } from './dom';\n\n/**\n * jsdom implements none of the `ElementInternals` form-association API: not `setFormValue`,\n * not `setValidity`, not the `checkValidity`/`reportValidity`/`validity`/`validationMessage`\n * mixin real browsers put on every `formAssociated: true` element, not even `FormData`\n * collecting a form-associated element's set value, or `<form>.reset()` invoking\n * `formResetCallback()`. Every one of those gaps is exercised by `useField()` (`@vielzeug/ore`),\n * so any package testing a form-associated component needs all of them, not just one.\n *\n * Opt-in via `install(afterEach, { formInternals: true })` (or call this directly) :\n * the patches are global monkey-patches, so suites without form-associated components\n * shouldn't pay for them. Returns an `uninstall()` that restores every patched global.\n *\n * Deliberately lives here rather than in each consuming package's own `vitest.setup.ts`: the\n * gap is in `ore`'s own form-association feature, not in any one consumer, so the fix belongs\n * with the feature. `walkFlatTree` handles form-associated custom elements across shadow\n * boundaries, so consumer packages do not need package-local copies of this polyfill.\n */\nexport const installFormInternalsPolyfill = (): (() => void) => {\n // Checked *before* consuming the flag below: an environment without `ElementInternals`\n // installs nothing and should stay eligible to install for real later (e.g. a differently\n // configured environment in the same process), not get marked \"already installed\" for having\n // done nothing.\n if (typeof ElementInternals === 'undefined') return () => {};\n\n const INSTALLED_FLAG = Symbol.for('vielzeug.ore.testing.formInternalsPolyfillInstalled');\n const flagHost = globalThis as Record<symbol, boolean | undefined>;\n\n if (flagHost[INSTALLED_FLAG]) return () => {};\n\n flagHost[INSTALLED_FLAG] = true;\n\n // Every patch pushes its inverse here, so uninstall() restores the environment exactly.\n const restorers: Array<() => void> = [];\n\n const proto = ElementInternals.prototype as unknown as Record<string, unknown>;\n const validityState = new WeakMap<ElementInternals, { flags: ValidityStateFlags; message: string }>();\n const formValueByHost = new WeakMap<HTMLElement, File | FormData | string | null>();\n const hostByInternals = new WeakMap<ElementInternals, HTMLElement>();\n\n const patchProto = (name: string, descriptor: PropertyDescriptor): void => {\n if (name in proto) return;\n\n Object.defineProperty(proto, name, descriptor);\n restorers.push(() => delete proto[name]);\n };\n\n const isValid = (internals: ElementInternals): boolean => {\n const state = validityState.get(internals);\n\n return !state || !Object.values(state.flags).some(Boolean);\n };\n\n patchProto('setFormValue', {\n configurable: true,\n value: function (this: ElementInternals, value: File | FormData | string | null) {\n const host = hostByInternals.get(this);\n\n if (host) formValueByHost.set(host, value);\n },\n writable: true,\n });\n\n patchProto('setValidity', {\n configurable: true,\n // Matches the real platform contract: throws if any flag is true and message is empty.\n // `useField()` itself already guards against triggering this: see forms/field.ts, but\n // the polyfill enforcing it too means a test would still catch a *different* caller doing\n // the same thing wrong, instead of that bug only surfacing in a real browser.\n value: function (this: ElementInternals, flags: ValidityStateFlags = {}, message = '') {\n if (Object.values(flags).some(Boolean) && !message) {\n throw new TypeError(\n \"Failed to execute 'setValidity' on 'ElementInternals': The second argument must not be empty if \" +\n 'one or more flags in the first argument are true.',\n );\n }\n\n validityState.set(this, { flags, message });\n },\n writable: true,\n });\n\n patchProto('checkValidity', {\n configurable: true,\n value: function (this: ElementInternals) {\n return isValid(this);\n },\n writable: true,\n });\n\n patchProto('reportValidity', {\n configurable: true,\n value: function (this: ElementInternals) {\n return isValid(this);\n },\n writable: true,\n });\n\n patchProto('validationMessage', {\n configurable: true,\n get(this: ElementInternals) {\n return isValid(this) ? '' : (validityState.get(this)?.message ?? '');\n },\n });\n\n // A ValidityState-shaped view of the flags passed to setValidity: every known\n // flag defaults to false, `valid` reflects whether any flag is set.\n patchProto('validity', {\n configurable: true,\n get(this: ElementInternals): ValidityState {\n const state = validityState.get(this);\n\n return {\n badInput: false,\n customError: false,\n patternMismatch: false,\n rangeOverflow: false,\n rangeUnderflow: false,\n stepMismatch: false,\n tooLong: false,\n tooShort: false,\n typeMismatch: false,\n valid: isValid(this),\n valueMissing: false,\n ...(state?.flags ?? {}),\n } as ValidityState;\n },\n });\n\n patchProto('states', {\n configurable: true,\n get: function (this: ElementInternals & { _states?: Set<string> }) {\n this._states ??= new Set();\n\n return this._states;\n },\n });\n\n // Real browsers mix `checkValidity`/`reportValidity`/`validity`/`validationMessage` onto any\n // `formAssociated: true` custom element itself (delegating to its internals): not just onto\n // `ElementInternals`. jsdom does neither; mirror it here so a component's own\n // `checkValidity()`/`reportValidity()`, and a test asserting against the element directly,\n // behave the same as they would in a real browser.\n const originalAttachInternals = HTMLElement.prototype.attachInternals;\n\n HTMLElement.prototype.attachInternals = function (this: HTMLElement, ...args: []): ElementInternals {\n const internals = originalAttachInternals.apply(this, args);\n\n hostByInternals.set(internals, this);\n\n Object.defineProperties(this, {\n checkValidity: { configurable: true, value: () => internals.checkValidity() },\n reportValidity: { configurable: true, value: () => internals.reportValidity() },\n validationMessage: { configurable: true, get: () => internals.validationMessage },\n validity: { configurable: true, get: () => internals.validity },\n });\n\n return internals;\n };\n restorers.push(() => {\n HTMLElement.prototype.attachInternals = originalAttachInternals;\n });\n\n const appendFormValue = (formData: FormData, name: string, value: File | FormData | string): void => {\n if (value instanceof FormData) {\n for (const [entryName, entryValue] of value.entries()) formData.append(entryName, entryValue);\n\n return;\n }\n\n formData.append(name, value);\n };\n\n // jsdom's `FormData` constructor never collects a form-associated custom element's set form\n // value: real browsers walk the flat tree for every form-associated element with a `name`.\n const NativeFormData = globalThis.FormData;\n\n globalThis.FormData = class FormDataWithFormAssociatedElements extends NativeFormData {\n constructor(form?: HTMLFormElement, submitter?: HTMLElement | null) {\n super(form as HTMLFormElement | undefined, submitter as HTMLElement | null | undefined);\n\n if (!(form instanceof HTMLFormElement)) return;\n\n walkFlatTree(form, (element) => {\n const name = element.getAttribute('name');\n const value = formValueByHost.get(element);\n\n if (!name || value == null || element.hasAttribute('disabled')) return;\n\n appendFormValue(this, name, value);\n });\n }\n };\n restorers.push(() => {\n globalThis.FormData = NativeFormData;\n });\n\n // jsdom never invokes the native `formResetCallback` lifecycle method on form-associated\n // custom elements when their form resets: patch `reset()` to do it (via the same flat-tree\n // walk, since a reset field can be nested behind a shadow boundary too), so `onFormReset()`\n // (see `@vielzeug/ore`'s runtime.ts) is testable against a real `<form>.reset()` call instead\n // of only by calling `element.formResetCallback()` directly.\n const originalReset = HTMLFormElement.prototype.reset;\n\n HTMLFormElement.prototype.reset = function (this: HTMLFormElement, ...args: []) {\n originalReset.apply(this, args);\n\n walkFlatTree(this, (element) => {\n (element as Partial<{ formResetCallback: () => void }>).formResetCallback?.();\n });\n };\n restorers.push(() => {\n HTMLFormElement.prototype.reset = originalReset;\n });\n\n return () => {\n for (const restore of restorers) restore();\n\n restorers.length = 0;\n flagHost[INSTALLED_FLAG] = false;\n };\n};\n"],"mappings":"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"}