html-validate 8.10.0 → 8.11.1
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 +205 -19
- 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 +205 -20
- 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/es/core-browser.js
CHANGED
package/dist/es/core-nodejs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { a as ConfigError, b as ConfigLoader, C as Config,
|
|
3
|
+
import { a as ConfigError, b as ConfigLoader, C as Config, I as compatibilityCheckImpl, v as version } from './core.js';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import kleur from 'kleur';
|
|
6
6
|
|
package/dist/es/core.js
CHANGED
|
@@ -584,8 +584,13 @@ const patternProperties = {
|
|
|
584
584
|
implicitRole: {
|
|
585
585
|
title: "Implicit ARIA role for this element",
|
|
586
586
|
description: "Some elements have implicit ARIA roles.",
|
|
587
|
+
deprecated: true,
|
|
587
588
|
"function": true
|
|
588
589
|
},
|
|
590
|
+
aria: {
|
|
591
|
+
title: "WAI-ARIA properties for this element",
|
|
592
|
+
$ref: "#/definitions/Aria"
|
|
593
|
+
},
|
|
589
594
|
scriptSupporting: {
|
|
590
595
|
title: "Mark element as script-supporting",
|
|
591
596
|
description: "Script-supporting elements are elements which can be inserted where othersise not permitted to assist in templating",
|
|
@@ -682,6 +687,39 @@ const patternProperties = {
|
|
|
682
687
|
}
|
|
683
688
|
};
|
|
684
689
|
const definitions = {
|
|
690
|
+
Aria: {
|
|
691
|
+
type: "object",
|
|
692
|
+
additionalProperties: false,
|
|
693
|
+
properties: {
|
|
694
|
+
implicitRole: {
|
|
695
|
+
title: "Implicit ARIA role for this element",
|
|
696
|
+
description: "Some elements have implicit ARIA roles.",
|
|
697
|
+
anyOf: [
|
|
698
|
+
{
|
|
699
|
+
type: "string"
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
"function": true
|
|
703
|
+
}
|
|
704
|
+
]
|
|
705
|
+
},
|
|
706
|
+
naming: {
|
|
707
|
+
title: "Prohibit or allow this element to be named by aria-label or aria-labelledby",
|
|
708
|
+
anyOf: [
|
|
709
|
+
{
|
|
710
|
+
type: "string",
|
|
711
|
+
"enum": [
|
|
712
|
+
"prohibited",
|
|
713
|
+
"allowed"
|
|
714
|
+
]
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"function": true
|
|
718
|
+
}
|
|
719
|
+
]
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
},
|
|
685
723
|
contentCategory: {
|
|
686
724
|
anyOf: [
|
|
687
725
|
{
|
|
@@ -982,6 +1020,7 @@ const MetaCopyableProperty = [
|
|
|
982
1020
|
"formAssociated",
|
|
983
1021
|
"labelable",
|
|
984
1022
|
"attributes",
|
|
1023
|
+
"aria",
|
|
985
1024
|
"permittedContent",
|
|
986
1025
|
"permittedDescendants",
|
|
987
1026
|
"permittedOrder",
|
|
@@ -1042,7 +1081,27 @@ function migrateAttributes(src) {
|
|
|
1042
1081
|
});
|
|
1043
1082
|
return Object.fromEntries(entries);
|
|
1044
1083
|
}
|
|
1084
|
+
function normalizeAriaImplicitRole(value) {
|
|
1085
|
+
if (!value) {
|
|
1086
|
+
return () => null;
|
|
1087
|
+
}
|
|
1088
|
+
if (typeof value === "string") {
|
|
1089
|
+
return () => value;
|
|
1090
|
+
}
|
|
1091
|
+
return value;
|
|
1092
|
+
}
|
|
1093
|
+
function normalizeAriaNaming(value) {
|
|
1094
|
+
if (!value) {
|
|
1095
|
+
return () => "allowed";
|
|
1096
|
+
}
|
|
1097
|
+
if (typeof value === "string") {
|
|
1098
|
+
return () => value;
|
|
1099
|
+
}
|
|
1100
|
+
return value;
|
|
1101
|
+
}
|
|
1045
1102
|
function migrateElement(src) {
|
|
1103
|
+
var _a, _b;
|
|
1104
|
+
const implicitRole = normalizeAriaImplicitRole(src.implicitRole ?? ((_a = src.aria) == null ? void 0 : _a.implicitRole));
|
|
1046
1105
|
const result = {
|
|
1047
1106
|
...src,
|
|
1048
1107
|
...{
|
|
@@ -1051,7 +1110,11 @@ function migrateElement(src) {
|
|
|
1051
1110
|
attributes: migrateAttributes(src),
|
|
1052
1111
|
textContent: src.textContent,
|
|
1053
1112
|
focusable: src.focusable ?? false,
|
|
1054
|
-
implicitRole
|
|
1113
|
+
implicitRole,
|
|
1114
|
+
aria: {
|
|
1115
|
+
implicitRole,
|
|
1116
|
+
naming: normalizeAriaNaming((_b = src.aria) == null ? void 0 : _b.naming)
|
|
1117
|
+
}
|
|
1055
1118
|
};
|
|
1056
1119
|
delete result.deprecatedAttributes;
|
|
1057
1120
|
delete result.requiredAttributes;
|
|
@@ -1890,11 +1953,82 @@ function factory$1(name, context) {
|
|
|
1890
1953
|
}
|
|
1891
1954
|
}
|
|
1892
1955
|
|
|
1956
|
+
const escapedCodepoints = ["9", "a", "d"];
|
|
1957
|
+
function* splitSelectorElements(selector) {
|
|
1958
|
+
let begin = 0;
|
|
1959
|
+
let end = 0;
|
|
1960
|
+
function initialState(ch, p) {
|
|
1961
|
+
if (ch === "\\") {
|
|
1962
|
+
return 1 /* ESCAPED */;
|
|
1963
|
+
}
|
|
1964
|
+
if (ch === " ") {
|
|
1965
|
+
end = p;
|
|
1966
|
+
return 2 /* WHITESPACE */;
|
|
1967
|
+
}
|
|
1968
|
+
return 0 /* INITIAL */;
|
|
1969
|
+
}
|
|
1970
|
+
function escapedState(ch) {
|
|
1971
|
+
if (escapedCodepoints.includes(ch)) {
|
|
1972
|
+
return 1 /* ESCAPED */;
|
|
1973
|
+
}
|
|
1974
|
+
return 0 /* INITIAL */;
|
|
1975
|
+
}
|
|
1976
|
+
function* whitespaceState(ch, p) {
|
|
1977
|
+
if (ch === " ") {
|
|
1978
|
+
return 2 /* WHITESPACE */;
|
|
1979
|
+
}
|
|
1980
|
+
yield selector.slice(begin, end);
|
|
1981
|
+
begin = p;
|
|
1982
|
+
end = p;
|
|
1983
|
+
return 0 /* INITIAL */;
|
|
1984
|
+
}
|
|
1985
|
+
let state = 0 /* INITIAL */;
|
|
1986
|
+
for (let p = 0; p < selector.length; p++) {
|
|
1987
|
+
const ch = selector[p];
|
|
1988
|
+
switch (state) {
|
|
1989
|
+
case 0 /* INITIAL */:
|
|
1990
|
+
state = initialState(ch, p);
|
|
1991
|
+
break;
|
|
1992
|
+
case 1 /* ESCAPED */:
|
|
1993
|
+
state = escapedState(ch);
|
|
1994
|
+
break;
|
|
1995
|
+
case 2 /* WHITESPACE */:
|
|
1996
|
+
state = yield* whitespaceState(ch, p);
|
|
1997
|
+
break;
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
if (begin !== selector.length) {
|
|
2001
|
+
yield selector.slice(begin);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
|
|
1893
2005
|
function stripslashes(value) {
|
|
1894
2006
|
return value.replace(/\\(.)/g, "$1");
|
|
1895
2007
|
}
|
|
2008
|
+
function unescapeCodepoint(value) {
|
|
2009
|
+
const replacement = {
|
|
2010
|
+
"\\9 ": " ",
|
|
2011
|
+
"\\a ": "\n",
|
|
2012
|
+
"\\d ": "\r"
|
|
2013
|
+
};
|
|
2014
|
+
return value.replace(
|
|
2015
|
+
/(\\[\u0039\u0061\u0064] )/g,
|
|
2016
|
+
(_, codepoint) => replacement[codepoint]
|
|
2017
|
+
);
|
|
2018
|
+
}
|
|
1896
2019
|
function escapeSelectorComponent(text) {
|
|
1897
|
-
|
|
2020
|
+
const codepoints = {
|
|
2021
|
+
" ": "\\9 ",
|
|
2022
|
+
"\n": "\\a ",
|
|
2023
|
+
"\r": "\\d "
|
|
2024
|
+
};
|
|
2025
|
+
return text.toString().replace(/([\t\n\r]|[^a-z0-9_-])/gi, (_, ch) => {
|
|
2026
|
+
if (codepoints[ch]) {
|
|
2027
|
+
return codepoints[ch];
|
|
2028
|
+
} else {
|
|
2029
|
+
return `\\${ch}`;
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
1898
2032
|
}
|
|
1899
2033
|
function generateIdSelector(id) {
|
|
1900
2034
|
const escaped = escapeSelectorComponent(id);
|
|
@@ -2009,7 +2143,10 @@ class PseudoClassMatcher extends Matcher {
|
|
|
2009
2143
|
}
|
|
2010
2144
|
class Pattern {
|
|
2011
2145
|
constructor(pattern) {
|
|
2012
|
-
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(
|
|
2146
|
+
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)([^]*)$/);
|
|
2147
|
+
if (!match) {
|
|
2148
|
+
throw new Error(`Failed to create selector pattern from "${pattern}"`);
|
|
2149
|
+
}
|
|
2013
2150
|
match.shift();
|
|
2014
2151
|
this.selector = pattern;
|
|
2015
2152
|
this.combinator = parseCombinator(match.shift(), pattern);
|
|
@@ -2064,13 +2201,8 @@ class Selector {
|
|
|
2064
2201
|
}
|
|
2065
2202
|
static parse(selector) {
|
|
2066
2203
|
selector = selector.replace(/([+~>]) /g, "$1");
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
return Array.from(selector.matchAll(delimiter), (match) => {
|
|
2070
|
-
const end = match.index + 1;
|
|
2071
|
-
const part = selector.slice(begin, end);
|
|
2072
|
-
begin = end + 1;
|
|
2073
|
-
return new Pattern(part);
|
|
2204
|
+
return Array.from(splitSelectorElements(selector), (element) => {
|
|
2205
|
+
return new Pattern(unescapeCodepoint(element));
|
|
2074
2206
|
});
|
|
2075
2207
|
}
|
|
2076
2208
|
static findCandidates(root, pattern) {
|
|
@@ -2401,7 +2533,8 @@ class HtmlElement extends DOMNode {
|
|
|
2401
2533
|
return this.cacheSet(ROLE, role.value);
|
|
2402
2534
|
}
|
|
2403
2535
|
if (this.metaElement) {
|
|
2404
|
-
const
|
|
2536
|
+
const { aria } = this.metaElement;
|
|
2537
|
+
const implicitRole = aria.implicitRole(this._adapter);
|
|
2405
2538
|
return this.cacheSet(ROLE, implicitRole);
|
|
2406
2539
|
}
|
|
2407
2540
|
return this.cacheSet(ROLE, null);
|
|
@@ -3143,6 +3276,48 @@ function interpolate(text, data) {
|
|
|
3143
3276
|
});
|
|
3144
3277
|
}
|
|
3145
3278
|
|
|
3279
|
+
const cacheKey = Symbol("aria-naming");
|
|
3280
|
+
const defaultValue = "allowed";
|
|
3281
|
+
const prohibitedRoles = [
|
|
3282
|
+
"caption",
|
|
3283
|
+
"code",
|
|
3284
|
+
"deletion",
|
|
3285
|
+
"emphasis",
|
|
3286
|
+
"generic",
|
|
3287
|
+
"insertion",
|
|
3288
|
+
"paragraph",
|
|
3289
|
+
"presentation",
|
|
3290
|
+
"strong",
|
|
3291
|
+
"subscript",
|
|
3292
|
+
"superscript"
|
|
3293
|
+
];
|
|
3294
|
+
function byRole(role) {
|
|
3295
|
+
return prohibitedRoles.includes(role) ? "prohibited" : "allowed";
|
|
3296
|
+
}
|
|
3297
|
+
function byMeta(element, meta) {
|
|
3298
|
+
return meta.aria.naming(element._adapter);
|
|
3299
|
+
}
|
|
3300
|
+
function ariaNaming(element) {
|
|
3301
|
+
var _a;
|
|
3302
|
+
const cached = element.cacheGet(cacheKey);
|
|
3303
|
+
if (cached) {
|
|
3304
|
+
return cached;
|
|
3305
|
+
}
|
|
3306
|
+
const role = (_a = element.getAttribute("role")) == null ? void 0 : _a.value;
|
|
3307
|
+
if (role) {
|
|
3308
|
+
if (role instanceof DynamicValue) {
|
|
3309
|
+
return element.cacheSet(cacheKey, defaultValue);
|
|
3310
|
+
} else {
|
|
3311
|
+
return element.cacheSet(cacheKey, byRole(role));
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
const meta = element.meta;
|
|
3315
|
+
if (!meta) {
|
|
3316
|
+
return element.cacheSet(cacheKey, defaultValue);
|
|
3317
|
+
}
|
|
3318
|
+
return element.cacheSet(cacheKey, byMeta(element, meta));
|
|
3319
|
+
}
|
|
3320
|
+
|
|
3146
3321
|
const patternCache = /* @__PURE__ */ new Map();
|
|
3147
3322
|
function compileStringPattern(pattern) {
|
|
3148
3323
|
const regexp = pattern.replace(/[*]+/g, ".+");
|
|
@@ -3661,7 +3836,7 @@ class Rule {
|
|
|
3661
3836
|
}
|
|
3662
3837
|
}
|
|
3663
3838
|
|
|
3664
|
-
const defaults$
|
|
3839
|
+
const defaults$v = {
|
|
3665
3840
|
allowExternal: true,
|
|
3666
3841
|
allowRelative: true,
|
|
3667
3842
|
allowAbsolute: true,
|
|
@@ -3702,7 +3877,7 @@ function matchList(value, list) {
|
|
|
3702
3877
|
}
|
|
3703
3878
|
class AllowedLinks extends Rule {
|
|
3704
3879
|
constructor(options) {
|
|
3705
|
-
super({ ...defaults$
|
|
3880
|
+
super({ ...defaults$v, ...options });
|
|
3706
3881
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3707
3882
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3708
3883
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3866,7 +4041,7 @@ class AllowedLinks extends Rule {
|
|
|
3866
4041
|
}
|
|
3867
4042
|
}
|
|
3868
4043
|
|
|
3869
|
-
const defaults$
|
|
4044
|
+
const defaults$u = {
|
|
3870
4045
|
accessible: true
|
|
3871
4046
|
};
|
|
3872
4047
|
function findByTarget(target, siblings) {
|
|
@@ -3896,7 +4071,7 @@ function getDescription$1(context) {
|
|
|
3896
4071
|
}
|
|
3897
4072
|
class AreaAlt extends Rule {
|
|
3898
4073
|
constructor(options) {
|
|
3899
|
-
super({ ...defaults$
|
|
4074
|
+
super({ ...defaults$u, ...options });
|
|
3900
4075
|
}
|
|
3901
4076
|
static schema() {
|
|
3902
4077
|
return {
|
|
@@ -3975,6 +4150,9 @@ class AriaHiddenBody extends Rule {
|
|
|
3975
4150
|
}
|
|
3976
4151
|
}
|
|
3977
4152
|
|
|
4153
|
+
const defaults$t = {
|
|
4154
|
+
allowAnyNamable: false
|
|
4155
|
+
};
|
|
3978
4156
|
const whitelisted = [
|
|
3979
4157
|
"main",
|
|
3980
4158
|
"nav",
|
|
@@ -4013,6 +4191,9 @@ function isValidUsage(target, meta) {
|
|
|
4013
4191
|
return false;
|
|
4014
4192
|
}
|
|
4015
4193
|
class AriaLabelMisuse extends Rule {
|
|
4194
|
+
constructor(options) {
|
|
4195
|
+
super({ ...defaults$t, ...options });
|
|
4196
|
+
}
|
|
4016
4197
|
documentation() {
|
|
4017
4198
|
const valid = [
|
|
4018
4199
|
"Interactive elements",
|
|
@@ -4055,6 +4236,9 @@ ${lines}`,
|
|
|
4055
4236
|
if (isValidUsage(target, meta)) {
|
|
4056
4237
|
return;
|
|
4057
4238
|
}
|
|
4239
|
+
if (this.options.allowAnyNamable && ariaNaming(target) === "allowed") {
|
|
4240
|
+
return;
|
|
4241
|
+
}
|
|
4058
4242
|
this.report(target, `"aria-label" cannot be used on this element`, attr.keyLocation);
|
|
4059
4243
|
}
|
|
4060
4244
|
}
|
|
@@ -7552,7 +7736,7 @@ class NoRedundantRole extends Rule {
|
|
|
7552
7736
|
if (!meta) {
|
|
7553
7737
|
return;
|
|
7554
7738
|
}
|
|
7555
|
-
const implicitRole = meta.implicitRole(target._adapter);
|
|
7739
|
+
const implicitRole = meta.aria.implicitRole(target._adapter);
|
|
7556
7740
|
if (!implicitRole) {
|
|
7557
7741
|
return;
|
|
7558
7742
|
}
|
|
@@ -9334,7 +9518,7 @@ const config$4 = {
|
|
|
9334
9518
|
rules: {
|
|
9335
9519
|
"area-alt": ["error", { accessible: true }],
|
|
9336
9520
|
"aria-hidden-body": "error",
|
|
9337
|
-
"aria-label-misuse": "error",
|
|
9521
|
+
"aria-label-misuse": ["error", { allowAnyNamable: false }],
|
|
9338
9522
|
"deprecated-rule": "warn",
|
|
9339
9523
|
"empty-heading": "error",
|
|
9340
9524
|
"empty-title": "error",
|
|
@@ -9386,7 +9570,7 @@ const config$1 = {
|
|
|
9386
9570
|
rules: {
|
|
9387
9571
|
"area-alt": ["error", { accessible: true }],
|
|
9388
9572
|
"aria-hidden-body": "error",
|
|
9389
|
-
"aria-label-misuse": "error",
|
|
9573
|
+
"aria-label-misuse": ["error", { allowAnyNamable: false }],
|
|
9390
9574
|
"attr-case": "error",
|
|
9391
9575
|
"attr-delimiter": "error",
|
|
9392
9576
|
"attr-quotes": "error",
|
|
@@ -9467,6 +9651,7 @@ var recommended = config$1;
|
|
|
9467
9651
|
const config = {
|
|
9468
9652
|
rules: {
|
|
9469
9653
|
"area-alt": ["error", { accessible: false }],
|
|
9654
|
+
"aria-label-misuse": ["error", { allowAnyNamable: true }],
|
|
9470
9655
|
"attr-spacing": "error",
|
|
9471
9656
|
"attribute-allowed-values": "error",
|
|
9472
9657
|
"attribute-misuse": "error",
|
|
@@ -11719,7 +11904,7 @@ class HtmlValidate {
|
|
|
11719
11904
|
}
|
|
11720
11905
|
|
|
11721
11906
|
const name = "html-validate";
|
|
11722
|
-
const version = "8.
|
|
11907
|
+
const version = "8.11.1";
|
|
11723
11908
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11724
11909
|
|
|
11725
11910
|
function definePlugin(plugin) {
|
|
@@ -12596,5 +12781,5 @@ function compatibilityCheckImpl(name, declared, options) {
|
|
|
12596
12781
|
return false;
|
|
12597
12782
|
}
|
|
12598
12783
|
|
|
12599
|
-
export { Attribute as A,
|
|
12784
|
+
export { Attribute as A, definePlugin as B, Config as C, DOMNode as D, Parser as E, ruleExists as F, EventHandler as G, HtmlValidate as H, compatibilityCheckImpl as I, codeframe as J, name as K, bugs as L, MetaCopyableProperty as M, NodeClosed as N, Presets as P, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, ConfigError as a, ConfigLoader as b, defineConfig as c, deepmerge$1 as d, ensureError as e, StaticConfigLoader as f, getFormatter as g, DOMTokenList as h, ignore$1 as i, DOMTree as j, DynamicValue as k, HtmlElement as l, NodeType as m, NestedError as n, SchemaValidationError as o, MetaTable as p, TextContent$1 as q, Rule as r, staticResolver as s, ariaNaming as t, TextClassification as u, version as v, classifyNodeText as w, keywordPatternMatcher as x, sliceLocation as y, Reporter as z };
|
|
12600
12785
|
//# sourceMappingURL=core.js.map
|