html-validate 8.10.0 → 8.11.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/dist/cjs/browser.js +1 -0
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/core.js +156 -14
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +496 -235
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/es/browser.js +1 -1
- package/dist/es/cli.js +1 -1
- package/dist/es/core-browser.js +1 -1
- package/dist/es/core-nodejs.js +1 -1
- package/dist/es/core.js +156 -15
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +496 -235
- package/dist/es/elements.js.map +1 -1
- package/dist/es/html-validate.js +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/matchers-jestonly.js +1 -1
- package/dist/schema/elements.json +22 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +78 -1
- package/dist/types/index.d.ts +78 -1
- package/package.json +8 -6
package/dist/cjs/browser.js
CHANGED
|
@@ -45,6 +45,7 @@ exports.TextNode = core.TextNode;
|
|
|
45
45
|
exports.UserError = core.UserError;
|
|
46
46
|
exports.Validator = core.Validator;
|
|
47
47
|
exports.WrappedError = core.WrappedError;
|
|
48
|
+
exports.ariaNaming = core.ariaNaming;
|
|
48
49
|
exports.classifyNodeText = core.classifyNodeText;
|
|
49
50
|
exports.configPresets = core.Presets;
|
|
50
51
|
exports.defineConfig = core.defineConfig;
|
package/dist/cjs/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/cjs/core.js
CHANGED
|
@@ -594,8 +594,13 @@ const patternProperties = {
|
|
|
594
594
|
implicitRole: {
|
|
595
595
|
title: "Implicit ARIA role for this element",
|
|
596
596
|
description: "Some elements have implicit ARIA roles.",
|
|
597
|
+
deprecated: true,
|
|
597
598
|
"function": true
|
|
598
599
|
},
|
|
600
|
+
aria: {
|
|
601
|
+
title: "WAI-ARIA properties for this element",
|
|
602
|
+
$ref: "#/definitions/Aria"
|
|
603
|
+
},
|
|
599
604
|
scriptSupporting: {
|
|
600
605
|
title: "Mark element as script-supporting",
|
|
601
606
|
description: "Script-supporting elements are elements which can be inserted where othersise not permitted to assist in templating",
|
|
@@ -692,6 +697,39 @@ const patternProperties = {
|
|
|
692
697
|
}
|
|
693
698
|
};
|
|
694
699
|
const definitions = {
|
|
700
|
+
Aria: {
|
|
701
|
+
type: "object",
|
|
702
|
+
additionalProperties: false,
|
|
703
|
+
properties: {
|
|
704
|
+
implicitRole: {
|
|
705
|
+
title: "Implicit ARIA role for this element",
|
|
706
|
+
description: "Some elements have implicit ARIA roles.",
|
|
707
|
+
anyOf: [
|
|
708
|
+
{
|
|
709
|
+
type: "string"
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
"function": true
|
|
713
|
+
}
|
|
714
|
+
]
|
|
715
|
+
},
|
|
716
|
+
naming: {
|
|
717
|
+
title: "Prohibit or allow this element to be named by aria-label or aria-labelledby",
|
|
718
|
+
anyOf: [
|
|
719
|
+
{
|
|
720
|
+
type: "string",
|
|
721
|
+
"enum": [
|
|
722
|
+
"prohibited",
|
|
723
|
+
"allowed"
|
|
724
|
+
]
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
"function": true
|
|
728
|
+
}
|
|
729
|
+
]
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
},
|
|
695
733
|
contentCategory: {
|
|
696
734
|
anyOf: [
|
|
697
735
|
{
|
|
@@ -992,6 +1030,7 @@ const MetaCopyableProperty = [
|
|
|
992
1030
|
"formAssociated",
|
|
993
1031
|
"labelable",
|
|
994
1032
|
"attributes",
|
|
1033
|
+
"aria",
|
|
995
1034
|
"permittedContent",
|
|
996
1035
|
"permittedDescendants",
|
|
997
1036
|
"permittedOrder",
|
|
@@ -1052,7 +1091,27 @@ function migrateAttributes(src) {
|
|
|
1052
1091
|
});
|
|
1053
1092
|
return Object.fromEntries(entries);
|
|
1054
1093
|
}
|
|
1094
|
+
function normalizeAriaImplicitRole(value) {
|
|
1095
|
+
if (!value) {
|
|
1096
|
+
return () => null;
|
|
1097
|
+
}
|
|
1098
|
+
if (typeof value === "string") {
|
|
1099
|
+
return () => value;
|
|
1100
|
+
}
|
|
1101
|
+
return value;
|
|
1102
|
+
}
|
|
1103
|
+
function normalizeAriaNaming(value) {
|
|
1104
|
+
if (!value) {
|
|
1105
|
+
return () => "allowed";
|
|
1106
|
+
}
|
|
1107
|
+
if (typeof value === "string") {
|
|
1108
|
+
return () => value;
|
|
1109
|
+
}
|
|
1110
|
+
return value;
|
|
1111
|
+
}
|
|
1055
1112
|
function migrateElement(src) {
|
|
1113
|
+
var _a, _b;
|
|
1114
|
+
const implicitRole = normalizeAriaImplicitRole(src.implicitRole ?? ((_a = src.aria) == null ? void 0 : _a.implicitRole));
|
|
1056
1115
|
const result = {
|
|
1057
1116
|
...src,
|
|
1058
1117
|
...{
|
|
@@ -1061,7 +1120,11 @@ function migrateElement(src) {
|
|
|
1061
1120
|
attributes: migrateAttributes(src),
|
|
1062
1121
|
textContent: src.textContent,
|
|
1063
1122
|
focusable: src.focusable ?? false,
|
|
1064
|
-
implicitRole
|
|
1123
|
+
implicitRole,
|
|
1124
|
+
aria: {
|
|
1125
|
+
implicitRole,
|
|
1126
|
+
naming: normalizeAriaNaming((_b = src.aria) == null ? void 0 : _b.naming)
|
|
1127
|
+
}
|
|
1065
1128
|
};
|
|
1066
1129
|
delete result.deprecatedAttributes;
|
|
1067
1130
|
delete result.requiredAttributes;
|
|
@@ -1903,8 +1966,30 @@ function factory$1(name, context) {
|
|
|
1903
1966
|
function stripslashes(value) {
|
|
1904
1967
|
return value.replace(/\\(.)/g, "$1");
|
|
1905
1968
|
}
|
|
1969
|
+
function unescapeCodepoint(value) {
|
|
1970
|
+
const replacement = {
|
|
1971
|
+
"\\9 ": " ",
|
|
1972
|
+
"\\a ": "\n",
|
|
1973
|
+
"\\d ": "\r"
|
|
1974
|
+
};
|
|
1975
|
+
return value.replace(
|
|
1976
|
+
/(\\[\u0039\u0061\u0064] )/g,
|
|
1977
|
+
(_, codepoint) => replacement[codepoint]
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1906
1980
|
function escapeSelectorComponent(text) {
|
|
1907
|
-
|
|
1981
|
+
const codepoints = {
|
|
1982
|
+
" ": "\\9 ",
|
|
1983
|
+
"\n": "\\a ",
|
|
1984
|
+
"\r": "\\d "
|
|
1985
|
+
};
|
|
1986
|
+
return text.toString().replace(/([\t\n\r]|[^a-z0-9_-])/gi, (_, ch) => {
|
|
1987
|
+
if (codepoints[ch]) {
|
|
1988
|
+
return codepoints[ch];
|
|
1989
|
+
} else {
|
|
1990
|
+
return `\\${ch}`;
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1908
1993
|
}
|
|
1909
1994
|
function generateIdSelector(id) {
|
|
1910
1995
|
const escaped = escapeSelectorComponent(id);
|
|
@@ -2019,7 +2104,10 @@ class PseudoClassMatcher extends Matcher {
|
|
|
2019
2104
|
}
|
|
2020
2105
|
class Pattern {
|
|
2021
2106
|
constructor(pattern) {
|
|
2022
|
-
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(
|
|
2107
|
+
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)([^]*)$/);
|
|
2108
|
+
if (!match) {
|
|
2109
|
+
throw new Error(`Failed to create selector pattern from "${pattern}"`);
|
|
2110
|
+
}
|
|
2023
2111
|
match.shift();
|
|
2024
2112
|
this.selector = pattern;
|
|
2025
2113
|
this.combinator = parseCombinator(match.shift(), pattern);
|
|
@@ -2075,10 +2163,10 @@ class Selector {
|
|
|
2075
2163
|
static parse(selector) {
|
|
2076
2164
|
selector = selector.replace(/([+~>]) /g, "$1");
|
|
2077
2165
|
let begin = 0;
|
|
2078
|
-
const delimiter = /((?:[
|
|
2166
|
+
const delimiter = /((?:[^\\\u0039\u0061\u0064]) +|$)/g;
|
|
2079
2167
|
return Array.from(selector.matchAll(delimiter), (match) => {
|
|
2080
2168
|
const end = match.index + 1;
|
|
2081
|
-
const part = selector.slice(begin, end);
|
|
2169
|
+
const part = unescapeCodepoint(selector.slice(begin, end));
|
|
2082
2170
|
begin = end + 1;
|
|
2083
2171
|
return new Pattern(part);
|
|
2084
2172
|
});
|
|
@@ -2411,7 +2499,8 @@ class HtmlElement extends DOMNode {
|
|
|
2411
2499
|
return this.cacheSet(ROLE, role.value);
|
|
2412
2500
|
}
|
|
2413
2501
|
if (this.metaElement) {
|
|
2414
|
-
const
|
|
2502
|
+
const { aria } = this.metaElement;
|
|
2503
|
+
const implicitRole = aria.implicitRole(this._adapter);
|
|
2415
2504
|
return this.cacheSet(ROLE, implicitRole);
|
|
2416
2505
|
}
|
|
2417
2506
|
return this.cacheSet(ROLE, null);
|
|
@@ -3153,6 +3242,48 @@ function interpolate(text, data) {
|
|
|
3153
3242
|
});
|
|
3154
3243
|
}
|
|
3155
3244
|
|
|
3245
|
+
const cacheKey = Symbol("aria-naming");
|
|
3246
|
+
const defaultValue = "allowed";
|
|
3247
|
+
const prohibitedRoles = [
|
|
3248
|
+
"caption",
|
|
3249
|
+
"code",
|
|
3250
|
+
"deletion",
|
|
3251
|
+
"emphasis",
|
|
3252
|
+
"generic",
|
|
3253
|
+
"insertion",
|
|
3254
|
+
"paragraph",
|
|
3255
|
+
"presentation",
|
|
3256
|
+
"strong",
|
|
3257
|
+
"subscript",
|
|
3258
|
+
"superscript"
|
|
3259
|
+
];
|
|
3260
|
+
function byRole(role) {
|
|
3261
|
+
return prohibitedRoles.includes(role) ? "prohibited" : "allowed";
|
|
3262
|
+
}
|
|
3263
|
+
function byMeta(element, meta) {
|
|
3264
|
+
return meta.aria.naming(element._adapter);
|
|
3265
|
+
}
|
|
3266
|
+
function ariaNaming(element) {
|
|
3267
|
+
var _a;
|
|
3268
|
+
const cached = element.cacheGet(cacheKey);
|
|
3269
|
+
if (cached) {
|
|
3270
|
+
return cached;
|
|
3271
|
+
}
|
|
3272
|
+
const role = (_a = element.getAttribute("role")) == null ? void 0 : _a.value;
|
|
3273
|
+
if (role) {
|
|
3274
|
+
if (role instanceof DynamicValue) {
|
|
3275
|
+
return element.cacheSet(cacheKey, defaultValue);
|
|
3276
|
+
} else {
|
|
3277
|
+
return element.cacheSet(cacheKey, byRole(role));
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
const meta = element.meta;
|
|
3281
|
+
if (!meta) {
|
|
3282
|
+
return element.cacheSet(cacheKey, defaultValue);
|
|
3283
|
+
}
|
|
3284
|
+
return element.cacheSet(cacheKey, byMeta(element, meta));
|
|
3285
|
+
}
|
|
3286
|
+
|
|
3156
3287
|
const patternCache = /* @__PURE__ */ new Map();
|
|
3157
3288
|
function compileStringPattern(pattern) {
|
|
3158
3289
|
const regexp = pattern.replace(/[*]+/g, ".+");
|
|
@@ -3671,7 +3802,7 @@ class Rule {
|
|
|
3671
3802
|
}
|
|
3672
3803
|
}
|
|
3673
3804
|
|
|
3674
|
-
const defaults$
|
|
3805
|
+
const defaults$v = {
|
|
3675
3806
|
allowExternal: true,
|
|
3676
3807
|
allowRelative: true,
|
|
3677
3808
|
allowAbsolute: true,
|
|
@@ -3712,7 +3843,7 @@ function matchList(value, list) {
|
|
|
3712
3843
|
}
|
|
3713
3844
|
class AllowedLinks extends Rule {
|
|
3714
3845
|
constructor(options) {
|
|
3715
|
-
super({ ...defaults$
|
|
3846
|
+
super({ ...defaults$v, ...options });
|
|
3716
3847
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3717
3848
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3718
3849
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3876,7 +4007,7 @@ class AllowedLinks extends Rule {
|
|
|
3876
4007
|
}
|
|
3877
4008
|
}
|
|
3878
4009
|
|
|
3879
|
-
const defaults$
|
|
4010
|
+
const defaults$u = {
|
|
3880
4011
|
accessible: true
|
|
3881
4012
|
};
|
|
3882
4013
|
function findByTarget(target, siblings) {
|
|
@@ -3906,7 +4037,7 @@ function getDescription$1(context) {
|
|
|
3906
4037
|
}
|
|
3907
4038
|
class AreaAlt extends Rule {
|
|
3908
4039
|
constructor(options) {
|
|
3909
|
-
super({ ...defaults$
|
|
4040
|
+
super({ ...defaults$u, ...options });
|
|
3910
4041
|
}
|
|
3911
4042
|
static schema() {
|
|
3912
4043
|
return {
|
|
@@ -3985,6 +4116,9 @@ class AriaHiddenBody extends Rule {
|
|
|
3985
4116
|
}
|
|
3986
4117
|
}
|
|
3987
4118
|
|
|
4119
|
+
const defaults$t = {
|
|
4120
|
+
allowAnyNamable: false
|
|
4121
|
+
};
|
|
3988
4122
|
const whitelisted = [
|
|
3989
4123
|
"main",
|
|
3990
4124
|
"nav",
|
|
@@ -4023,6 +4157,9 @@ function isValidUsage(target, meta) {
|
|
|
4023
4157
|
return false;
|
|
4024
4158
|
}
|
|
4025
4159
|
class AriaLabelMisuse extends Rule {
|
|
4160
|
+
constructor(options) {
|
|
4161
|
+
super({ ...defaults$t, ...options });
|
|
4162
|
+
}
|
|
4026
4163
|
documentation() {
|
|
4027
4164
|
const valid = [
|
|
4028
4165
|
"Interactive elements",
|
|
@@ -4065,6 +4202,9 @@ ${lines}`,
|
|
|
4065
4202
|
if (isValidUsage(target, meta)) {
|
|
4066
4203
|
return;
|
|
4067
4204
|
}
|
|
4205
|
+
if (this.options.allowAnyNamable && ariaNaming(target) === "allowed") {
|
|
4206
|
+
return;
|
|
4207
|
+
}
|
|
4068
4208
|
this.report(target, `"aria-label" cannot be used on this element`, attr.keyLocation);
|
|
4069
4209
|
}
|
|
4070
4210
|
}
|
|
@@ -7562,7 +7702,7 @@ class NoRedundantRole extends Rule {
|
|
|
7562
7702
|
if (!meta) {
|
|
7563
7703
|
return;
|
|
7564
7704
|
}
|
|
7565
|
-
const implicitRole = meta.implicitRole(target._adapter);
|
|
7705
|
+
const implicitRole = meta.aria.implicitRole(target._adapter);
|
|
7566
7706
|
if (!implicitRole) {
|
|
7567
7707
|
return;
|
|
7568
7708
|
}
|
|
@@ -9344,7 +9484,7 @@ const config$4 = {
|
|
|
9344
9484
|
rules: {
|
|
9345
9485
|
"area-alt": ["error", { accessible: true }],
|
|
9346
9486
|
"aria-hidden-body": "error",
|
|
9347
|
-
"aria-label-misuse": "error",
|
|
9487
|
+
"aria-label-misuse": ["error", { allowAnyNamable: false }],
|
|
9348
9488
|
"deprecated-rule": "warn",
|
|
9349
9489
|
"empty-heading": "error",
|
|
9350
9490
|
"empty-title": "error",
|
|
@@ -9396,7 +9536,7 @@ const config$1 = {
|
|
|
9396
9536
|
rules: {
|
|
9397
9537
|
"area-alt": ["error", { accessible: true }],
|
|
9398
9538
|
"aria-hidden-body": "error",
|
|
9399
|
-
"aria-label-misuse": "error",
|
|
9539
|
+
"aria-label-misuse": ["error", { allowAnyNamable: false }],
|
|
9400
9540
|
"attr-case": "error",
|
|
9401
9541
|
"attr-delimiter": "error",
|
|
9402
9542
|
"attr-quotes": "error",
|
|
@@ -9477,6 +9617,7 @@ var recommended = config$1;
|
|
|
9477
9617
|
const config = {
|
|
9478
9618
|
rules: {
|
|
9479
9619
|
"area-alt": ["error", { accessible: false }],
|
|
9620
|
+
"aria-label-misuse": ["error", { allowAnyNamable: true }],
|
|
9480
9621
|
"attr-spacing": "error",
|
|
9481
9622
|
"attribute-allowed-values": "error",
|
|
9482
9623
|
"attribute-misuse": "error",
|
|
@@ -11729,7 +11870,7 @@ class HtmlValidate {
|
|
|
11729
11870
|
}
|
|
11730
11871
|
|
|
11731
11872
|
const name = "html-validate";
|
|
11732
|
-
const version = "8.
|
|
11873
|
+
const version = "8.11.0";
|
|
11733
11874
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11734
11875
|
|
|
11735
11876
|
function definePlugin(plugin) {
|
|
@@ -12636,6 +12777,7 @@ exports.TextNode = TextNode;
|
|
|
12636
12777
|
exports.UserError = UserError;
|
|
12637
12778
|
exports.Validator = Validator;
|
|
12638
12779
|
exports.WrappedError = WrappedError;
|
|
12780
|
+
exports.ariaNaming = ariaNaming;
|
|
12639
12781
|
exports.bugs = bugs;
|
|
12640
12782
|
exports.classifyNodeText = classifyNodeText;
|
|
12641
12783
|
exports.codeframe = codeframe;
|