axe-core 4.11.4 → 4.12.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.
@@ -0,0 +1,219 @@
1
+ (() => {
2
+ var elementInternalsMap = (() => {
3
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports);
4
+
5
+ // lib/gather-internals/main.js
6
+ var require_main = __commonJS((exports, module) => {
7
+ walkTree();
8
+ module.exports = elementInternalsMap;
9
+ });
10
+
11
+ // lib/core/utils/is-valid-custom-element-name.js
12
+ var reservedNames = [
13
+ "annotation-xml",
14
+ "color-profile",
15
+ "font-face",
16
+ "font-face-src",
17
+ "font-face-uri",
18
+ "font-face-format",
19
+ "font-face-name",
20
+ "missing-glyph"
21
+ ];
22
+ var validLocalNameRegex = /^(?:[A-Za-z][^\0\t\n\f\r\u0020/>]*|[:_\u0080-\u{10FFFF}][A-Za-z0-9-.:_\u0080-\u{10FFFF}]*)$/u;
23
+ var alphaLowerRegex = /[a-z]/;
24
+ var alphaUpperRegex = /[A-Z]/;
25
+ function isValidCustomElementName(nodeName) {
26
+ return !reservedNames.includes(nodeName) && validLocalNameRegex.test(nodeName) && alphaLowerRegex.test(nodeName[0]) && !alphaUpperRegex.test(nodeName) && nodeName.includes("-");
27
+ }
28
+
29
+ // lib/core/utils/get-element-internals.js
30
+ var propNames = ["_internals", "internals", "internals_"];
31
+ var symbolNames = ["internals", "privateInternals"];
32
+ function getElementInternals(node) {
33
+ if (!isValidCustomElementName(node.nodeName.toLowerCase())) {
34
+ return;
35
+ }
36
+ const mapInternals = globalThis._elementInternals?.get(node);
37
+ if (mapInternals) {
38
+ return mapInternals;
39
+ }
40
+ if (!("ElementInternals" in window)) {
41
+ return;
42
+ }
43
+ for (const propName of propNames) {
44
+ if (Object.getOwnPropertyDescriptor(node, propName)?.get) {
45
+ continue;
46
+ }
47
+ if (node[propName] instanceof window.ElementInternals) {
48
+ return node[propName];
49
+ }
50
+ }
51
+ const ownSymbols = Object.getOwnPropertySymbols(node);
52
+ if (!ownSymbols.length) {
53
+ return;
54
+ }
55
+ for (const symbolName of symbolNames) {
56
+ const symbol = ownSymbols.find((s) => s.description === symbolName);
57
+ if (symbol) {
58
+ if (Object.getOwnPropertyDescriptor(node, symbol)?.get) {
59
+ continue;
60
+ }
61
+ if (node[symbol] instanceof window.ElementInternals) {
62
+ return node[symbol];
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ // lib/core/utils/escape-selector.js
69
+ function escapeSelector(value) {
70
+ const string = String(value);
71
+ const length = string.length;
72
+ let index = -1;
73
+ let codeUnit;
74
+ let result = "";
75
+ const firstCodeUnit = string.charCodeAt(0);
76
+ while (++index < length) {
77
+ codeUnit = string.charCodeAt(index);
78
+ if (codeUnit == 0) {
79
+ result += "\uFFFD";
80
+ continue;
81
+ }
82
+ if (codeUnit >= 1 && codeUnit <= 31 || codeUnit == 127 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) {
83
+ result += "\\" + codeUnit.toString(16) + " ";
84
+ continue;
85
+ }
86
+ if (index == 0 && length == 1 && codeUnit == 45) {
87
+ result += "\\" + string.charAt(index);
88
+ continue;
89
+ }
90
+ if (codeUnit >= 128 || codeUnit == 45 || codeUnit == 95 || codeUnit >= 48 && codeUnit <= 57 || codeUnit >= 65 && codeUnit <= 90 || codeUnit >= 97 && codeUnit <= 122) {
91
+ result += string.charAt(index);
92
+ continue;
93
+ }
94
+ result += "\\" + string.charAt(index);
95
+ }
96
+ return result;
97
+ }
98
+ var escape_selector_default = escapeSelector;
99
+
100
+ // lib/core/utils/get-shadow-selector.js
101
+ function getShadowSelector(generateSelector, elm, options = {}) {
102
+ if (!elm) {
103
+ return "";
104
+ }
105
+ let doc = elm.getRootNode && elm.getRootNode() || document;
106
+ if (doc.nodeType !== 11) {
107
+ return generateSelector(elm, options, doc);
108
+ }
109
+ const stack = [];
110
+ while (doc.nodeType === 11) {
111
+ if (!doc.host) {
112
+ return "";
113
+ }
114
+ stack.unshift({elm, doc});
115
+ elm = doc.host;
116
+ doc = elm.getRootNode();
117
+ }
118
+ stack.unshift({elm, doc});
119
+ return stack.map((item) => generateSelector(item.elm, options, item.doc));
120
+ }
121
+
122
+ // lib/core/utils/get-ancestry.js
123
+ function generateAncestry(node) {
124
+ const nodeName = escape_selector_default(node.nodeName.toLowerCase());
125
+ const parentElement = node.parentElement;
126
+ const parentNode = node.parentNode;
127
+ let nthChild = "";
128
+ if (nodeName !== "head" && nodeName !== "body" && parentNode?.children.length > 1) {
129
+ const index = Array.prototype.indexOf.call(parentNode.children, node) + 1;
130
+ nthChild = `:nth-child(${index})`;
131
+ }
132
+ if (!parentElement) {
133
+ return nodeName + nthChild;
134
+ }
135
+ return generateAncestry(parentElement) + " > " + nodeName + nthChild;
136
+ }
137
+ function getAncestry(elm, options) {
138
+ return getShadowSelector(generateAncestry, elm, options);
139
+ }
140
+
141
+ // lib/core/utils/is-shadow-root.js
142
+ var possibleShadowRoots = [
143
+ "article",
144
+ "aside",
145
+ "blockquote",
146
+ "body",
147
+ "div",
148
+ "footer",
149
+ "h1",
150
+ "h2",
151
+ "h3",
152
+ "h4",
153
+ "h5",
154
+ "h6",
155
+ "header",
156
+ "main",
157
+ "nav",
158
+ "p",
159
+ "section",
160
+ "span"
161
+ ];
162
+ function isShadowRoot(node) {
163
+ if (node.shadowRoot) {
164
+ const nodeName = node.nodeName.toLowerCase();
165
+ if (possibleShadowRoots.includes(nodeName) || isValidCustomElementName(nodeName)) {
166
+ return true;
167
+ }
168
+ }
169
+ return false;
170
+ }
171
+ var is_shadow_root_default = isShadowRoot;
172
+
173
+ // lib/gather-internals/walk-tree.js
174
+ var elementInternalsMap = [];
175
+ var ariaPropRegex = /^aria[A-Z]/;
176
+ var propsToCapture = ["role", "labels", "form"];
177
+ function walkTree(tree = document.body) {
178
+ const treeWalker = document.createTreeWalker(tree, globalThis.NodeFilter.SHOW_ELEMENT, null, false);
179
+ let node = treeWalker.currentNode;
180
+ while (node) {
181
+ const elementInternals = getElementInternals(node);
182
+ if (elementInternals) {
183
+ const ancestry = getAncestry(node);
184
+ const internals = {};
185
+ for (const prop in elementInternals) {
186
+ if (!ariaPropRegex.test(prop) && !propsToCapture.includes(prop)) {
187
+ continue;
188
+ }
189
+ try {
190
+ const value = elementInternals[prop];
191
+ if (value === null) {
192
+ continue;
193
+ }
194
+ if (value instanceof globalThis.HTMLElement) {
195
+ internals[prop] = value.isConnected ? {type: "HTMLElement", value: getAncestry(value)} : void 0;
196
+ } else if (Array.isArray(value) || value instanceof globalThis.NodeList) {
197
+ const array = Array.from(value).filter((n) => n.isConnected);
198
+ internals[prop] = array.length ? {type: "NodeList", value: array.map((n) => getAncestry(n))} : void 0;
199
+ } else if (typeof value === "string") {
200
+ internals[prop] = value;
201
+ }
202
+ } catch {
203
+ }
204
+ }
205
+ elementInternalsMap.push({
206
+ ancestry,
207
+ internals
208
+ });
209
+ }
210
+ if (is_shadow_root_default(node)) {
211
+ walkTree(node.shadowRoot);
212
+ }
213
+ node = treeWalker.nextNode();
214
+ }
215
+ }
216
+ return require_main();
217
+ })();
218
+ return elementInternalsMap;
219
+ })();
@@ -81,6 +81,10 @@
81
81
  "description": "Ensure all elements with a role attribute use a valid value",
82
82
  "help": "ARIA roles used must conform to valid values"
83
83
  },
84
+ "aria-tab-name": {
85
+ "description": "Ensure every ARIA tab node has an accessible name",
86
+ "help": "ARIA tab nodes must have an accessible name"
87
+ },
84
88
  "aria-text": {
85
89
  "description": "Ensure role=\"text\" is used on elements with no focusable descendants",
86
90
  "help": "\"role=text\" should have no focusable descendants"
@@ -460,6 +464,7 @@
460
464
  "pass": "ARIA attribute is allowed",
461
465
  "fail": {
462
466
  "checkbox": "Remove aria-checked, or set it to \"${data.checkState}\" to match the real checkbox state",
467
+ "radio": "Remove aria-checked, or set it to \"${data.checkState}\" to match the real radio state",
463
468
  "rowSingular": "This attribute is supported with treegrid rows, but not ${data.ownerRole}: ${data.invalidAttrs}",
464
469
  "rowPlural": "These attributes are supported with treegrid rows, but not ${data.ownerRole}: ${data.invalidAttrs}"
465
470
  }
package/locales/ja.json CHANGED
@@ -453,6 +453,7 @@
453
453
  "pass": "ARIA 属性が許可されています",
454
454
  "fail": {
455
455
  "checkbox": "aria-checkedを削除するか\"${data.checkState}\"を設定して、チェックボックスの実際の状態と合うようにしましょう",
456
+ "radio": "aria-checkedを削除するか\"${data.checkState}\"を設定して、ラジオボタンの実際の状態と合うようにしましょう",
456
457
  "rowSingular": "treegridの行でサポートされている属性ですが、${data.ownerRole}: ${data.invalidAttrs}の場合はこの限りではありません",
457
458
  "rowPlural": "treegridの行でサポートされている属性ですが、${data.ownerRole}: ${data.invalidAttrs}の場合はこの限りではありません"
458
459
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "lang": "nb-no",
2
+ "lang": "nb",
3
3
  "rules": {
4
4
  "accesskeys": {
5
5
  "description": "",
@@ -1,5 +1,5 @@
1
1
  {
2
- "lang": "pt_BR",
2
+ "lang": "pt-BR",
3
3
  "rules": {
4
4
  "accesskeys": {
5
5
  "description": "Certifique-se de que cada valor do atributo 'acesskey' é único",
@@ -1,5 +1,5 @@
1
1
  {
2
- "lang": "pt_PT",
2
+ "lang": "pt-PT",
3
3
  "rules": {
4
4
  "accesskeys": {
5
5
  "description": "Garantir que cada valor do atributo 'accesskey' seja único",
@@ -1,5 +1,5 @@
1
1
  {
2
- "lang": "zh_CN",
2
+ "lang": "zh-CN",
3
3
  "rules": {
4
4
  "accesskeys": {
5
5
  "description": "确保每个 accesskey 属性值都是唯一的",
@@ -1,5 +1,5 @@
1
1
  {
2
- "lang": "zh_TW",
2
+ "lang": "zh-TW",
3
3
  "rules": {
4
4
  "accesskeys": {
5
5
  "description": "確保每個 accesskey 屬性值都是唯一的",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "axe-core",
3
3
  "description": "Accessibility engine for automated Web UI testing",
4
- "version": "4.11.4",
4
+ "version": "4.12.0",
5
5
  "license": "MPL-2.0",
6
6
  "engines": {
7
7
  "node": ">=4"
@@ -61,7 +61,8 @@
61
61
  "axe.d.ts",
62
62
  "sri-history.json",
63
63
  "locales/",
64
- "LICENSE-3RD-PARTY.txt"
64
+ "LICENSE-3RD-PARTY.txt",
65
+ "gather-internals.js"
65
66
  ],
66
67
  "standard-version": {
67
68
  "scripts": {
@@ -90,6 +91,7 @@
90
91
  "test:unit:api": "npm run test:unit -- testDirs=api",
91
92
  "test:unit:integration": "npm run test:unit -- testDirs=integration",
92
93
  "test:unit:virtual-rules": "npm run test:unit -- testDirs=virtual-rules",
94
+ "test:unit:gather-internals": "npm run test:unit -- testDirs=gather-internals",
93
95
  "integration": "node test/integration/full/test-webdriver.js",
94
96
  "integration:apg": "mocha --fail-zero test/aria-practices/*.spec.js",
95
97
  "integration:chrome": "npm run integration -- browser=Chrome",
@@ -110,6 +112,7 @@
110
112
  "rule-gen": "node build/rule-generator",
111
113
  "sri-update": "grunt build && node build/sri-update && git add sri-history.json",
112
114
  "sri-validate": "node build/sri-update --validate",
115
+ "codemod:modernize-tests": "node build/codemods/modernize-test-files.mjs",
113
116
  "fmt": "prettier --write .",
114
117
  "fmt:check": "prettier --check .",
115
118
  "prepare": "husky && npm run patch",
@@ -124,7 +127,7 @@
124
127
  "@babel/preset-env": "^7.20.2",
125
128
  "@babel/runtime-corejs3": "^7.20.7",
126
129
  "@deque/dot": "^1.1.5",
127
- "@types/node": "^4.9.5",
130
+ "@types/node": "^25.6.0",
128
131
  "aria-practices": "github:w3c/aria-practices#ce0336bd82d7d3651abcbde86af644197ddbc629",
129
132
  "aria-query": "^5.1.3",
130
133
  "chai": "^4.3.7",
@@ -158,7 +161,7 @@
158
161
  "inquirer": "^8.2.5",
159
162
  "jquery": "^4.0.0",
160
163
  "jsdoc": "^4.0.2",
161
- "jsdom": "^28.1.0",
164
+ "jsdom": "^29.0.2",
162
165
  "karma": "^6.4.1",
163
166
  "karma-chai": "^0.1.0",
164
167
  "karma-chrome-launcher": "^3.1.1",
@@ -173,17 +176,19 @@
173
176
  "node-notifier": "^10.0.1",
174
177
  "npm-run-all": "^4.1.5",
175
178
  "outdent": "^0.8.0",
179
+ "parse5": "^8.0.0",
176
180
  "patch-package": "^8.0.0",
177
181
  "prettier": "^3.0.3",
182
+ "recast": "^0.23.11",
178
183
  "revalidator": "^0.3.1",
179
184
  "selenium-webdriver": "^4.7.1",
180
185
  "serve-handler": "^6.1.5",
181
186
  "sinon": "^21.0.0",
182
187
  "sri-toolbox": "^0.2.0",
183
188
  "standard-version": "^9.5.0",
184
- "start-server-and-test": "^2.0.1",
189
+ "start-server-and-test": "^3.0.2",
185
190
  "typedarray": "^0.0.7",
186
- "typescript": "^5.2.2",
191
+ "typescript": "^6.0.3",
187
192
  "uglify-js": "^3.17.4",
188
193
  "wcag-act-rules": "github:w3c/wcag-act-rules#5adb55d19eb2cd7fb23213b2d1acedf9004dc063",
189
194
  "weakmap-polyfill": "^2.0.4"
package/sri-history.json CHANGED
@@ -414,5 +414,9 @@
414
414
  "4.11.4": {
415
415
  "axe.js": "sha256-MFYbxYKg+pR6osY47p1hwmvMOb7f5kMTHtPU7APqp/A=",
416
416
  "axe.min.js": "sha256-+4OkN42Xjst9La5Io6N3ioTJcaxpLzr9RdcU+6icDw0="
417
+ },
418
+ "4.12.0": {
419
+ "axe.js": "sha256-oNBNtCwIenGwI5OepWKyxcy5/OyV+O6pYjPmYhZrVvU=",
420
+ "axe.min.js": "sha256-oK/ECKvsvgb/dnUDPn6ixARmGBYhZ6qkzhAwsQlj3s4="
417
421
  }
418
422
  }