@siteimprove/alfa-dom 0.95.0 → 0.96.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/node/attribute/autocomplete.d.ts +23 -0
- package/dist/node/attribute/autocomplete.js +111 -0
- package/dist/node/attribute.d.ts +2 -0
- package/dist/node/attribute.js +2 -0
- package/dist/node/element/augment.d.ts +4 -0
- package/dist/node/element/augment.js +14 -2
- package/dist/node/element/predicate/is-suggested-focusable.js +2 -12
- package/package.json +28 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @siteimprove/alfa-dom
|
|
2
2
|
|
|
3
|
+
## 0.96.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **Added:** An `Element<"summary">#isSummaryForItsParentDetails` predicate is now available. ([#1728](https://github.com/Siteimprove/alfa/pull/1728))
|
|
8
|
+
|
|
9
|
+
- **Added:** An `Attribute.Autocomplete` namespace is now available, grouping functionalities around the `autocomplete` attribute. ([#1724](https://github.com/Siteimprove/alfa/pull/1724))
|
|
10
|
+
|
|
3
11
|
## 0.95.0
|
|
4
12
|
|
|
5
13
|
## 0.94.1
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Predicate } from "@siteimprove/alfa-predicate";
|
|
2
|
+
import { Array } from "@siteimprove/alfa-array";
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare namespace Autocomplete {
|
|
7
|
+
/**
|
|
8
|
+
* Autofill detail tokens from steps 2-4 of the list in {@link https://html.spec.whatwg.org/multipage/#autofill-detail-tokens}.
|
|
9
|
+
*/
|
|
10
|
+
namespace AutofillDetailTokens {
|
|
11
|
+
const unmodifiables: string[];
|
|
12
|
+
const modifiables: string[];
|
|
13
|
+
const modifiers: string[];
|
|
14
|
+
const addressTypes: string[];
|
|
15
|
+
const webauthn = "webauthn";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Checks if the provided string contains a valid autocomplete string according to {@link https://html.spec.whatwg.org/multipage/#autofill-detail-tokens}
|
|
19
|
+
*/
|
|
20
|
+
const isValid: Predicate<string>;
|
|
21
|
+
function tokenize(autocomplete: string): Array<string>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=autocomplete.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Predicate } from "@siteimprove/alfa-predicate";
|
|
2
|
+
import { Parser } from "@siteimprove/alfa-parser";
|
|
3
|
+
import { Slice } from "@siteimprove/alfa-slice";
|
|
4
|
+
import { Array } from "@siteimprove/alfa-array";
|
|
5
|
+
import { Err, Ok } from "@siteimprove/alfa-result";
|
|
6
|
+
const { either, end, option, right, parseIf } = Parser;
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export var Autocomplete;
|
|
11
|
+
(function (Autocomplete) {
|
|
12
|
+
/**
|
|
13
|
+
* Autofill detail tokens from steps 2-4 of the list in {@link https://html.spec.whatwg.org/multipage/#autofill-detail-tokens}.
|
|
14
|
+
*/
|
|
15
|
+
let AutofillDetailTokens;
|
|
16
|
+
(function (AutofillDetailTokens) {
|
|
17
|
+
AutofillDetailTokens.unmodifiables = [
|
|
18
|
+
"name",
|
|
19
|
+
"honorific-prefix",
|
|
20
|
+
"given-name",
|
|
21
|
+
"additional-name",
|
|
22
|
+
"family-name",
|
|
23
|
+
"honorific-suffix",
|
|
24
|
+
"nickname",
|
|
25
|
+
"username",
|
|
26
|
+
"new-password",
|
|
27
|
+
"current-password",
|
|
28
|
+
"one-time-code",
|
|
29
|
+
"organization-title",
|
|
30
|
+
"organization",
|
|
31
|
+
"street-address",
|
|
32
|
+
"address-line1",
|
|
33
|
+
"address-line2",
|
|
34
|
+
"address-line3",
|
|
35
|
+
"address-level4",
|
|
36
|
+
"address-level3",
|
|
37
|
+
"address-level2",
|
|
38
|
+
"address-level1",
|
|
39
|
+
"country",
|
|
40
|
+
"country-name",
|
|
41
|
+
"postal-code",
|
|
42
|
+
"cc-name",
|
|
43
|
+
"cc-given-name",
|
|
44
|
+
"cc-additional-name",
|
|
45
|
+
"cc-family-name",
|
|
46
|
+
"cc-number",
|
|
47
|
+
"cc-exp",
|
|
48
|
+
"cc-exp-month",
|
|
49
|
+
"cc-exp-year",
|
|
50
|
+
"cc-csc",
|
|
51
|
+
"cc-type",
|
|
52
|
+
"transaction-currency",
|
|
53
|
+
"transaction-amount",
|
|
54
|
+
"language",
|
|
55
|
+
"bday",
|
|
56
|
+
"bday-day",
|
|
57
|
+
"bday-month",
|
|
58
|
+
"bday-year",
|
|
59
|
+
"sex",
|
|
60
|
+
"url",
|
|
61
|
+
"photo",
|
|
62
|
+
];
|
|
63
|
+
AutofillDetailTokens.modifiables = [
|
|
64
|
+
"tel",
|
|
65
|
+
"tel-country-code",
|
|
66
|
+
"tel-national",
|
|
67
|
+
"tel-area-code",
|
|
68
|
+
"tel-local",
|
|
69
|
+
"tel-local-prefix",
|
|
70
|
+
"tel-local-suffix",
|
|
71
|
+
"tel-extension",
|
|
72
|
+
"email",
|
|
73
|
+
"impp",
|
|
74
|
+
];
|
|
75
|
+
AutofillDetailTokens.modifiers = ["home", "work", "mobile", "fax", "pager"];
|
|
76
|
+
AutofillDetailTokens.addressTypes = ["shipping", "billing"];
|
|
77
|
+
AutofillDetailTokens.webauthn = "webauthn";
|
|
78
|
+
})(AutofillDetailTokens = Autocomplete.AutofillDetailTokens || (Autocomplete.AutofillDetailTokens = {}));
|
|
79
|
+
/**
|
|
80
|
+
* Checks if the provided string contains a valid autocomplete string according to {@link https://html.spec.whatwg.org/multipage/#autofill-detail-tokens}
|
|
81
|
+
*/
|
|
82
|
+
Autocomplete.isValid = (autocomplete) => {
|
|
83
|
+
// The following line comments each refers to the corresponding position in the HTML specification linked above at the time of writing
|
|
84
|
+
const parse = right(option(section), // 1.
|
|
85
|
+
right(option(addressType), // 2.
|
|
86
|
+
right(
|
|
87
|
+
// 3.
|
|
88
|
+
either(unmodifiable, // 3.a
|
|
89
|
+
right(option(modifier) /*3.b.1*/, modifiable /*3.b.2*/)), right(option(webauthn), // 4.
|
|
90
|
+
end((token) => `Expected EOF, but got ${token}`)))));
|
|
91
|
+
return parse(Slice.of(tokenize(autocomplete))).isOk();
|
|
92
|
+
};
|
|
93
|
+
function tokenize(autocomplete) {
|
|
94
|
+
return Array.from(autocomplete.toLowerCase().trim().split(/\s+/));
|
|
95
|
+
}
|
|
96
|
+
Autocomplete.tokenize = tokenize;
|
|
97
|
+
const parseFirst = (input) => input
|
|
98
|
+
.first()
|
|
99
|
+
.map((token) => Ok.of([input.rest(), token]))
|
|
100
|
+
.getOr(Err.of("No token left"));
|
|
101
|
+
function parserOf(tokens) {
|
|
102
|
+
return parseIf((token) => tokens.includes(token), parseFirst, (token) => `Expected valid token, but got ${token}`);
|
|
103
|
+
}
|
|
104
|
+
const addressType = parserOf(AutofillDetailTokens.addressTypes);
|
|
105
|
+
const unmodifiable = parserOf(AutofillDetailTokens.unmodifiables);
|
|
106
|
+
const section = parseIf((token) => token.startsWith("section-"), parseFirst, (token) => `Expected token beginning with \`section-\`, but got ${token}`);
|
|
107
|
+
const modifiable = parserOf(AutofillDetailTokens.modifiables);
|
|
108
|
+
const modifier = parserOf(AutofillDetailTokens.modifiers);
|
|
109
|
+
const webauthn = parserOf([AutofillDetailTokens.webauthn]);
|
|
110
|
+
})(Autocomplete || (Autocomplete = {}));
|
|
111
|
+
//# sourceMappingURL=autocomplete.js.map
|
package/dist/node/attribute.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { Namespace } from "../namespace.js";
|
|
|
6
6
|
import { Node } from "../node.js";
|
|
7
7
|
import type { Element } from "./element.js";
|
|
8
8
|
import * as predicate from "./attribute/predicate.js";
|
|
9
|
+
import * as autocomplete from "./attribute/autocomplete.js";
|
|
9
10
|
/**
|
|
10
11
|
* @public
|
|
11
12
|
*/
|
|
@@ -86,5 +87,6 @@ export declare namespace Attribute {
|
|
|
86
87
|
*/
|
|
87
88
|
function foldCase<N extends string = string>(name: N, owner: Option<Element>): N | Lowercase<N>;
|
|
88
89
|
const hasName: typeof predicate.hasName;
|
|
90
|
+
export import Autocomplete = autocomplete.Autocomplete;
|
|
89
91
|
}
|
|
90
92
|
//# sourceMappingURL=attribute.d.ts.map
|
package/dist/node/attribute.js
CHANGED
|
@@ -7,6 +7,7 @@ import * as json from "@siteimprove/alfa-json";
|
|
|
7
7
|
import { Namespace } from "../namespace.js";
|
|
8
8
|
import { Node } from "../node.js";
|
|
9
9
|
import * as predicate from "./attribute/predicate.js";
|
|
10
|
+
import * as autocomplete from "./attribute/autocomplete.js";
|
|
10
11
|
const { isEmpty } = Iterable;
|
|
11
12
|
const { equals, not } = Predicate;
|
|
12
13
|
/**
|
|
@@ -160,5 +161,6 @@ export class Attribute extends Node {
|
|
|
160
161
|
}
|
|
161
162
|
Attribute.foldCase = foldCase;
|
|
162
163
|
Attribute.hasName = predicate.hasName;
|
|
164
|
+
Attribute.Autocomplete = autocomplete.Autocomplete;
|
|
163
165
|
})(Attribute || (Attribute = {}));
|
|
164
166
|
//# sourceMappingURL=attribute.js.map
|
|
@@ -21,6 +21,10 @@ declare module "../element.js" {
|
|
|
21
21
|
* {@link https://html.spec.whatwg.org/multipage/form-elements.html#concept-select-option-list}
|
|
22
22
|
*/
|
|
23
23
|
optionsList(this: Element<"select">): Sequence<Element<"option">>;
|
|
24
|
+
/**
|
|
25
|
+
* {@link https://html.spec.whatwg.org/multipage/#summary-for-its-parent-details}
|
|
26
|
+
*/
|
|
27
|
+
isSummaryForItsParentDetails(this: Element<"summary">): boolean;
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
//# sourceMappingURL=augment.d.ts.map
|
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
* {@link https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
|
|
7
7
|
*/
|
|
8
8
|
import { None, Some } from "@siteimprove/alfa-option";
|
|
9
|
+
import { Refinement } from "@siteimprove/alfa-refinement";
|
|
9
10
|
import { Sequence } from "@siteimprove/alfa-sequence";
|
|
10
11
|
import { Element } from "../element.js";
|
|
12
|
+
const { isElement } = Element;
|
|
13
|
+
const { and } = Refinement;
|
|
11
14
|
Element.prototype.inputType = function () {
|
|
12
15
|
if (this._inputType === undefined) {
|
|
13
16
|
this._inputType = this.attribute("type")
|
|
@@ -33,7 +36,7 @@ Element.prototype.displaySize = function () {
|
|
|
33
36
|
Element.prototype.optionsList = function () {
|
|
34
37
|
if (this._optionsList === undefined) {
|
|
35
38
|
this._optionsList = this.children()
|
|
36
|
-
.filter(
|
|
39
|
+
.filter(isElement)
|
|
37
40
|
.flatMap((child) => {
|
|
38
41
|
switch (child.name) {
|
|
39
42
|
case "option":
|
|
@@ -41,7 +44,7 @@ Element.prototype.optionsList = function () {
|
|
|
41
44
|
case "optgroup":
|
|
42
45
|
return child
|
|
43
46
|
.children()
|
|
44
|
-
.filter(
|
|
47
|
+
.filter(isElement)
|
|
45
48
|
.filter(
|
|
46
49
|
// We cannot really use `Element.hasName` here as it would
|
|
47
50
|
// create a circular dependency.
|
|
@@ -53,4 +56,13 @@ Element.prototype.optionsList = function () {
|
|
|
53
56
|
}
|
|
54
57
|
return this._optionsList;
|
|
55
58
|
};
|
|
59
|
+
Element.prototype.isSummaryForItsParentDetails = function () {
|
|
60
|
+
// We cannot use `Element.hasName` here as it would create a circular dependency.
|
|
61
|
+
return this.parent()
|
|
62
|
+
.filter(and(Element.isElement, (parent) => parent.name === "details"))
|
|
63
|
+
.some((details) => details
|
|
64
|
+
.children()
|
|
65
|
+
.find(and(Element.isElement, (candidate) => candidate.name === "summary"))
|
|
66
|
+
.includes(this));
|
|
67
|
+
};
|
|
56
68
|
//# sourceMappingURL=augment.js.map
|
|
@@ -28,18 +28,8 @@ export function isSuggestedFocusable(element) {
|
|
|
28
28
|
case "textarea":
|
|
29
29
|
return true;
|
|
30
30
|
case "summary":
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.filter(Element.isElement)
|
|
34
|
-
.some((parent) => parent.name === "details" &&
|
|
35
|
-
// Checking that element is the first <summary> child of parent.
|
|
36
|
-
parent
|
|
37
|
-
.children()
|
|
38
|
-
.filter(Element.isElement)
|
|
39
|
-
// Switching on element.name does not narrow the type, so we must
|
|
40
|
-
// keep it as Element<string>.
|
|
41
|
-
.find(Element.hasName("summary"))
|
|
42
|
-
.includes(element));
|
|
31
|
+
// The type is ensured by the switch on the name.
|
|
32
|
+
return element.isSummaryForItsParentDetails();
|
|
43
33
|
}
|
|
44
34
|
return (Element.isEditingHost(element) ||
|
|
45
35
|
Element.isBrowsingContextContainer(element));
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json.schemastore.org/package",
|
|
3
3
|
"name": "@siteimprove/alfa-dom",
|
|
4
4
|
"homepage": "https://alfa.siteimprove.com",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.96.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"description": "Implementations of the core DOM and CSSOM node types",
|
|
8
8
|
"repository": {
|
|
@@ -35,32 +35,35 @@
|
|
|
35
35
|
"dist/**/*.d.ts"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@siteimprove/alfa-array": "^0.
|
|
39
|
-
"@siteimprove/alfa-cache": "^0.
|
|
40
|
-
"@siteimprove/alfa-comparable": "^0.
|
|
41
|
-
"@siteimprove/alfa-css": "^0.
|
|
42
|
-
"@siteimprove/alfa-css-feature": "^0.
|
|
43
|
-
"@siteimprove/alfa-device": "^0.
|
|
44
|
-
"@siteimprove/alfa-earl": "^0.
|
|
45
|
-
"@siteimprove/alfa-equatable": "^0.
|
|
46
|
-
"@siteimprove/alfa-flags": "^0.
|
|
47
|
-
"@siteimprove/alfa-iterable": "^0.
|
|
48
|
-
"@siteimprove/alfa-json": "^0.
|
|
49
|
-
"@siteimprove/alfa-lazy": "^0.
|
|
50
|
-
"@siteimprove/alfa-map": "^0.
|
|
51
|
-
"@siteimprove/alfa-option": "^0.
|
|
52
|
-
"@siteimprove/alfa-
|
|
53
|
-
"@siteimprove/alfa-
|
|
54
|
-
"@siteimprove/alfa-
|
|
55
|
-
"@siteimprove/alfa-
|
|
56
|
-
"@siteimprove/alfa-
|
|
57
|
-
"@siteimprove/alfa-
|
|
58
|
-
"@siteimprove/alfa-
|
|
59
|
-
"@siteimprove/alfa-
|
|
60
|
-
"@siteimprove/alfa-
|
|
38
|
+
"@siteimprove/alfa-array": "^0.96.0",
|
|
39
|
+
"@siteimprove/alfa-cache": "^0.96.0",
|
|
40
|
+
"@siteimprove/alfa-comparable": "^0.96.0",
|
|
41
|
+
"@siteimprove/alfa-css": "^0.96.0",
|
|
42
|
+
"@siteimprove/alfa-css-feature": "^0.96.0",
|
|
43
|
+
"@siteimprove/alfa-device": "^0.96.0",
|
|
44
|
+
"@siteimprove/alfa-earl": "^0.96.0",
|
|
45
|
+
"@siteimprove/alfa-equatable": "^0.96.0",
|
|
46
|
+
"@siteimprove/alfa-flags": "^0.96.0",
|
|
47
|
+
"@siteimprove/alfa-iterable": "^0.96.0",
|
|
48
|
+
"@siteimprove/alfa-json": "^0.96.0",
|
|
49
|
+
"@siteimprove/alfa-lazy": "^0.96.0",
|
|
50
|
+
"@siteimprove/alfa-map": "^0.96.0",
|
|
51
|
+
"@siteimprove/alfa-option": "^0.96.0",
|
|
52
|
+
"@siteimprove/alfa-parser": "^0.96.0",
|
|
53
|
+
"@siteimprove/alfa-predicate": "^0.96.0",
|
|
54
|
+
"@siteimprove/alfa-rectangle": "^0.96.0",
|
|
55
|
+
"@siteimprove/alfa-refinement": "^0.96.0",
|
|
56
|
+
"@siteimprove/alfa-result": "^0.96.0",
|
|
57
|
+
"@siteimprove/alfa-sarif": "^0.96.0",
|
|
58
|
+
"@siteimprove/alfa-selective": "^0.96.0",
|
|
59
|
+
"@siteimprove/alfa-sequence": "^0.96.0",
|
|
60
|
+
"@siteimprove/alfa-slice": "^0.96.0",
|
|
61
|
+
"@siteimprove/alfa-string": "^0.96.0",
|
|
62
|
+
"@siteimprove/alfa-trampoline": "^0.96.0",
|
|
63
|
+
"@siteimprove/alfa-tree": "^0.96.0"
|
|
61
64
|
},
|
|
62
65
|
"devDependencies": {
|
|
63
|
-
"@siteimprove/alfa-test": "^0.
|
|
66
|
+
"@siteimprove/alfa-test": "^0.96.0",
|
|
64
67
|
"@types/jsdom": "^21.1.6",
|
|
65
68
|
"jsdom": "^25.0.0"
|
|
66
69
|
},
|