@siteimprove/alfa-dom 0.89.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/CHANGELOG.md +291 -0
  2. package/dist/h.d.ts +37 -0
  3. package/dist/h.js +214 -0
  4. package/dist/index.d.ts +32 -0
  5. package/dist/index.js +32 -0
  6. package/dist/jsx-runtime.d.ts +26 -0
  7. package/dist/jsx-runtime.js +41 -0
  8. package/dist/jsx.d.ts +44 -0
  9. package/dist/jsx.js +45 -0
  10. package/dist/namespace.d.ts +43 -0
  11. package/dist/namespace.js +57 -0
  12. package/dist/native.d.ts +18 -0
  13. package/dist/native.js +449 -0
  14. package/dist/node/attribute/predicate/has-name.d.ts +11 -0
  15. package/dist/node/attribute/predicate/has-name.js +13 -0
  16. package/dist/node/attribute/predicate.d.ts +2 -0
  17. package/dist/node/attribute/predicate.js +2 -0
  18. package/dist/node/attribute.d.ts +90 -0
  19. package/dist/node/attribute.js +164 -0
  20. package/dist/node/comment.d.ts +42 -0
  21. package/dist/node/comment.js +74 -0
  22. package/dist/node/document.d.ts +59 -0
  23. package/dist/node/document.js +113 -0
  24. package/dist/node/element/input-type.d.ts +12 -0
  25. package/dist/node/element/input-type.js +10 -0
  26. package/dist/node/element/predicate/has-attribute.d.ts +12 -0
  27. package/dist/node/element/predicate/has-attribute.js +11 -0
  28. package/dist/node/element/predicate/has-box.d.ts +9 -0
  29. package/dist/node/element/predicate/has-box.js +7 -0
  30. package/dist/node/element/predicate/has-display-size.d.ts +7 -0
  31. package/dist/node/element/predicate/has-display-size.js +28 -0
  32. package/dist/node/element/predicate/has-id.d.ts +16 -0
  33. package/dist/node/element/predicate/has-id.js +17 -0
  34. package/dist/node/element/predicate/has-input-type.d.ts +12 -0
  35. package/dist/node/element/predicate/has-input-type.js +17 -0
  36. package/dist/node/element/predicate/has-name.d.ts +11 -0
  37. package/dist/node/element/predicate/has-name.js +13 -0
  38. package/dist/node/element/predicate/has-namespace.d.ts +12 -0
  39. package/dist/node/element/predicate/has-namespace.js +13 -0
  40. package/dist/node/element/predicate/has-tab-index.d.ts +12 -0
  41. package/dist/node/element/predicate/has-tab-index.js +11 -0
  42. package/dist/node/element/predicate/has-unique-id.d.ts +7 -0
  43. package/dist/node/element/predicate/has-unique-id.js +31 -0
  44. package/dist/node/element/predicate/is-actually-disabled.d.ts +8 -0
  45. package/dist/node/element/predicate/is-actually-disabled.js +47 -0
  46. package/dist/node/element/predicate/is-browsing-context-container.d.ts +8 -0
  47. package/dist/node/element/predicate/is-browsing-context-container.js +20 -0
  48. package/dist/node/element/predicate/is-content.d.ts +10 -0
  49. package/dist/node/element/predicate/is-content.js +17 -0
  50. package/dist/node/element/predicate/is-document-element.d.ts +6 -0
  51. package/dist/node/element/predicate/is-document-element.js +13 -0
  52. package/dist/node/element/predicate/is-draggable.d.ts +8 -0
  53. package/dist/node/element/predicate/is-draggable.js +28 -0
  54. package/dist/node/element/predicate/is-editing-host.d.ts +8 -0
  55. package/dist/node/element/predicate/is-editing-host.js +20 -0
  56. package/dist/node/element/predicate/is-fallback.d.ts +15 -0
  57. package/dist/node/element/predicate/is-fallback.js +28 -0
  58. package/dist/node/element/predicate/is-replaced.d.ts +8 -0
  59. package/dist/node/element/predicate/is-replaced.js +17 -0
  60. package/dist/node/element/predicate/is-scoped-to.d.ts +7 -0
  61. package/dist/node/element/predicate/is-scoped-to.js +11 -0
  62. package/dist/node/element/predicate/is-suggested-focusable.d.ts +14 -0
  63. package/dist/node/element/predicate/is-suggested-focusable.js +47 -0
  64. package/dist/node/element/predicate.d.ts +20 -0
  65. package/dist/node/element/predicate.js +20 -0
  66. package/dist/node/element.d.ts +122 -0
  67. package/dist/node/element.js +330 -0
  68. package/dist/node/fragment.d.ts +38 -0
  69. package/dist/node/fragment.js +68 -0
  70. package/dist/node/predicate/has-child.d.ts +7 -0
  71. package/dist/node/predicate/has-child.js +8 -0
  72. package/dist/node/predicate/has-descendant.d.ts +7 -0
  73. package/dist/node/predicate/has-descendant.js +8 -0
  74. package/dist/node/predicate/has-inclusive-descendant.d.ts +7 -0
  75. package/dist/node/predicate/has-inclusive-descendant.js +8 -0
  76. package/dist/node/predicate/has-text-content.d.ts +7 -0
  77. package/dist/node/predicate/has-text-content.js +12 -0
  78. package/dist/node/predicate/is-root.d.ts +7 -0
  79. package/dist/node/predicate/is-root.js +7 -0
  80. package/dist/node/predicate.d.ts +6 -0
  81. package/dist/node/predicate.js +6 -0
  82. package/dist/node/query/element-descendants.d.ts +8 -0
  83. package/dist/node/query/element-descendants.js +17 -0
  84. package/dist/node/query/element-id-map.d.ts +14 -0
  85. package/dist/node/query/element-id-map.js +30 -0
  86. package/dist/node/query/inclusive-element-descendants.d.ts +8 -0
  87. package/dist/node/query/inclusive-element-descendants.js +10 -0
  88. package/dist/node/query/index.d.ts +12 -0
  89. package/dist/node/query/index.js +13 -0
  90. package/dist/node/shadow.d.ts +66 -0
  91. package/dist/node/shadow.js +128 -0
  92. package/dist/node/slot.d.ts +29 -0
  93. package/dist/node/slot.js +41 -0
  94. package/dist/node/slotable.d.ts +29 -0
  95. package/dist/node/slotable.js +40 -0
  96. package/dist/node/text.d.ts +46 -0
  97. package/dist/node/text.js +83 -0
  98. package/dist/node/traversal/get-nodes-between.d.ts +24 -0
  99. package/dist/node/traversal/get-nodes-between.js +62 -0
  100. package/dist/node/traversal/lowest-common-ancestor.d.ts +13 -0
  101. package/dist/node/traversal/lowest-common-ancestor.js +19 -0
  102. package/dist/node/traversal.d.ts +2 -0
  103. package/dist/node/traversal.js +2 -0
  104. package/dist/node/type.d.ts +45 -0
  105. package/dist/node/type.js +74 -0
  106. package/dist/node.d.ts +263 -0
  107. package/dist/node.js +325 -0
  108. package/dist/style/block.d.ts +30 -0
  109. package/dist/style/block.js +63 -0
  110. package/dist/style/declaration.d.ts +65 -0
  111. package/dist/style/declaration.js +103 -0
  112. package/dist/style/rule/condition.d.ts +21 -0
  113. package/dist/style/rule/condition.js +30 -0
  114. package/dist/style/rule/font-face.d.ts +29 -0
  115. package/dist/style/rule/font-face.js +47 -0
  116. package/dist/style/rule/grouping.d.ts +22 -0
  117. package/dist/style/rule/grouping.js +34 -0
  118. package/dist/style/rule/import.d.ts +47 -0
  119. package/dist/style/rule/import.js +114 -0
  120. package/dist/style/rule/keyframe.d.ts +32 -0
  121. package/dist/style/rule/keyframe.js +53 -0
  122. package/dist/style/rule/keyframes.d.ts +28 -0
  123. package/dist/style/rule/keyframes.js +49 -0
  124. package/dist/style/rule/layer.d.ts +61 -0
  125. package/dist/style/rule/layer.js +106 -0
  126. package/dist/style/rule/media.d.ts +32 -0
  127. package/dist/style/rule/media.js +54 -0
  128. package/dist/style/rule/namespace.d.ts +31 -0
  129. package/dist/style/rule/namespace.js +52 -0
  130. package/dist/style/rule/page.d.ts +32 -0
  131. package/dist/style/rule/page.js +53 -0
  132. package/dist/style/rule/style.d.ts +35 -0
  133. package/dist/style/rule/style.js +62 -0
  134. package/dist/style/rule/supports.d.ts +32 -0
  135. package/dist/style/rule/supports.js +56 -0
  136. package/dist/style/rule.d.ts +60 -0
  137. package/dist/style/rule.js +109 -0
  138. package/dist/style/sheet.d.ts +37 -0
  139. package/dist/style/sheet.js +66 -0
  140. package/package.json +69 -0
package/dist/jsx.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ import type { Element, Node } from "./index.js";
2
+ import type * as dom from "./index.js";
3
+ /**
4
+ * @public
5
+ */
6
+ export declare function jsx<N extends string = string>(name: N, properties?: jsx.Properties | null, ...children: jsx.Children): Element<N>;
7
+ /**
8
+ * @public
9
+ */
10
+ export declare namespace jsx {
11
+ type Child = Node | string;
12
+ /**
13
+ * @remarks
14
+ * This type is declared using the short array syntax (`[]`) to avoid issues
15
+ * with circular generic references.
16
+ */
17
+ type Children = (Child | Children)[];
18
+ interface Properties {
19
+ [name: string]: unknown;
20
+ /**
21
+ * An optional record of CSS property names and their associated values.
22
+ * This works similarly to the `style` property in React.
23
+ *
24
+ * {@link https://reactjs.org/docs/dom-elements.html#style}
25
+ */
26
+ style?: Record<string, string>;
27
+ }
28
+ /**
29
+ * {@link https://www.typescriptlang.org/docs/handbook/jsx.html}
30
+ *
31
+ * @remarks
32
+ * This namespace is currently needed to let the TypeScript compiler know the
33
+ * shape of elements returned by `jsx()` and the properties that tags allow.
34
+ * We should keep an eye on https://github.com/microsoft/TypeScript/issues/14729
35
+ * as it might provide an opportunity to get rid of this namespace entirely.
36
+ */
37
+ namespace JSX {
38
+ type Element<N extends string = string> = dom.Element<N>;
39
+ interface IntrinsicElements {
40
+ [tag: string]: Properties;
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=jsx.d.ts.map
package/dist/jsx.js ADDED
@@ -0,0 +1,45 @@
1
+ import { h } from "./h.js";
2
+ import { Rectangle } from "@siteimprove/alfa-rectangle";
3
+ const { entries } = Object;
4
+ /**
5
+ * @public
6
+ */
7
+ export function jsx(name, properties = null, ...children) {
8
+ const attributes = {};
9
+ const style = {};
10
+ let box = undefined;
11
+ let device = undefined;
12
+ let externalId = undefined;
13
+ let serializationId = undefined;
14
+ for (const [name, value] of entries(properties ?? {})) {
15
+ if (value === null || value === undefined) {
16
+ continue;
17
+ }
18
+ switch (name) {
19
+ case "style":
20
+ for (const [propName, propValue] of entries(value)) {
21
+ style[propName] = propValue;
22
+ }
23
+ continue;
24
+ case "box":
25
+ const deviceAndBox = value;
26
+ box = Rectangle.from(deviceAndBox);
27
+ device = deviceAndBox.device;
28
+ continue;
29
+ case "externalId":
30
+ if (typeof value === "string") {
31
+ externalId = value;
32
+ }
33
+ continue;
34
+ case "serializationId":
35
+ if (typeof value === "string") {
36
+ serializationId = value;
37
+ }
38
+ continue;
39
+ default:
40
+ attributes[name] = value === true ? value : `${value}`;
41
+ }
42
+ }
43
+ return h(name, attributes, children.flat(Infinity), style, box, device, externalId, serializationId);
44
+ }
45
+ //# sourceMappingURL=jsx.js.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * {@link https://infra.spec.whatwg.org/#namespaces}
3
+ *
4
+ * @public
5
+ */
6
+ export declare enum Namespace {
7
+ /**
8
+ * {@link https://infra.spec.whatwg.org/#html-namespace}
9
+ */
10
+ HTML = "http://www.w3.org/1999/xhtml",
11
+ /**
12
+ * {@link https://infra.spec.whatwg.org/#mathml-namespace}
13
+ */
14
+ MathML = "http://www.w3.org/1998/Math/MathML",
15
+ /**
16
+ * {@link https://infra.spec.whatwg.org/#svg-namespace}
17
+ */
18
+ SVG = "http://www.w3.org/2000/svg",
19
+ /**
20
+ * {@link https://infra.spec.whatwg.org/#xlink-namespace}
21
+ */
22
+ XLink = "http://www.w3.org/1999/xlink",
23
+ /**
24
+ * {@link https://infra.spec.whatwg.org/#xml-namespace}
25
+ */
26
+ XML = "http://www.w3.org/XML/1998/namespace",
27
+ /**
28
+ * @remarks
29
+ * The trailing slash is not a typo! For some reason it snuck its way into the
30
+ * specification and whether or not it is strictly required is an awfully good
31
+ * question.
32
+ *
33
+ * {@link https://infra.spec.whatwg.org/#xmlns-namespace}
34
+ */
35
+ XMLNS = "http://www.w3.org/2000/xmlns/"
36
+ }
37
+ /**
38
+ * @public
39
+ */
40
+ export declare namespace Namespace {
41
+ function isNamespace(value: string): value is Namespace;
42
+ }
43
+ //# sourceMappingURL=namespace.d.ts.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * {@link https://infra.spec.whatwg.org/#namespaces}
3
+ *
4
+ * @public
5
+ */
6
+ export var Namespace;
7
+ (function (Namespace) {
8
+ /**
9
+ * {@link https://infra.spec.whatwg.org/#html-namespace}
10
+ */
11
+ Namespace["HTML"] = "http://www.w3.org/1999/xhtml";
12
+ /**
13
+ * {@link https://infra.spec.whatwg.org/#mathml-namespace}
14
+ */
15
+ Namespace["MathML"] = "http://www.w3.org/1998/Math/MathML";
16
+ /**
17
+ * {@link https://infra.spec.whatwg.org/#svg-namespace}
18
+ */
19
+ Namespace["SVG"] = "http://www.w3.org/2000/svg";
20
+ /**
21
+ * {@link https://infra.spec.whatwg.org/#xlink-namespace}
22
+ */
23
+ Namespace["XLink"] = "http://www.w3.org/1999/xlink";
24
+ /**
25
+ * {@link https://infra.spec.whatwg.org/#xml-namespace}
26
+ */
27
+ Namespace["XML"] = "http://www.w3.org/XML/1998/namespace";
28
+ /**
29
+ * @remarks
30
+ * The trailing slash is not a typo! For some reason it snuck its way into the
31
+ * specification and whether or not it is strictly required is an awfully good
32
+ * question.
33
+ *
34
+ * {@link https://infra.spec.whatwg.org/#xmlns-namespace}
35
+ */
36
+ Namespace["XMLNS"] = "http://www.w3.org/2000/xmlns/";
37
+ })(Namespace || (Namespace = {}));
38
+ /**
39
+ * @public
40
+ */
41
+ (function (Namespace) {
42
+ function isNamespace(value) {
43
+ switch (value) {
44
+ case Namespace.HTML:
45
+ case Namespace.MathML:
46
+ case Namespace.SVG:
47
+ case Namespace.XLink:
48
+ case Namespace.XML:
49
+ case Namespace.XMLNS:
50
+ return true;
51
+ default:
52
+ return false;
53
+ }
54
+ }
55
+ Namespace.isNamespace = isNamespace;
56
+ })(Namespace || (Namespace = {}));
57
+ //# sourceMappingURL=namespace.js.map
@@ -0,0 +1,18 @@
1
+ import type { Attribute, Comment, Document, Element, Node, Text, Type } from "./index.js";
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare namespace Native {
6
+ function fromNode(node: globalThis.Element, options?: Options): Promise<Element.JSON>;
7
+ function fromNode(node: globalThis.Attr, options?: Options): Promise<Attribute.JSON>;
8
+ function fromNode(node: globalThis.Text, options?: Options): Promise<Text.JSON>;
9
+ function fromNode(node: globalThis.Comment, options?: Options): Promise<Comment.JSON>;
10
+ function fromNode(node: globalThis.Document, options?: Options): Promise<Document.JSON>;
11
+ function fromNode(node: globalThis.DocumentType, options?: Options): Promise<Type.JSON>;
12
+ function fromNode(node: globalThis.Node, options?: Options): Promise<Node.JSON>;
13
+ interface Options {
14
+ /** Whether to enforce anonymous CORS on <link> missing one */
15
+ withCrossOrigin?: boolean;
16
+ }
17
+ }
18
+ //# sourceMappingURL=native.d.ts.map
package/dist/native.js ADDED
@@ -0,0 +1,449 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * @internal
4
+ */
5
+ export var Native;
6
+ (function (Native) {
7
+ async function fromNode(node, options) {
8
+ const { withCrossOrigin = false } = options ?? {};
9
+ return toNode(node);
10
+ async function toNode(node) {
11
+ switch (node.nodeType) {
12
+ case node.ELEMENT_NODE:
13
+ return toElement(node);
14
+ case node.ATTRIBUTE_NODE:
15
+ return toAttribute(node);
16
+ case node.TEXT_NODE:
17
+ return toText(node);
18
+ case node.COMMENT_NODE:
19
+ return toComment(node);
20
+ case node.DOCUMENT_NODE:
21
+ return toDocument(node);
22
+ case node.DOCUMENT_TYPE_NODE:
23
+ return toType(node);
24
+ }
25
+ throw new Error(`Unsupported node of type: ${node.nodeType}`);
26
+ }
27
+ async function toElement(element) {
28
+ return {
29
+ type: "element",
30
+ namespace: element.namespaceURI,
31
+ prefix: element.prefix,
32
+ name: element.localName,
33
+ attributes: map(element.attributes, toAttribute),
34
+ style: "style" in element ? toBlock(element.style) : null,
35
+ children: await mapAsync(element.childNodes, toNode),
36
+ shadow: element.shadowRoot !== null
37
+ ? await toShadow(element.shadowRoot)
38
+ : null,
39
+ content: "contentDocument" in element && element.contentDocument !== null
40
+ ? await toDocument(element.contentDocument)
41
+ : null,
42
+ box: toRectangle(element.getBoundingClientRect()),
43
+ };
44
+ }
45
+ function toAttribute(attribute) {
46
+ return {
47
+ type: "attribute",
48
+ namespace: attribute.namespaceURI,
49
+ prefix: attribute.prefix,
50
+ name: attribute.localName,
51
+ value: attribute.value,
52
+ };
53
+ }
54
+ function toText(text) {
55
+ return {
56
+ type: "text",
57
+ data: text.data,
58
+ };
59
+ }
60
+ function toComment(comment) {
61
+ return {
62
+ type: "comment",
63
+ data: comment.data,
64
+ };
65
+ }
66
+ async function toDocument(document) {
67
+ if (withCrossOrigin) {
68
+ await ensureCrossOrigin(document);
69
+ }
70
+ return {
71
+ type: "document",
72
+ children: await mapAsync(document.childNodes, toNode),
73
+ style: getStyleSheets(document),
74
+ };
75
+ }
76
+ function toType(type) {
77
+ return {
78
+ type: "type",
79
+ name: type.name,
80
+ publicId: type.publicId === "" ? null : type.publicId,
81
+ systemId: type.systemId === "" ? null : type.systemId,
82
+ };
83
+ }
84
+ async function toShadow(shadow) {
85
+ if (withCrossOrigin) {
86
+ await ensureCrossOrigin(document);
87
+ }
88
+ return {
89
+ type: "shadow",
90
+ mode: shadow.mode,
91
+ children: await mapAsync(shadow.childNodes, toNode),
92
+ style: getStyleSheets(shadow),
93
+ };
94
+ }
95
+ /**
96
+ * @privateRemarks
97
+ * Adopted stylesheets are assumed to be ordered after document stylesheets.
98
+ *
99
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptedStyleSheets}
100
+ */
101
+ function getStyleSheets(docOrShadow) {
102
+ return [
103
+ ...map(docOrShadow.styleSheets, toSheet),
104
+ // `adoptedStyleSheets` generated by JSDOM can be undefined despite it violating the type.
105
+ // It seems this part of the specification is still not fully implemented in JSDOM as of July 2024.
106
+ // https://github.com/jsdom/jsdom/issues/3444
107
+ ...map(docOrShadow.adoptedStyleSheets ?? [], toSheet),
108
+ ];
109
+ }
110
+ function toSheet(sheet) {
111
+ let rules;
112
+ try {
113
+ rules = map(sheet.cssRules, toRule);
114
+ }
115
+ catch {
116
+ rules = [];
117
+ }
118
+ return {
119
+ rules,
120
+ disabled: sheet.disabled,
121
+ condition:
122
+ // Sheets generated by pre-renderers like JSDOM do not contain media
123
+ // at all.
124
+ // OTOH, the MediaList.mediaText interface treat null as the empty
125
+ // string, so we must do the same here (in the other direction).
126
+ (sheet?.media?.mediaText ?? "") === "" ? null : sheet.media.mediaText,
127
+ };
128
+ }
129
+ function toRule(rule) {
130
+ // In the best case, rule.constructor.name works and everything is fine.
131
+ switch (rule.constructor.name) {
132
+ case "CSSFontFaceRule":
133
+ return toFontFaceRule(rule);
134
+ case "CSSImportRule":
135
+ return toImportRule(rule);
136
+ case "CSSKeyframeRule":
137
+ return toKeyframeRule(rule);
138
+ case "CSSKeyframesRule":
139
+ return toKeyframesRule(rule);
140
+ case "CSSLayerBlockRule":
141
+ return toLayerBlockRule(rule);
142
+ case "CSSLayerStatementRule":
143
+ return toLayerStatementRule(rule);
144
+ case "CSSMediaRule":
145
+ return toMediaRule(rule);
146
+ case "CSSNamespaceRule":
147
+ return toNamespaceRule(rule);
148
+ case "CSSPageRule":
149
+ return toPageRule(rule);
150
+ case "CSSStyleRule":
151
+ return toStyleRule(rule);
152
+ case "CSSSupportsRule":
153
+ return toSupportsRule(rule);
154
+ }
155
+ // In some case (June 2024: in Firefox), rule.constructor.name returns
156
+ // undefined when used from an extension's content script. This is likely
157
+ // due to the fact that the rule has been created in the "page" world,
158
+ // but this code is evaluated in a content script world which does not
159
+ // have access to the actual constructor.
160
+ // However, in that case, .toString() seems to work… Since it may have been
161
+ // redefined along the prototype chain, we make sure to use the basic one.
162
+ // see https://stackoverflow.com/questions/43616128/undefined-javascript-object-constructor
163
+ switch (Object.prototype.toString.apply(rule)) {
164
+ case "[object CSSFontFaceRule]":
165
+ return toFontFaceRule(rule);
166
+ case "[object CSSImportRule]":
167
+ return toImportRule(rule);
168
+ case "[object CSSKeyframeRule]":
169
+ return toKeyframeRule(rule);
170
+ case "[object CSSKeyframesRule]":
171
+ return toKeyframesRule(rule);
172
+ case "[object CSSLayerBlockRule]":
173
+ return toLayerBlockRule(rule);
174
+ case "[object CSSLayerStatementRule]":
175
+ return toLayerStatementRule(rule);
176
+ case "[object CSSMediaRule]":
177
+ return toMediaRule(rule);
178
+ case "[object CSSNamespaceRule]":
179
+ return toNamespaceRule(rule);
180
+ case "[object CSSPageRule]":
181
+ return toPageRule(rule);
182
+ case "[object CSSStyleRule]":
183
+ return toStyleRule(rule);
184
+ case "[object CSSSupportsRule]":
185
+ return toSupportsRule(rule);
186
+ }
187
+ // If everything else failed, we default to the deprecated `type`.
188
+ // This is clearly bad, notably because @layer rules where introduced
189
+ // after the deprecation and thus do not have a `type` property.
190
+ // But it might still save the show in some corner cases.
191
+ switch (rule.type) {
192
+ case CSSRule.FONT_FACE_RULE:
193
+ return toFontFaceRule(rule);
194
+ case CSSRule.IMPORT_RULE:
195
+ return toImportRule(rule);
196
+ case CSSRule.KEYFRAME_RULE:
197
+ return toKeyframeRule(rule);
198
+ case CSSRule.KEYFRAMES_RULE:
199
+ return toKeyframesRule(rule);
200
+ // case "CSSLayerBlockRule":
201
+ // return toLayerBlockRule(rule);
202
+ // case "CSSLayerStatementRule":
203
+ // return toLayerStatementRule(rule);
204
+ case CSSRule.MEDIA_RULE:
205
+ return toMediaRule(rule);
206
+ case CSSRule.NAMESPACE_RULE:
207
+ return toNamespaceRule(rule);
208
+ case CSSRule.PAGE_RULE:
209
+ return toPageRule(rule);
210
+ case CSSRule.STYLE_RULE:
211
+ return toStyleRule(rule);
212
+ case CSSRule.SUPPORTS_RULE:
213
+ return toSupportsRule(rule);
214
+ }
215
+ // If nothing worked, just crash.
216
+ throw new Error(`Unsupported rule of type: ${rule.constructor.name} / ${Object.prototype.toString.apply(rule)} / ${rule.type}`);
217
+ }
218
+ function toFontFaceRule(rule) {
219
+ return {
220
+ type: "font-face",
221
+ style: toBlock(rule.style),
222
+ };
223
+ }
224
+ function toImportRule(rule) {
225
+ return {
226
+ type: "import",
227
+ rules: rule.styleSheet === null ? [] : toSheet(rule.styleSheet).rules,
228
+ condition: rule.media.mediaText === "" ? "all" : rule.media.mediaText,
229
+ href: rule.href,
230
+ supportText: rule.supportsText,
231
+ layer: rule.layerName,
232
+ };
233
+ }
234
+ function toKeyframeRule(rule) {
235
+ return {
236
+ type: "keyframe",
237
+ key: rule.keyText,
238
+ style: toBlock(rule.style),
239
+ };
240
+ }
241
+ function toKeyframesRule(rule) {
242
+ let rules;
243
+ try {
244
+ rules = map(rule.cssRules, toRule);
245
+ }
246
+ catch {
247
+ rules = [];
248
+ }
249
+ return {
250
+ type: "keyframes",
251
+ rules,
252
+ name: rule.name,
253
+ };
254
+ }
255
+ function toLayerBlockRule(rule) {
256
+ return {
257
+ type: "layer-block",
258
+ layer: rule.name,
259
+ rules: map(rule.cssRules, toRule),
260
+ };
261
+ }
262
+ function toLayerStatementRule(rule) {
263
+ return {
264
+ type: "layer-statement",
265
+ layers: [...rule.nameList],
266
+ };
267
+ }
268
+ function toMediaRule(rule) {
269
+ let rules;
270
+ try {
271
+ rules = map(rule.cssRules, toRule);
272
+ }
273
+ catch {
274
+ rules = [];
275
+ }
276
+ return {
277
+ type: "media",
278
+ condition: rule.conditionText,
279
+ rules,
280
+ };
281
+ }
282
+ function toNamespaceRule(rule) {
283
+ return {
284
+ type: "namespace",
285
+ namespace: rule.namespaceURI,
286
+ prefix: rule.prefix,
287
+ };
288
+ }
289
+ function toPageRule(rule) {
290
+ return {
291
+ type: "page",
292
+ selector: rule.selectorText,
293
+ style: toBlock(rule.style),
294
+ };
295
+ }
296
+ function toStyleRule(styleRule) {
297
+ return {
298
+ type: "style",
299
+ selector: styleRule.selectorText,
300
+ style: toBlock(styleRule.style),
301
+ };
302
+ }
303
+ function toSupportsRule(rule) {
304
+ let rules;
305
+ try {
306
+ rules = map(rule.cssRules, toRule);
307
+ }
308
+ catch {
309
+ rules = [];
310
+ }
311
+ return {
312
+ type: "supports",
313
+ condition: rule.conditionText,
314
+ rules,
315
+ };
316
+ }
317
+ /**
318
+ * @privateRemarks
319
+ * User Agents normally expose the pre-parsed declarations.
320
+ * However, there is a corner case of shorthands whose value is a `var()`
321
+ * where several UAs (as of April 2024: at least Chrome and Firefox) list
322
+ * the **longhands** in their CSSStyleDeclaration object (in the enumerable
323
+ * part), but associate no values to them, only to the corresponding
324
+ * shorthand (as expected and declared). This causes attempts to access
325
+ * the apparently declared properties through the `getPropertyValue()`
326
+ * method to return an empty string.
327
+ *
328
+ * {@link https://github.com/Siteimprove/alfa/issues/1563}
329
+ *
330
+ * To circumvent that, we simply return the raw CSS text; and delegate parsing
331
+ * to consumers, aka Block.from.
332
+ *
333
+ * Note that somehow JSDOM behaves differently and correctly associate the
334
+ * value with the shorthand. This means that the local tests using JSDOM
335
+ * are brittle and cannot detect a regression on this issue.
336
+ */
337
+ function toBlock(block) {
338
+ return block.cssText;
339
+ }
340
+ function toRectangle(domRect) {
341
+ return {
342
+ type: "rectangle",
343
+ x: domRect.x,
344
+ y: domRect.y,
345
+ width: domRect.width,
346
+ height: domRect.height,
347
+ };
348
+ }
349
+ function map(arrayLike, mapper) {
350
+ const result = new Array(arrayLike.length);
351
+ for (let i = 0, n = arrayLike.length; i < n; i++) {
352
+ result[i] = mapper(arrayLike[i]);
353
+ }
354
+ return result;
355
+ }
356
+ async function mapAsync(arrayLike, mapper) {
357
+ const result = new Array(arrayLike.length);
358
+ for (let i = 0, n = arrayLike.length; i < n; i++) {
359
+ result[i] = await mapper(arrayLike[i]);
360
+ }
361
+ return result;
362
+ }
363
+ /**
364
+ * Ensure that the needed resources for the document or shadow root, such as
365
+ * style sheets, adhere to CORS policy.
366
+ */
367
+ async function ensureCrossOrigin(documentOrShadowRoot) {
368
+ /**
369
+ * Ensure that all `<link>` elements specify the `crossorigin` attribute.
370
+ * Even `<link>` elements that reference same-origin resources will need
371
+ * this attribute as they may contain nested resource imports that risk
372
+ * violating CORS policy.
373
+ *
374
+ * Do keep in mind that this will only work for resources that also set
375
+ * appropriate CORS request headers.
376
+ */
377
+ const links = documentOrShadowRoot.querySelectorAll("link");
378
+ for (let i = 0; i < links.length; i++) {
379
+ const link = links[i];
380
+ /**
381
+ * Skip `<link>` elements for which the `crossorigin` attribute is already
382
+ * set to a valid value.
383
+ */
384
+ if (link.crossOrigin !== null) {
385
+ continue;
386
+ }
387
+ /**
388
+ * Simply setting the `crossorigin` attribute for the `<link>` element
389
+ * will not work as it must be reevaluated. We therefore create a clone,
390
+ * set the `crossorigin` attribute, and replace the original `<link>`
391
+ * element.
392
+ */
393
+ const clone = link.cloneNode();
394
+ /**
395
+ * Set the `crossorigin` attribute to `anonymous`, ensuring that
396
+ * credentials are not sent as part of the cross-origin request. This is
397
+ * incredibly important as we don't want to risk leaking credentials!
398
+ */
399
+ clone.crossOrigin = "anonymous";
400
+ /**
401
+ * Replace the original `<link>` element with its clone. For style sheets,
402
+ * this will unfortunately cause a FOUC while the browser recomputes
403
+ * styles.
404
+ *
405
+ * {@link https://en.wikipedia.org/wiki/Flash_of_unstyled_content}
406
+ */
407
+ link.parentNode.replaceChild(clone, link);
408
+ /**
409
+ * While certain resources will load synchronously from cache, others will
410
+ * not and we therefore need to await these.
411
+ */
412
+ if (shouldAwait(link)) {
413
+ /**
414
+ * Construct a promise that resolves once the `<link>` element either
415
+ * loads successfully or fails to load. If the `<link>` element fails to
416
+ * load, a request error will be logged to the console which should be
417
+ * enough indication that something didn't go quite as expected. Either
418
+ * way, we will deliver audit results even in the event of a missing
419
+ * resource.
420
+ */
421
+ await new Promise((resolve) => ["load", "error"].forEach((event) => clone.addEventListener(event, () => resolve())));
422
+ }
423
+ }
424
+ /**
425
+ * Check if the given `<link>` element should be awaited.
426
+ */
427
+ function shouldAwait(link) {
428
+ /**
429
+ * A `<link>` element with an empty `href` will cause the fetch process to
430
+ * abort with no events to await.
431
+ */
432
+ if (link.getAttribute("href")?.trim() === "") {
433
+ return false;
434
+ }
435
+ /**
436
+ * Style sheets should be awaited as these are loaded and applied
437
+ * asynchronously, often times causing additional resources to be loaded
438
+ * via `url()` references and `@import` rules.
439
+ */
440
+ if (link.rel === "stylesheet") {
441
+ return true;
442
+ }
443
+ return false;
444
+ }
445
+ }
446
+ }
447
+ Native.fromNode = fromNode;
448
+ })(Native || (Native = {}));
449
+ //# sourceMappingURL=native.js.map
@@ -0,0 +1,11 @@
1
+ import type { Refinement } from "@siteimprove/alfa-refinement";
2
+ import { Attribute } from "../../attribute.js";
3
+ /**
4
+ * @public
5
+ */
6
+ export declare function hasName<N extends string = string>(predicate: Refinement<string, N>): Refinement<Attribute, Attribute<N>>;
7
+ /**
8
+ * @public
9
+ */
10
+ export declare function hasName<N extends string = string>(name: N, ...rest: Array<N>): Refinement<Attribute, Attribute<N>>;
11
+ //# sourceMappingURL=has-name.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { Attribute } from "../../attribute.js";
2
+ export function hasName(nameOrPredicate, ...names) {
3
+ let predicate;
4
+ if (typeof nameOrPredicate === "function") {
5
+ predicate = nameOrPredicate;
6
+ }
7
+ else {
8
+ names.unshift(nameOrPredicate);
9
+ predicate = (name, attribute) => names.some((candidate) => Attribute.foldCase(candidate, attribute.owner) === name);
10
+ }
11
+ return (attribute) => predicate(attribute.name, attribute);
12
+ }
13
+ //# sourceMappingURL=has-name.js.map
@@ -0,0 +1,2 @@
1
+ export * from "./predicate/has-name.js";
2
+ //# sourceMappingURL=predicate.d.ts.map