@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/node.js ADDED
@@ -0,0 +1,325 @@
1
+ import { Comparable, Comparison, } from "@siteimprove/alfa-comparable";
2
+ import { Flags } from "@siteimprove/alfa-flags";
3
+ import { Lazy } from "@siteimprove/alfa-lazy";
4
+ import { Option } from "@siteimprove/alfa-option";
5
+ import { Selective } from "@siteimprove/alfa-selective";
6
+ import { Sequence } from "@siteimprove/alfa-sequence";
7
+ import { String } from "@siteimprove/alfa-string";
8
+ import * as tree from "@siteimprove/alfa-tree";
9
+ import { Attribute, Comment, Document, Element, Fragment, Shadow, Slot, Slotable, Text, Type, } from "./index.js";
10
+ import * as predicate from "./node/predicate.js";
11
+ import * as traversal from "./node/traversal.js";
12
+ /**
13
+ * @public
14
+ */
15
+ export class Node extends tree.Node {
16
+ constructor(children, type, externalId, serializationId, extraData) {
17
+ super(children, type, externalId, serializationId, extraData);
18
+ }
19
+ /**
20
+ * {@link https://dom.spec.whatwg.org/#concept-descendant-text-content}
21
+ */
22
+ textContent(options = Node.Traversal.empty) {
23
+ return String.flatten(this.descendants(options).filter(Text.isText).join(""));
24
+ }
25
+ /**
26
+ * Construct a sequence of descendants of this node sorted by tab index. Only
27
+ * nodes with a non-negative tab index are included in the sequence.
28
+ *
29
+ * {@link https://html.spec.whatwg.org/multipage/#tabindex-value}
30
+ */
31
+ tabOrder() {
32
+ /**
33
+ * Gather candidates for sequential focus navigation.
34
+ *
35
+ * @remarks
36
+ * These are all elements that are keyboard focusable (non-negative
37
+ * tabIndex), plus the shadow hosts and content elements that may contain
38
+ * focusable descendants.
39
+ *
40
+ * It is important that the traversal is done here on the DOM tree only.
41
+ * The shadow trees and content documents will be expanded later. Doing it
42
+ * too early potentially would mix their elements during sorting of the
43
+ * tabIndexes.
44
+ */
45
+ function candidates(node) {
46
+ if (Element.isElement(node)) {
47
+ const element = node;
48
+ const tabIndex = element.tabIndex();
49
+ // If the element is a shadow host that doesn't block keyboard navigation
50
+ // we record it to later expand its shadow tree.
51
+ if (element.shadow.isSome()) {
52
+ // If the element has a negative tab index and is a shadow host then
53
+ // none of its descendants will be part of the tab order.
54
+ if (tabIndex.some((i) => i < 0)) {
55
+ return Sequence.empty();
56
+ }
57
+ else {
58
+ return Sequence.of([element, tabIndex]);
59
+ }
60
+ }
61
+ // If the element contains a content document, we record it to later
62
+ // expand its content.
63
+ if (element.content.isSome()) {
64
+ return Sequence.of([element, tabIndex]);
65
+ }
66
+ // If the element is a slot, we replace it by its assigned nodes.
67
+ if (Slot.isSlot(element)) {
68
+ return Sequence.from(element.assignedNodes())
69
+ .filter(Element.isElement)
70
+ .map((element) => [element, tabIndex]);
71
+ }
72
+ // If the element is keyboard focusable, record it and recurse.
73
+ if (tabIndex.some((i) => i >= 0)) {
74
+ return Sequence.of([element, tabIndex], Lazy.of(() => element.children().flatMap(candidates)));
75
+ }
76
+ }
77
+ // Otherwise (not an element, or not keyboard focusable), recurse into the children.
78
+ return node.children().flatMap(candidates);
79
+ }
80
+ /**
81
+ * Compare two elements, with non-negative tabindexes, by tabindex.
82
+ *
83
+ * @remarks
84
+ * Due to non-focusable shadow hosts being candidates (for shadow DOM
85
+ * expansion), we may have some indexes being None. These must be treated
86
+ * as 0 (insert in DOM order), rather than smaller than actual indexes
87
+ * (insert at start). Therefore, we cannot use Option.compareWith.
88
+ */
89
+ const comparer = ([, a], [, b]) => {
90
+ const aValue = a.getOr(0);
91
+ const bValue = b.getOr(0);
92
+ return aValue === 0
93
+ ? // "normal order" must come after any "specific order",
94
+ // i.e., 0 is greater than any positive number.
95
+ bValue === 0
96
+ ? Comparison.Equal
97
+ : Comparison.Greater
98
+ : bValue === 0
99
+ ? // aValue cannot be 0 anymore.
100
+ Comparison.Less
101
+ : // If none are 0, simply compare the values.
102
+ Comparable.compare(aValue, bValue);
103
+ };
104
+ /**
105
+ * Expand an element into the sequentially focusable elements in its
106
+ * shadow tree or content document.
107
+ *
108
+ * @remarks
109
+ * It is important that this expansion happens **after** sorting by tabindex
110
+ * since shadow DOM and content documents build their own sequential focus
111
+ * order that is inserted as-is in the light tree or parent browsing context.
112
+ * That is, a tabindex of 1 in a shadow tree or content document does
113
+ * **not** come before a tabindex of 2 in the main document.
114
+ */
115
+ function expand([element, tabIndex]) {
116
+ // In case of shadow host, we include it if its sequentially focusable,
117
+ // and always recurse into the shadow tree.
118
+ for (const shadow of element.shadow) {
119
+ if (tabIndex.some((i) => i >= 0)) {
120
+ return Sequence.of(element, Lazy.of(() => shadow.tabOrder()));
121
+ }
122
+ else {
123
+ return shadow.tabOrder();
124
+ }
125
+ }
126
+ // In case of content document, we always ignore the host (iframe) which
127
+ // usually redirects focus to the content.
128
+ for (const content of element.content) {
129
+ return content.tabOrder();
130
+ }
131
+ // If no shadow or content document, just keep the element.
132
+ return Sequence.of(element);
133
+ }
134
+ return candidates(this).sortWith(comparer).flatMap(expand);
135
+ }
136
+ parent(options = Node.Traversal.empty) {
137
+ const parent = this._parent;
138
+ // If we traverse the flat tree, we want to jump over shadow roots.
139
+ if (options.isSet(Node.Traversal.flattened)) {
140
+ return parent.flatMap((parent) => {
141
+ if (Shadow.isShadow(parent)) {
142
+ return parent.host;
143
+ }
144
+ // Additionally, if this is a slottable light child of a shadow host, we want
145
+ // to search for where it is slotted, and return that parent instead.
146
+ if (Element.isElement(parent) &&
147
+ parent.shadow.isSome() &&
148
+ Slotable.isSlotable(this)) {
149
+ return this.assignedSlot().flatMap((slot) => slot.parent(options));
150
+ }
151
+ return Option.of(parent);
152
+ });
153
+ }
154
+ return parent;
155
+ }
156
+ _path = [];
157
+ /**
158
+ * @internal
159
+ */
160
+ _internalPath(options) {
161
+ let path = this.parent(options)
162
+ .map((parent) => parent.path(options))
163
+ .getOr("/");
164
+ path += path === "/" ? "" : "/";
165
+ path += "node()";
166
+ path += `[${this.index(options) + 1}]`;
167
+ return path;
168
+ }
169
+ /**
170
+ * Get an XPath that uniquely identifies the node across descendants of its
171
+ * root.
172
+ */
173
+ // path may change if the subtree is attached to a parent, so we shouldn't
174
+ // cache it.
175
+ // However, path is a fairly "final" serialisation operation that makes
176
+ // little sense in the context of an incomplete tree.
177
+ // For the sake of simplicity, and until we encounter errors due to this,
178
+ // we accept the risk of caching the value assuming that it will only be
179
+ // computed on fully frozen trees.
180
+ path(options = Node.Traversal.empty) {
181
+ if (this._path[options.value] !== undefined) {
182
+ return this._path[options.value];
183
+ }
184
+ else {
185
+ this._path[options.value] = this._internalPath(options);
186
+ return this._internalPath(options);
187
+ }
188
+ }
189
+ equals(value) {
190
+ return value === this;
191
+ }
192
+ toEARL() {
193
+ return {
194
+ "@context": {
195
+ ptr: "http://www.w3.org/2009/pointers#",
196
+ },
197
+ "@type": [
198
+ "ptr:Pointer",
199
+ "ptr:SinglePointer",
200
+ "ptr:ExpressionPointer",
201
+ "ptr:XPathPointer",
202
+ ],
203
+ "ptr:expression": this.path(),
204
+ };
205
+ }
206
+ toSARIF() {
207
+ return {
208
+ logicalLocations: [
209
+ {
210
+ fullyQualifiedName: this.path(),
211
+ },
212
+ ],
213
+ };
214
+ }
215
+ }
216
+ /**
217
+ * @public
218
+ */
219
+ (function (Node) {
220
+ function isNode(value) {
221
+ return value instanceof Node;
222
+ }
223
+ Node.isNode = isNode;
224
+ class Traversal extends Flags {
225
+ static of(...flags) {
226
+ return new Traversal(Flags._reduce(...flags));
227
+ }
228
+ }
229
+ Node.Traversal = Traversal;
230
+ (function (Traversal) {
231
+ Traversal.none = 0;
232
+ /**
233
+ * When set, traverse the node in shadow-including tree order.
234
+ *
235
+ * {@link https://dom.spec.whatwg.org/#concept-shadow-including-tree-order}
236
+ */
237
+ Traversal.composed = (1 << 0);
238
+ /**
239
+ * When set, traverse the flattened element tree rooted at the node.
240
+ *
241
+ * {@link https://drafts.csswg.org/css-scoping/#flat-tree}
242
+ */
243
+ Traversal.flattened = (1 << 1);
244
+ /**
245
+ * When set, traverse all nested browsing contexts encountered.
246
+ *
247
+ * {@link https://html.spec.whatwg.org/#nested-browsing-context}
248
+ */
249
+ Traversal.nested = (1 << 2);
250
+ Traversal.empty = Traversal.of(Traversal.none);
251
+ })(Traversal = Node.Traversal || (Node.Traversal = {}));
252
+ /**
253
+ * Traversal options to traverse the flat tree.
254
+ *
255
+ * {@link https://drafts.csswg.org/css-scoping-1/#flattening}
256
+ */
257
+ Node.flatTree = Traversal.of(Traversal.flattened);
258
+ /**
259
+ * Traversal options to traverse all relevant nodes (flat tree and inside
260
+ * nested browsing container), a very frequent use case.
261
+ */
262
+ Node.fullTree = Traversal.of(Traversal.flattened, Traversal.nested);
263
+ /**
264
+ * Traversal options to traverse in shadow-including tree order and inside
265
+ * nested browsing context container, a common use case.
266
+ */
267
+ Node.composedNested = Traversal.of(Traversal.composed, Traversal.nested);
268
+ function from(json, device) {
269
+ return fromNode(json, device).run();
270
+ }
271
+ Node.from = from;
272
+ /**
273
+ * @internal
274
+ */
275
+ function fromNode(json, device) {
276
+ switch (json.type) {
277
+ case "element":
278
+ return Element.fromElement(json, device);
279
+ case "attribute":
280
+ return Attribute.fromAttribute(json);
281
+ case "text":
282
+ return Text.fromText(json);
283
+ case "comment":
284
+ return Comment.fromComment(json);
285
+ case "document":
286
+ return Document.fromDocument(json, device);
287
+ case "type":
288
+ return Type.fromType(json);
289
+ case "fragment":
290
+ return Fragment.fromFragment(json, device);
291
+ default:
292
+ throw new Error(`Unexpected node of type: ${json.type}`);
293
+ }
294
+ }
295
+ Node.fromNode = fromNode;
296
+ function clone(node, options, device) {
297
+ return cloneNode(node, options, device).run();
298
+ }
299
+ Node.clone = clone;
300
+ /**
301
+ * @internal
302
+ */
303
+ function cloneNode(node, options = {
304
+ predicate: () => false,
305
+ newElements: [],
306
+ }, device) {
307
+ return Selective.of(node)
308
+ .if(Element.isElement, Element.cloneElement(options, device))
309
+ .if(Attribute.isAttribute, Attribute.cloneAttribute)
310
+ .if(Text.isText, Text.cloneText)
311
+ .if(Comment.isComment, Comment.cloneComment)
312
+ .if(Document.isDocument, Document.cloneDocument(options, device))
313
+ .if(Type.isType, Type.cloneType)
314
+ .if(Fragment.isFragment, Fragment.cloneFragment(options, device))
315
+ .if(Shadow.isShadow, Shadow.cloneShadow(options, device))
316
+ .else(() => {
317
+ throw new Error(`Unexpected node of type: ${node.type}`);
318
+ })
319
+ .get();
320
+ }
321
+ Node.cloneNode = cloneNode;
322
+ Node.getNodesBetween = traversal.getNodesBetween;
323
+ Node.hasChild = predicate.hasChild, Node.hasDescendant = predicate.hasDescendant, Node.hasInclusiveDescendant = predicate.hasInclusiveDescendant, Node.hasTextContent = predicate.hasTextContent, Node.isRoot = predicate.isRoot;
324
+ })(Node || (Node = {}));
325
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1,30 @@
1
+ import type { Equatable } from "@siteimprove/alfa-equatable";
2
+ import { Iterable } from "@siteimprove/alfa-iterable";
3
+ import type { Serializable } from "@siteimprove/alfa-json";
4
+ import { Option } from "@siteimprove/alfa-option";
5
+ import type { Predicate } from "@siteimprove/alfa-predicate";
6
+ import { Declaration } from "./declaration.js";
7
+ /**
8
+ * @public
9
+ */
10
+ export declare class Block implements Iterable<Declaration>, Equatable, Serializable {
11
+ static of(declarations: Iterable<Declaration>): Block;
12
+ private _declarations;
13
+ private constructor();
14
+ get declarations(): Iterable<Declaration>;
15
+ get size(): number;
16
+ isEmpty(): boolean;
17
+ declaration(predicate: string | Predicate<Declaration>): Option<Declaration>;
18
+ equals(value: unknown): value is this;
19
+ [Symbol.iterator](): Iterator<Declaration>;
20
+ toJSON(): Block.JSON;
21
+ toString(): string;
22
+ }
23
+ /**
24
+ * @public
25
+ */
26
+ export declare namespace Block {
27
+ type JSON = Array<Declaration.JSON>;
28
+ function from(jsonOrText: JSON | string): Block;
29
+ }
30
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1,63 @@
1
+ import { Declaration as CSSDeclaration, Lexer } from "@siteimprove/alfa-css";
2
+ import { Iterable } from "@siteimprove/alfa-iterable";
3
+ import { Option } from "@siteimprove/alfa-option";
4
+ import { Declaration } from "./declaration.js";
5
+ /**
6
+ * @public
7
+ */
8
+ export class Block {
9
+ static of(declarations) {
10
+ return new Block(Array.from(declarations));
11
+ }
12
+ _declarations;
13
+ constructor(declarations) {
14
+ this._declarations = declarations;
15
+ }
16
+ get declarations() {
17
+ return this._declarations;
18
+ }
19
+ get size() {
20
+ return this._declarations.length;
21
+ }
22
+ isEmpty() {
23
+ return this._declarations.length === 0;
24
+ }
25
+ declaration(predicate) {
26
+ return Option.from(this._declarations.find(typeof predicate === "string"
27
+ ? (declaration) => declaration.name === predicate
28
+ : predicate));
29
+ }
30
+ equals(value) {
31
+ return (value instanceof Block &&
32
+ value._declarations.length === this._declarations.length &&
33
+ value._declarations.every((declaration, i) => declaration.equals(this._declarations[i])));
34
+ }
35
+ *[Symbol.iterator]() {
36
+ yield* this._declarations;
37
+ }
38
+ toJSON() {
39
+ return this._declarations.map((declaration) => declaration.toJSON());
40
+ }
41
+ toString() {
42
+ return this._declarations.join(";\n");
43
+ }
44
+ }
45
+ /**
46
+ * @public
47
+ */
48
+ (function (Block) {
49
+ function from(jsonOrText) {
50
+ if (typeof jsonOrText === "string") {
51
+ return Block.of(Iterable.map(CSSDeclaration.parseList(Lexer.lex(jsonOrText)).getUnsafe(`Could not parse CSS declarations "${jsonOrText}"`)[1], (declaration) => Declaration.from({
52
+ name: declaration.name,
53
+ value: declaration.value.join(""),
54
+ important: declaration.important,
55
+ })));
56
+ }
57
+ else {
58
+ return Block.of(jsonOrText.map(Declaration.from));
59
+ }
60
+ }
61
+ Block.from = from;
62
+ })(Block || (Block = {}));
63
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1,65 @@
1
+ import type { Equatable } from "@siteimprove/alfa-equatable";
2
+ import type { Serializable } from "@siteimprove/alfa-json";
3
+ import { Option } from "@siteimprove/alfa-option";
4
+ import type * as json from "@siteimprove/alfa-json";
5
+ import type { Element } from "../node/element.js";
6
+ import type { Rule } from "./rule.js";
7
+ /**
8
+ * @public
9
+ */
10
+ export declare class Declaration implements Equatable, Serializable {
11
+ static of(name: string, value: string, important?: boolean): Declaration;
12
+ private readonly _name;
13
+ private readonly _value;
14
+ private readonly _important;
15
+ /**
16
+ * @remarks
17
+ * If the declaration is in a style rule, point to it
18
+ */
19
+ private _parent;
20
+ /**
21
+ * @remarks
22
+ * If the declaration is in a style attribute on an element, point to it
23
+ *
24
+ * @remarks
25
+ * "owner" use the same vocabulary as attribute's owner
26
+ *
27
+ * @remarks
28
+ * Only one of _parent and _owner should be Some.
29
+ */
30
+ private _owner;
31
+ private constructor();
32
+ get name(): string;
33
+ get value(): string;
34
+ get important(): boolean;
35
+ get parent(): Option<Rule>;
36
+ get owner(): Option<Element>;
37
+ ancestors(): Iterable<Rule>;
38
+ /**
39
+ * Parent rule or owner element are ignored for declaration equality.
40
+ */
41
+ equals(value: unknown): value is this;
42
+ toJSON(): Declaration.JSON;
43
+ toString(): string;
44
+ /**
45
+ * @internal
46
+ */
47
+ _attachParent(parent: Rule): boolean;
48
+ /**
49
+ * @internal
50
+ */
51
+ _attachOwner(owner: Element): boolean;
52
+ }
53
+ /**
54
+ * @public
55
+ */
56
+ export declare namespace Declaration {
57
+ interface JSON {
58
+ [key: string]: json.JSON;
59
+ name: string;
60
+ value: string;
61
+ important: boolean;
62
+ }
63
+ function from(json: JSON): Declaration;
64
+ }
65
+ //# sourceMappingURL=declaration.d.ts.map
@@ -0,0 +1,103 @@
1
+ import { None, Option } from "@siteimprove/alfa-option";
2
+ /**
3
+ * @public
4
+ */
5
+ export class Declaration {
6
+ static of(name, value, important = false) {
7
+ return new Declaration(name, value, important);
8
+ }
9
+ _name;
10
+ _value;
11
+ _important;
12
+ /**
13
+ * @remarks
14
+ * If the declaration is in a style rule, point to it
15
+ */
16
+ _parent = None;
17
+ /**
18
+ * @remarks
19
+ * If the declaration is in a style attribute on an element, point to it
20
+ *
21
+ * @remarks
22
+ * "owner" use the same vocabulary as attribute's owner
23
+ *
24
+ * @remarks
25
+ * Only one of _parent and _owner should be Some.
26
+ */
27
+ _owner = None;
28
+ constructor(name, value, important) {
29
+ this._name = name;
30
+ this._value = value;
31
+ this._important = important;
32
+ }
33
+ get name() {
34
+ return this._name;
35
+ }
36
+ get value() {
37
+ return this._value;
38
+ }
39
+ get important() {
40
+ return this._important;
41
+ }
42
+ get parent() {
43
+ return this._parent;
44
+ }
45
+ get owner() {
46
+ return this._owner;
47
+ }
48
+ *ancestors() {
49
+ for (const parent of this._parent) {
50
+ yield parent;
51
+ yield* parent.ancestors();
52
+ }
53
+ }
54
+ /**
55
+ * Parent rule or owner element are ignored for declaration equality.
56
+ */
57
+ equals(value) {
58
+ return (value instanceof Declaration &&
59
+ value._name === this._name &&
60
+ value._value === this._value &&
61
+ value._important === this._important);
62
+ }
63
+ toJSON() {
64
+ return {
65
+ name: this._name,
66
+ value: this._value,
67
+ important: this._important,
68
+ };
69
+ }
70
+ toString() {
71
+ return `${this._name}: ${this._value}${this._important ? " !important" : ""}`;
72
+ }
73
+ /**
74
+ * @internal
75
+ */
76
+ _attachParent(parent) {
77
+ if (this._parent.isSome() || this._owner.isSome()) {
78
+ return false;
79
+ }
80
+ this._parent = Option.of(parent);
81
+ return true;
82
+ }
83
+ /**
84
+ * @internal
85
+ */
86
+ _attachOwner(owner) {
87
+ if (this._parent.isSome() || this._owner.isSome()) {
88
+ return false;
89
+ }
90
+ this._owner = Option.of(owner);
91
+ return true;
92
+ }
93
+ }
94
+ /**
95
+ * @public
96
+ */
97
+ (function (Declaration) {
98
+ function from(json) {
99
+ return Declaration.of(json.name, json.value, json.important);
100
+ }
101
+ Declaration.from = from;
102
+ })(Declaration || (Declaration = {}));
103
+ //# sourceMappingURL=declaration.js.map
@@ -0,0 +1,21 @@
1
+ import type { Rule } from "../rule.js";
2
+ import { GroupingRule } from "./grouping.js";
3
+ /**
4
+ * @public
5
+ */
6
+ export declare abstract class ConditionRule<T extends string = string> extends GroupingRule<T> {
7
+ protected readonly _condition: string;
8
+ protected constructor(type: T, condition: string, rules: Array<Rule>);
9
+ get condition(): string;
10
+ toJSON(): ConditionRule.JSON<T>;
11
+ }
12
+ /**
13
+ * @public
14
+ */
15
+ export declare namespace ConditionRule {
16
+ interface JSON<T extends string = string> extends GroupingRule.JSON<T> {
17
+ condition: string;
18
+ }
19
+ function isConditionRule(value: unknown): value is ConditionRule;
20
+ }
21
+ //# sourceMappingURL=condition.d.ts.map
@@ -0,0 +1,30 @@
1
+ import { GroupingRule } from "./grouping.js";
2
+ /**
3
+ * @public
4
+ */
5
+ export class ConditionRule extends GroupingRule {
6
+ _condition;
7
+ constructor(type, condition, rules) {
8
+ super(type, rules);
9
+ this._condition = condition;
10
+ }
11
+ get condition() {
12
+ return this._condition;
13
+ }
14
+ toJSON() {
15
+ return {
16
+ ...super.toJSON(),
17
+ condition: this._condition,
18
+ };
19
+ }
20
+ }
21
+ /**
22
+ * @public
23
+ */
24
+ (function (ConditionRule) {
25
+ function isConditionRule(value) {
26
+ return value instanceof ConditionRule;
27
+ }
28
+ ConditionRule.isConditionRule = isConditionRule;
29
+ })(ConditionRule || (ConditionRule = {}));
30
+ //# sourceMappingURL=condition.js.map
@@ -0,0 +1,29 @@
1
+ import { Trampoline } from "@siteimprove/alfa-trampoline";
2
+ import { Block } from "../block.js";
3
+ import type { Declaration } from "../declaration.js";
4
+ import { Rule } from "../rule.js";
5
+ /**
6
+ * @public
7
+ */
8
+ export declare class FontFaceRule extends Rule<"font-face"> {
9
+ static of(declarations: Iterable<Declaration>): FontFaceRule;
10
+ private readonly _style;
11
+ private constructor();
12
+ get style(): Block;
13
+ toJSON(): FontFaceRule.JSON;
14
+ toString(): string;
15
+ }
16
+ /**
17
+ * @public
18
+ */
19
+ export declare namespace FontFaceRule {
20
+ interface JSON extends Rule.JSON<"font-face"> {
21
+ style: Block.JSON | string;
22
+ }
23
+ function isFontFaceRule(value: unknown): value is FontFaceRule;
24
+ /**
25
+ * @internal
26
+ */
27
+ function fromFontFaceRule(json: JSON): Trampoline<FontFaceRule>;
28
+ }
29
+ //# sourceMappingURL=font-face.d.ts.map