@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.
- package/CHANGELOG.md +291 -0
- package/dist/h.d.ts +37 -0
- package/dist/h.js +214 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/jsx-runtime.d.ts +26 -0
- package/dist/jsx-runtime.js +41 -0
- package/dist/jsx.d.ts +44 -0
- package/dist/jsx.js +45 -0
- package/dist/namespace.d.ts +43 -0
- package/dist/namespace.js +57 -0
- package/dist/native.d.ts +18 -0
- package/dist/native.js +449 -0
- package/dist/node/attribute/predicate/has-name.d.ts +11 -0
- package/dist/node/attribute/predicate/has-name.js +13 -0
- package/dist/node/attribute/predicate.d.ts +2 -0
- package/dist/node/attribute/predicate.js +2 -0
- package/dist/node/attribute.d.ts +90 -0
- package/dist/node/attribute.js +164 -0
- package/dist/node/comment.d.ts +42 -0
- package/dist/node/comment.js +74 -0
- package/dist/node/document.d.ts +59 -0
- package/dist/node/document.js +113 -0
- package/dist/node/element/input-type.d.ts +12 -0
- package/dist/node/element/input-type.js +10 -0
- package/dist/node/element/predicate/has-attribute.d.ts +12 -0
- package/dist/node/element/predicate/has-attribute.js +11 -0
- package/dist/node/element/predicate/has-box.d.ts +9 -0
- package/dist/node/element/predicate/has-box.js +7 -0
- package/dist/node/element/predicate/has-display-size.d.ts +7 -0
- package/dist/node/element/predicate/has-display-size.js +28 -0
- package/dist/node/element/predicate/has-id.d.ts +16 -0
- package/dist/node/element/predicate/has-id.js +17 -0
- package/dist/node/element/predicate/has-input-type.d.ts +12 -0
- package/dist/node/element/predicate/has-input-type.js +17 -0
- package/dist/node/element/predicate/has-name.d.ts +11 -0
- package/dist/node/element/predicate/has-name.js +13 -0
- package/dist/node/element/predicate/has-namespace.d.ts +12 -0
- package/dist/node/element/predicate/has-namespace.js +13 -0
- package/dist/node/element/predicate/has-tab-index.d.ts +12 -0
- package/dist/node/element/predicate/has-tab-index.js +11 -0
- package/dist/node/element/predicate/has-unique-id.d.ts +7 -0
- package/dist/node/element/predicate/has-unique-id.js +31 -0
- package/dist/node/element/predicate/is-actually-disabled.d.ts +8 -0
- package/dist/node/element/predicate/is-actually-disabled.js +47 -0
- package/dist/node/element/predicate/is-browsing-context-container.d.ts +8 -0
- package/dist/node/element/predicate/is-browsing-context-container.js +20 -0
- package/dist/node/element/predicate/is-content.d.ts +10 -0
- package/dist/node/element/predicate/is-content.js +17 -0
- package/dist/node/element/predicate/is-document-element.d.ts +6 -0
- package/dist/node/element/predicate/is-document-element.js +13 -0
- package/dist/node/element/predicate/is-draggable.d.ts +8 -0
- package/dist/node/element/predicate/is-draggable.js +28 -0
- package/dist/node/element/predicate/is-editing-host.d.ts +8 -0
- package/dist/node/element/predicate/is-editing-host.js +20 -0
- package/dist/node/element/predicate/is-fallback.d.ts +15 -0
- package/dist/node/element/predicate/is-fallback.js +28 -0
- package/dist/node/element/predicate/is-replaced.d.ts +8 -0
- package/dist/node/element/predicate/is-replaced.js +17 -0
- package/dist/node/element/predicate/is-scoped-to.d.ts +7 -0
- package/dist/node/element/predicate/is-scoped-to.js +11 -0
- package/dist/node/element/predicate/is-suggested-focusable.d.ts +14 -0
- package/dist/node/element/predicate/is-suggested-focusable.js +47 -0
- package/dist/node/element/predicate.d.ts +20 -0
- package/dist/node/element/predicate.js +20 -0
- package/dist/node/element.d.ts +122 -0
- package/dist/node/element.js +330 -0
- package/dist/node/fragment.d.ts +38 -0
- package/dist/node/fragment.js +68 -0
- package/dist/node/predicate/has-child.d.ts +7 -0
- package/dist/node/predicate/has-child.js +8 -0
- package/dist/node/predicate/has-descendant.d.ts +7 -0
- package/dist/node/predicate/has-descendant.js +8 -0
- package/dist/node/predicate/has-inclusive-descendant.d.ts +7 -0
- package/dist/node/predicate/has-inclusive-descendant.js +8 -0
- package/dist/node/predicate/has-text-content.d.ts +7 -0
- package/dist/node/predicate/has-text-content.js +12 -0
- package/dist/node/predicate/is-root.d.ts +7 -0
- package/dist/node/predicate/is-root.js +7 -0
- package/dist/node/predicate.d.ts +6 -0
- package/dist/node/predicate.js +6 -0
- package/dist/node/query/element-descendants.d.ts +8 -0
- package/dist/node/query/element-descendants.js +17 -0
- package/dist/node/query/element-id-map.d.ts +14 -0
- package/dist/node/query/element-id-map.js +30 -0
- package/dist/node/query/inclusive-element-descendants.d.ts +8 -0
- package/dist/node/query/inclusive-element-descendants.js +10 -0
- package/dist/node/query/index.d.ts +12 -0
- package/dist/node/query/index.js +13 -0
- package/dist/node/shadow.d.ts +66 -0
- package/dist/node/shadow.js +128 -0
- package/dist/node/slot.d.ts +29 -0
- package/dist/node/slot.js +41 -0
- package/dist/node/slotable.d.ts +29 -0
- package/dist/node/slotable.js +40 -0
- package/dist/node/text.d.ts +46 -0
- package/dist/node/text.js +83 -0
- package/dist/node/traversal/get-nodes-between.d.ts +24 -0
- package/dist/node/traversal/get-nodes-between.js +62 -0
- package/dist/node/traversal/lowest-common-ancestor.d.ts +13 -0
- package/dist/node/traversal/lowest-common-ancestor.js +19 -0
- package/dist/node/traversal.d.ts +2 -0
- package/dist/node/traversal.js +2 -0
- package/dist/node/type.d.ts +45 -0
- package/dist/node/type.js +74 -0
- package/dist/node.d.ts +263 -0
- package/dist/node.js +325 -0
- package/dist/style/block.d.ts +30 -0
- package/dist/style/block.js +63 -0
- package/dist/style/declaration.d.ts +65 -0
- package/dist/style/declaration.js +103 -0
- package/dist/style/rule/condition.d.ts +21 -0
- package/dist/style/rule/condition.js +30 -0
- package/dist/style/rule/font-face.d.ts +29 -0
- package/dist/style/rule/font-face.js +47 -0
- package/dist/style/rule/grouping.d.ts +22 -0
- package/dist/style/rule/grouping.js +34 -0
- package/dist/style/rule/import.d.ts +47 -0
- package/dist/style/rule/import.js +114 -0
- package/dist/style/rule/keyframe.d.ts +32 -0
- package/dist/style/rule/keyframe.js +53 -0
- package/dist/style/rule/keyframes.d.ts +28 -0
- package/dist/style/rule/keyframes.js +49 -0
- package/dist/style/rule/layer.d.ts +61 -0
- package/dist/style/rule/layer.js +106 -0
- package/dist/style/rule/media.d.ts +32 -0
- package/dist/style/rule/media.js +54 -0
- package/dist/style/rule/namespace.d.ts +31 -0
- package/dist/style/rule/namespace.js +52 -0
- package/dist/style/rule/page.d.ts +32 -0
- package/dist/style/rule/page.js +53 -0
- package/dist/style/rule/style.d.ts +35 -0
- package/dist/style/rule/style.js +62 -0
- package/dist/style/rule/supports.d.ts +32 -0
- package/dist/style/rule/supports.js +56 -0
- package/dist/style/rule.d.ts +60 -0
- package/dist/style/rule.js +109 -0
- package/dist/style/sheet.d.ts +37 -0
- package/dist/style/sheet.js +66 -0
- package/package.json +69 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Cache } from "@siteimprove/alfa-cache";
|
|
2
|
+
import { Node } from "../../node.js";
|
|
3
|
+
import { Element } from "../element.js";
|
|
4
|
+
const _elementDescendantsCache = Cache.empty();
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export function getElementDescendants(node, options = Node.Traversal.empty) {
|
|
9
|
+
const optionsMap = _elementDescendantsCache.get(node, () => []);
|
|
10
|
+
if (optionsMap[options.value] === undefined) {
|
|
11
|
+
optionsMap[options.value] = node
|
|
12
|
+
.descendants(options)
|
|
13
|
+
.filter(Element.isElement);
|
|
14
|
+
}
|
|
15
|
+
return optionsMap[options.value];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=element-descendants.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Map } from "@siteimprove/alfa-map";
|
|
2
|
+
import type { Node } from "../../node.js";
|
|
3
|
+
import type { Element } from "../element.js";
|
|
4
|
+
/**
|
|
5
|
+
* Returns a map from id to elements, in the subtree rooted at a given node.
|
|
6
|
+
*
|
|
7
|
+
* @privateRemarks
|
|
8
|
+
* Since `id` are scoped to trees, and do not cross shadow or content boundaries,
|
|
9
|
+
* we never need traversal options.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export declare function getElementIdMap(node: Node): Map<string, Element>;
|
|
14
|
+
//# sourceMappingURL=element-id-map.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Cache } from "@siteimprove/alfa-cache";
|
|
2
|
+
import { Map } from "@siteimprove/alfa-map";
|
|
3
|
+
import { Document } from "../document.js";
|
|
4
|
+
import { getElementDescendants } from "./element-descendants.js";
|
|
5
|
+
const elementMapCache = Cache.empty();
|
|
6
|
+
/**
|
|
7
|
+
* Returns a map from id to elements, in the subtree rooted at a given node.
|
|
8
|
+
*
|
|
9
|
+
* @privateRemarks
|
|
10
|
+
* Since `id` are scoped to trees, and do not cross shadow or content boundaries,
|
|
11
|
+
* we never need traversal options.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export function getElementIdMap(node) {
|
|
16
|
+
if (Document.isDocument(node)) {
|
|
17
|
+
return elementMapCache.get(node, () => buildElementIdMap(node));
|
|
18
|
+
}
|
|
19
|
+
return buildElementIdMap(node);
|
|
20
|
+
}
|
|
21
|
+
function buildElementIdMap(node) {
|
|
22
|
+
// Build a map from ID -> element to allow fast resolution of ID references.
|
|
23
|
+
// The collected references are added to the map in reverse order to ensure
|
|
24
|
+
// that the first occurrence of a given ID is what ends up in the map in
|
|
25
|
+
// event of duplicates.
|
|
26
|
+
return Map.from(getElementDescendants(node)
|
|
27
|
+
.collect((element) => element.id.map((id) => [id, element]))
|
|
28
|
+
.reverse());
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=element-id-map.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Sequence } from "@siteimprove/alfa-sequence";
|
|
2
|
+
import { Node } from "../../node.js";
|
|
3
|
+
import { Element } from "../element.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare function getInclusiveElementDescendants(node: Element, options?: Node.Traversal): Sequence<Element>;
|
|
8
|
+
//# sourceMappingURL=inclusive-element-descendants.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Node } from "../../node.js";
|
|
2
|
+
import { Element } from "../element.js";
|
|
3
|
+
import { getElementDescendants } from "./element-descendants.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export function getInclusiveElementDescendants(node, options = Node.Traversal.empty) {
|
|
8
|
+
return getElementDescendants(node, options).prepend(node);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=inclusive-element-descendants.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as elementDescendants from "./element-descendants.js";
|
|
2
|
+
import * as elementIdMap from "./element-id-map.js";
|
|
3
|
+
import * as inclusiveElementDescendants from "./inclusive-element-descendants.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare namespace Query {
|
|
8
|
+
const getElementDescendants: typeof elementDescendants.getElementDescendants;
|
|
9
|
+
const getElementIdMap: typeof elementIdMap.getElementIdMap;
|
|
10
|
+
const getInclusiveElementDescendants: typeof inclusiveElementDescendants.getInclusiveElementDescendants;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as elementDescendants from "./element-descendants.js";
|
|
2
|
+
import * as elementIdMap from "./element-id-map.js";
|
|
3
|
+
import * as inclusiveElementDescendants from "./inclusive-element-descendants.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export var Query;
|
|
8
|
+
(function (Query) {
|
|
9
|
+
Query.getElementDescendants = elementDescendants.getElementDescendants;
|
|
10
|
+
Query.getElementIdMap = elementIdMap.getElementIdMap;
|
|
11
|
+
Query.getInclusiveElementDescendants = inclusiveElementDescendants.getInclusiveElementDescendants;
|
|
12
|
+
})(Query || (Query = {}));
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Option } from "@siteimprove/alfa-option";
|
|
2
|
+
import { Trampoline } from "@siteimprove/alfa-trampoline";
|
|
3
|
+
import type { Device } from "@siteimprove/alfa-device";
|
|
4
|
+
import { Iterable } from "@siteimprove/alfa-iterable";
|
|
5
|
+
import * as json from "@siteimprove/alfa-json";
|
|
6
|
+
import { Node } from "../node.js";
|
|
7
|
+
import { Sheet } from "../style/sheet.js";
|
|
8
|
+
import { Element } from "./element.js";
|
|
9
|
+
/**
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export declare class Shadow extends Node<"shadow"> {
|
|
13
|
+
static of(children: Iterable<Node>, style?: Iterable<Sheet>, mode?: Shadow.Mode, externalId?: string, serializationId?: string, extraData?: any): Shadow;
|
|
14
|
+
static empty(): Shadow;
|
|
15
|
+
private readonly _mode;
|
|
16
|
+
private _host;
|
|
17
|
+
private readonly _style;
|
|
18
|
+
private constructor();
|
|
19
|
+
get mode(): Shadow.Mode;
|
|
20
|
+
get host(): Option<Element>;
|
|
21
|
+
get style(): Iterable<Sheet>;
|
|
22
|
+
parent(options?: Node.Traversal): Option<Node>;
|
|
23
|
+
/**
|
|
24
|
+
* @internal
|
|
25
|
+
**/
|
|
26
|
+
protected _internalPath(options?: Node.Traversal): string;
|
|
27
|
+
toJSON(options: Node.SerializationOptions & {
|
|
28
|
+
verbosity: json.Serializable.Verbosity.Minimal | json.Serializable.Verbosity.Low;
|
|
29
|
+
}): Shadow.MinimalJSON;
|
|
30
|
+
toJSON(options?: Node.SerializationOptions): Shadow.JSON;
|
|
31
|
+
toString(): string;
|
|
32
|
+
/**
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
_attachParent(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
_attachHost(host: Element): boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export declare namespace Shadow {
|
|
45
|
+
enum Mode {
|
|
46
|
+
Open = "open",
|
|
47
|
+
Closed = "closed"
|
|
48
|
+
}
|
|
49
|
+
interface MinimalJSON extends Node.JSON {
|
|
50
|
+
}
|
|
51
|
+
interface JSON extends Node.JSON {
|
|
52
|
+
type: "shadow";
|
|
53
|
+
mode: string;
|
|
54
|
+
style: Array<Sheet.JSON>;
|
|
55
|
+
}
|
|
56
|
+
function isShadow(value: unknown): value is Shadow;
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
function fromShadow(json: JSON, device?: Device): Trampoline<Shadow>;
|
|
61
|
+
/**
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
function cloneShadow(options: Node.ElementReplacementOptions, device?: Device): (shadow: Shadow) => Trampoline<Shadow>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=shadow.d.ts.map
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { None, Option } from "@siteimprove/alfa-option";
|
|
2
|
+
import { String } from "@siteimprove/alfa-string";
|
|
3
|
+
import { Trampoline } from "@siteimprove/alfa-trampoline";
|
|
4
|
+
import { Iterable } from "@siteimprove/alfa-iterable";
|
|
5
|
+
import * as json from "@siteimprove/alfa-json";
|
|
6
|
+
import { Node } from "../node.js";
|
|
7
|
+
import { Sheet } from "../style/sheet.js";
|
|
8
|
+
import { Element } from "./element.js";
|
|
9
|
+
/**
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export class Shadow extends Node {
|
|
13
|
+
static of(children, style = [], mode = Shadow.Mode.Open, externalId, serializationId, extraData) {
|
|
14
|
+
return new Shadow(Array.from(children), Array.from(style), mode, externalId, serializationId, extraData);
|
|
15
|
+
}
|
|
16
|
+
static empty() {
|
|
17
|
+
return new Shadow([], [], Shadow.Mode.Open);
|
|
18
|
+
}
|
|
19
|
+
_mode;
|
|
20
|
+
_host = None;
|
|
21
|
+
_style;
|
|
22
|
+
constructor(children, style, mode, externalId, serializationId, extraData) {
|
|
23
|
+
super(children, "shadow", externalId, serializationId, extraData);
|
|
24
|
+
this._mode = mode;
|
|
25
|
+
this._style = style;
|
|
26
|
+
}
|
|
27
|
+
get mode() {
|
|
28
|
+
return this._mode;
|
|
29
|
+
}
|
|
30
|
+
get host() {
|
|
31
|
+
return this._host;
|
|
32
|
+
}
|
|
33
|
+
get style() {
|
|
34
|
+
return this._style;
|
|
35
|
+
}
|
|
36
|
+
parent(options = Node.Traversal.empty) {
|
|
37
|
+
// We only "land" on Shadow roots when traversing the composed tree.
|
|
38
|
+
// Notably, flattening the tree "jumps" over them.
|
|
39
|
+
if (options.isSet(Node.Traversal.composed)) {
|
|
40
|
+
return this._host;
|
|
41
|
+
}
|
|
42
|
+
return None;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @internal
|
|
46
|
+
**/
|
|
47
|
+
_internalPath(options = Node.Traversal.empty) {
|
|
48
|
+
if (options.isSet(Node.Traversal.composed)) {
|
|
49
|
+
return (this._host.map((host) => host.path(options)).getOr("") +
|
|
50
|
+
"/shadow-root()");
|
|
51
|
+
}
|
|
52
|
+
if (options.isSet(Node.Traversal.flattened)) {
|
|
53
|
+
return this._host.map((host) => host.path(options)).getOr("/");
|
|
54
|
+
}
|
|
55
|
+
return "/";
|
|
56
|
+
}
|
|
57
|
+
toJSON(options) {
|
|
58
|
+
const result = {
|
|
59
|
+
...super.toJSON(options),
|
|
60
|
+
};
|
|
61
|
+
const verbosity = options?.verbosity ?? json.Serializable.Verbosity.Medium;
|
|
62
|
+
if (verbosity < json.Serializable.Verbosity.Medium) {
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
result.mode = this._mode;
|
|
66
|
+
result.style = this._style.map((sheet) => sheet.toJSON());
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
toString() {
|
|
70
|
+
const children = this._children
|
|
71
|
+
.map((child) => String.indent(child.toString()))
|
|
72
|
+
.join("\n");
|
|
73
|
+
return `#shadow-root (${this._mode})${children === "" ? "" : `\n${children}`}`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
_attachParent() {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
_attachHost(host) {
|
|
85
|
+
if (this._frozen || this._host.isSome()) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
this._host = Option.of(host);
|
|
89
|
+
this._frozen = true;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
(function (Shadow) {
|
|
97
|
+
let Mode;
|
|
98
|
+
(function (Mode) {
|
|
99
|
+
Mode["Open"] = "open";
|
|
100
|
+
Mode["Closed"] = "closed";
|
|
101
|
+
})(Mode = Shadow.Mode || (Shadow.Mode = {}));
|
|
102
|
+
function isShadow(value) {
|
|
103
|
+
return value instanceof Shadow;
|
|
104
|
+
}
|
|
105
|
+
Shadow.isShadow = isShadow;
|
|
106
|
+
/**
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
function fromShadow(json, device) {
|
|
110
|
+
return Trampoline.traverse(json.children ?? [], (child) => Node.fromNode(child, device)).map((children) => Shadow.of(children, json.style.map(Sheet.from), json.mode, json.externalId, json.serializationId));
|
|
111
|
+
}
|
|
112
|
+
Shadow.fromShadow = fromShadow;
|
|
113
|
+
/**
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
function cloneShadow(options, device) {
|
|
117
|
+
return (shadow) => Trampoline.traverse(shadow.children(), (child) => {
|
|
118
|
+
if (Element.isElement(child) && options.predicate(child)) {
|
|
119
|
+
return Trampoline.done(Array.from(options.newElements));
|
|
120
|
+
}
|
|
121
|
+
return Node.cloneNode(child, options, device).map((node) => [node]);
|
|
122
|
+
}).map((children) => {
|
|
123
|
+
return Shadow.of(Iterable.flatten(children), shadow.style, shadow.mode, shadow.externalId, shadow.extraData, shadow.serializationId);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
Shadow.cloneShadow = cloneShadow;
|
|
127
|
+
})(Shadow || (Shadow = {}));
|
|
128
|
+
//# sourceMappingURL=shadow.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Element } from "./element.js";
|
|
2
|
+
import { Slotable } from "./slotable.js";
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface Slot extends Element {
|
|
7
|
+
/**
|
|
8
|
+
* Get the slotables assigned to this slot.
|
|
9
|
+
*
|
|
10
|
+
* {@link https://html.spec.whatwg.org/#dom-slot-assignednodes}
|
|
11
|
+
*/
|
|
12
|
+
assignedNodes(): Iterable<Slotable>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export declare namespace Slot {
|
|
18
|
+
function isSlot(element: Element): boolean;
|
|
19
|
+
function isSlot(value: unknown): value is Slot;
|
|
20
|
+
/**
|
|
21
|
+
* {@link https://dom.spec.whatwg.org/#slot-name}
|
|
22
|
+
*/
|
|
23
|
+
function name(slot: Slot): string;
|
|
24
|
+
/**
|
|
25
|
+
* {@link https://dom.spec.whatwg.org/#find-slotables}
|
|
26
|
+
*/
|
|
27
|
+
function findSlotables(slot: Slot): Iterable<Slotable>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=slot.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Element } from "./element.js";
|
|
2
|
+
import { Shadow } from "./shadow.js";
|
|
3
|
+
import { Slotable } from "./slotable.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export var Slot;
|
|
8
|
+
(function (Slot) {
|
|
9
|
+
function isSlot(value) {
|
|
10
|
+
return Element.isElement(value) && value.name === "slot";
|
|
11
|
+
}
|
|
12
|
+
Slot.isSlot = isSlot;
|
|
13
|
+
/**
|
|
14
|
+
* {@link https://dom.spec.whatwg.org/#slot-name}
|
|
15
|
+
*/
|
|
16
|
+
function name(slot) {
|
|
17
|
+
return slot
|
|
18
|
+
.attribute("name")
|
|
19
|
+
.map((name) => name.value)
|
|
20
|
+
.getOr("");
|
|
21
|
+
}
|
|
22
|
+
Slot.name = name;
|
|
23
|
+
/**
|
|
24
|
+
* {@link https://dom.spec.whatwg.org/#find-slotables}
|
|
25
|
+
*/
|
|
26
|
+
function* findSlotables(slot) {
|
|
27
|
+
const root = slot.root();
|
|
28
|
+
if (Shadow.isShadow(root)) {
|
|
29
|
+
for (const host of root.host) {
|
|
30
|
+
for (const child of host.children()) {
|
|
31
|
+
if (Slotable.isSlotable(child) &&
|
|
32
|
+
child.assignedSlot().includes(slot)) {
|
|
33
|
+
yield child;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
Slot.findSlotables = findSlotables;
|
|
40
|
+
})(Slot || (Slot = {}));
|
|
41
|
+
//# sourceMappingURL=slot.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Option } from "@siteimprove/alfa-option";
|
|
2
|
+
import type { Node } from "../node.js";
|
|
3
|
+
import { Slot } from "./slot.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface Slotable extends Node {
|
|
8
|
+
/**
|
|
9
|
+
* Get the slot that this slotable is assigned to.
|
|
10
|
+
*
|
|
11
|
+
* {@link https://dom.spec.whatwg.org/#dom-slotable-assignedslot}
|
|
12
|
+
*/
|
|
13
|
+
assignedSlot(): Option<Slot>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare namespace Slotable {
|
|
19
|
+
function isSlotable(value: unknown): value is Slotable;
|
|
20
|
+
/**
|
|
21
|
+
* {@link https://dom.spec.whatwg.org/#slotable-name}
|
|
22
|
+
*/
|
|
23
|
+
function name(slotable: Slotable): string;
|
|
24
|
+
/**
|
|
25
|
+
* {@link https://dom.spec.whatwg.org/#find-a-slot}
|
|
26
|
+
*/
|
|
27
|
+
function findSlot(slotable: Slotable): Option<Slot>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=slotable.d.ts.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Element } from "./element.js";
|
|
2
|
+
import { Slot } from "./slot.js";
|
|
3
|
+
import { Text } from "./text.js";
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export var Slotable;
|
|
8
|
+
(function (Slotable) {
|
|
9
|
+
function isSlotable(value) {
|
|
10
|
+
return Element.isElement(value) || Text.isText(value);
|
|
11
|
+
}
|
|
12
|
+
Slotable.isSlotable = isSlotable;
|
|
13
|
+
/**
|
|
14
|
+
* {@link https://dom.spec.whatwg.org/#slotable-name}
|
|
15
|
+
*/
|
|
16
|
+
function name(slotable) {
|
|
17
|
+
return Element.isElement(slotable)
|
|
18
|
+
? slotable
|
|
19
|
+
.attribute("slot")
|
|
20
|
+
.map((slot) => slot.value)
|
|
21
|
+
.getOr("")
|
|
22
|
+
: "";
|
|
23
|
+
}
|
|
24
|
+
Slotable.name = name;
|
|
25
|
+
/**
|
|
26
|
+
* {@link https://dom.spec.whatwg.org/#find-a-slot}
|
|
27
|
+
*/
|
|
28
|
+
function findSlot(slotable) {
|
|
29
|
+
const name = Slotable.name(slotable);
|
|
30
|
+
return slotable
|
|
31
|
+
.parent()
|
|
32
|
+
.filter(Element.isElement)
|
|
33
|
+
.flatMap((parent) => parent.shadow.flatMap((shadow) => shadow
|
|
34
|
+
.descendants()
|
|
35
|
+
.filter(Slot.isSlot)
|
|
36
|
+
.find((slot) => Slot.name(slot) === name)));
|
|
37
|
+
}
|
|
38
|
+
Slotable.findSlot = findSlot;
|
|
39
|
+
})(Slotable || (Slotable = {}));
|
|
40
|
+
//# sourceMappingURL=slotable.js.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Option } from "@siteimprove/alfa-option";
|
|
2
|
+
import { Trampoline } from "@siteimprove/alfa-trampoline";
|
|
3
|
+
import * as json from "@siteimprove/alfa-json";
|
|
4
|
+
import { Node } from "../node.js";
|
|
5
|
+
import type { Slot } from "./slot.js";
|
|
6
|
+
import { Slotable } from "./slotable.js";
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare class Text extends Node<"text"> implements Slotable {
|
|
11
|
+
static of(data: string, externalId?: string, serializationId?: string, extraData?: any): Text;
|
|
12
|
+
static empty(): Text;
|
|
13
|
+
private readonly _data;
|
|
14
|
+
private constructor();
|
|
15
|
+
get data(): string;
|
|
16
|
+
assignedSlot(): Option<Slot>;
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
**/
|
|
20
|
+
protected _internalPath(options?: Node.Traversal): string;
|
|
21
|
+
toJSON(options: Node.SerializationOptions & {
|
|
22
|
+
verbosity: json.Serializable.Verbosity.Minimal | json.Serializable.Verbosity.Low;
|
|
23
|
+
}): Text.MinimalJSON;
|
|
24
|
+
toJSON(options?: Node.SerializationOptions): Text.JSON;
|
|
25
|
+
toString(): string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare namespace Text {
|
|
31
|
+
interface MinimalJSON extends Node.JSON<"text"> {
|
|
32
|
+
}
|
|
33
|
+
interface JSON extends Node.JSON<"text"> {
|
|
34
|
+
data: string;
|
|
35
|
+
}
|
|
36
|
+
function isText(value: unknown): value is Text;
|
|
37
|
+
/**
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
function fromText(json: JSON): Trampoline<Text>;
|
|
41
|
+
/**
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
function cloneText(text: Text): Trampoline<Text>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Trampoline } from "@siteimprove/alfa-trampoline";
|
|
2
|
+
import * as json from "@siteimprove/alfa-json";
|
|
3
|
+
import { Node } from "../node.js";
|
|
4
|
+
import { Slotable } from "./slotable.js";
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export class Text extends Node {
|
|
9
|
+
static of(data, externalId, serializationId, extraData) {
|
|
10
|
+
return new Text(data, externalId, serializationId, extraData);
|
|
11
|
+
}
|
|
12
|
+
static empty() {
|
|
13
|
+
return new Text("");
|
|
14
|
+
}
|
|
15
|
+
_data;
|
|
16
|
+
constructor(data, externalId, serializationId, extraData) {
|
|
17
|
+
super([], "text", externalId, serializationId, extraData);
|
|
18
|
+
this._data = data;
|
|
19
|
+
}
|
|
20
|
+
get data() {
|
|
21
|
+
return this._data;
|
|
22
|
+
}
|
|
23
|
+
assignedSlot() {
|
|
24
|
+
return Slotable.findSlot(this);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @internal
|
|
28
|
+
**/
|
|
29
|
+
_internalPath(options) {
|
|
30
|
+
let path = this.parent(options)
|
|
31
|
+
.map((parent) => parent.path(options))
|
|
32
|
+
.getOr("/");
|
|
33
|
+
path += path === "/" ? "" : "/";
|
|
34
|
+
path += "text()";
|
|
35
|
+
const index = this.preceding(options).count(Text.isText);
|
|
36
|
+
path += `[${index + 1}]`;
|
|
37
|
+
return path;
|
|
38
|
+
}
|
|
39
|
+
toJSON(options) {
|
|
40
|
+
const result = {
|
|
41
|
+
...super.toJSON(options),
|
|
42
|
+
};
|
|
43
|
+
delete result.children;
|
|
44
|
+
const verbosity = options?.verbosity ?? json.Serializable.Verbosity.Medium;
|
|
45
|
+
if (verbosity < json.Serializable.Verbosity.Medium) {
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
result.data = this.data;
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
toString() {
|
|
52
|
+
const value = this.data;
|
|
53
|
+
// If the child is only spaces, we do not want to trim them to nothingness.
|
|
54
|
+
if (value.match(/\s+/) !== null) {
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
return value.trim();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
(function (Text) {
|
|
64
|
+
function isText(value) {
|
|
65
|
+
return value instanceof Text;
|
|
66
|
+
}
|
|
67
|
+
Text.isText = isText;
|
|
68
|
+
/**
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
function fromText(json) {
|
|
72
|
+
return Trampoline.done(Text.of(json.data, json.externalId, undefined, json.serializationId));
|
|
73
|
+
}
|
|
74
|
+
Text.fromText = fromText;
|
|
75
|
+
/**
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
function cloneText(text) {
|
|
79
|
+
return Trampoline.done(Text.of(text.data, text.externalId, text.extraData, text.serializationId));
|
|
80
|
+
}
|
|
81
|
+
Text.cloneText = cloneText;
|
|
82
|
+
})(Text || (Text = {}));
|
|
83
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Sequence } from "@siteimprove/alfa-sequence";
|
|
2
|
+
import { Node } from "../../index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Get content between two nodes. The relative order of the nodes is unknown.
|
|
5
|
+
* Options let it choose whether the first or second node (in tree order)
|
|
6
|
+
* should be included. By default, exclude both.
|
|
7
|
+
*
|
|
8
|
+
* When the first node is not included, all its subtree is skipped, that is we
|
|
9
|
+
* start looking after the closing tag, not after the opening one.
|
|
10
|
+
*
|
|
11
|
+
* Returns empty sequence in the corner case where both nodes are the same and
|
|
12
|
+
* at least one is excluded (i.e. considers that [X,X[ and ]X,X] are empty).
|
|
13
|
+
*
|
|
14
|
+
* Complexity: the size of the subtree anchored at the lowest common ancestor.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare function getNodesBetween(node1: Node, node2: Node, includeOptions?: Options, treeOptions?: Node.Traversal): Sequence<Node>;
|
|
19
|
+
type Options = {
|
|
20
|
+
includeFirst: boolean;
|
|
21
|
+
includeSecond: boolean;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=get-nodes-between.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Predicate } from "@siteimprove/alfa-predicate";
|
|
2
|
+
import { Sequence } from "@siteimprove/alfa-sequence";
|
|
3
|
+
import { Node } from "../../index.js";
|
|
4
|
+
import { lowestCommonAncestor } from "./lowest-common-ancestor.js";
|
|
5
|
+
const { equals, or } = Predicate;
|
|
6
|
+
/**
|
|
7
|
+
* Get content between two nodes. The relative order of the nodes is unknown.
|
|
8
|
+
* Options let it choose whether the first or second node (in tree order)
|
|
9
|
+
* should be included. By default, exclude both.
|
|
10
|
+
*
|
|
11
|
+
* When the first node is not included, all its subtree is skipped, that is we
|
|
12
|
+
* start looking after the closing tag, not after the opening one.
|
|
13
|
+
*
|
|
14
|
+
* Returns empty sequence in the corner case where both nodes are the same and
|
|
15
|
+
* at least one is excluded (i.e. considers that [X,X[ and ]X,X] are empty).
|
|
16
|
+
*
|
|
17
|
+
* Complexity: the size of the subtree anchored at the lowest common ancestor.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
export function getNodesBetween(node1, node2, includeOptions = { includeFirst: false, includeSecond: false }, treeOptions = Node.fullTree) {
|
|
22
|
+
let between = getNodesInclusivelyBetween(node1, node2, treeOptions);
|
|
23
|
+
// If somehow there is nothing between them, escape now
|
|
24
|
+
if (between.isEmpty()) {
|
|
25
|
+
return between;
|
|
26
|
+
}
|
|
27
|
+
// Do we keep the first node or skip its subtree?
|
|
28
|
+
if (!includeOptions.includeFirst) {
|
|
29
|
+
// By previous test, between is not empty
|
|
30
|
+
const first = between.first().getUnsafe();
|
|
31
|
+
// The 'first node after the subtree rooted at first' is the next sibling
|
|
32
|
+
// of the closest ancestor having one.
|
|
33
|
+
between = first
|
|
34
|
+
// Closest ancestor with a next sibling.
|
|
35
|
+
.closest((ancestor) => ancestor.next(treeOptions).isSome(), treeOptions)
|
|
36
|
+
// Get that sibling.
|
|
37
|
+
.flatMap((node) => node.next(treeOptions))
|
|
38
|
+
// Skip everything until next.
|
|
39
|
+
.map((next) => between.skipUntil((node) => node.equals(next)))
|
|
40
|
+
// If nothing after the subtree at first, just escape.
|
|
41
|
+
.getOrElse(Sequence.empty);
|
|
42
|
+
}
|
|
43
|
+
// Do we keep the second node or remove it?
|
|
44
|
+
between =
|
|
45
|
+
includeOptions.includeSecond || between.isEmpty()
|
|
46
|
+
? between
|
|
47
|
+
: between.skipLast(1);
|
|
48
|
+
return between;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get all nodes between node1 and node2, included.
|
|
52
|
+
*/
|
|
53
|
+
function getNodesInclusivelyBetween(node1, node2, treeOptions) {
|
|
54
|
+
const isFrontier = or(equals(node1), equals(node2));
|
|
55
|
+
return lowestCommonAncestor(node1, node2, treeOptions)
|
|
56
|
+
.map((context) => context
|
|
57
|
+
.inclusiveDescendants(treeOptions)
|
|
58
|
+
.skipUntil(isFrontier)
|
|
59
|
+
.skipLastUntil(isFrontier))
|
|
60
|
+
.getOrElse(Sequence.empty);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=get-nodes-between.js.map
|