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/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;
|
|
@@ -1893,8 +1956,30 @@ function factory$1(name, context) {
|
|
|
1893
1956
|
function stripslashes(value) {
|
|
1894
1957
|
return value.replace(/\\(.)/g, "$1");
|
|
1895
1958
|
}
|
|
1959
|
+
function unescapeCodepoint(value) {
|
|
1960
|
+
const replacement = {
|
|
1961
|
+
"\\9 ": " ",
|
|
1962
|
+
"\\a ": "\n",
|
|
1963
|
+
"\\d ": "\r"
|
|
1964
|
+
};
|
|
1965
|
+
return value.replace(
|
|
1966
|
+
/(\\[\u0039\u0061\u0064] )/g,
|
|
1967
|
+
(_, codepoint) => replacement[codepoint]
|
|
1968
|
+
);
|
|
1969
|
+
}
|
|
1896
1970
|
function escapeSelectorComponent(text) {
|
|
1897
|
-
|
|
1971
|
+
const codepoints = {
|
|
1972
|
+
" ": "\\9 ",
|
|
1973
|
+
"\n": "\\a ",
|
|
1974
|
+
"\r": "\\d "
|
|
1975
|
+
};
|
|
1976
|
+
return text.toString().replace(/([\t\n\r]|[^a-z0-9_-])/gi, (_, ch) => {
|
|
1977
|
+
if (codepoints[ch]) {
|
|
1978
|
+
return codepoints[ch];
|
|
1979
|
+
} else {
|
|
1980
|
+
return `\\${ch}`;
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1898
1983
|
}
|
|
1899
1984
|
function generateIdSelector(id) {
|
|
1900
1985
|
const escaped = escapeSelectorComponent(id);
|
|
@@ -2009,7 +2094,10 @@ class PseudoClassMatcher extends Matcher {
|
|
|
2009
2094
|
}
|
|
2010
2095
|
class Pattern {
|
|
2011
2096
|
constructor(pattern) {
|
|
2012
|
-
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(
|
|
2097
|
+
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)([^]*)$/);
|
|
2098
|
+
if (!match) {
|
|
2099
|
+
throw new Error(`Failed to create selector pattern from "${pattern}"`);
|
|
2100
|
+
}
|
|
2013
2101
|
match.shift();
|
|
2014
2102
|
this.selector = pattern;
|
|
2015
2103
|
this.combinator = parseCombinator(match.shift(), pattern);
|
|
@@ -2065,10 +2153,10 @@ class Selector {
|
|
|
2065
2153
|
static parse(selector) {
|
|
2066
2154
|
selector = selector.replace(/([+~>]) /g, "$1");
|
|
2067
2155
|
let begin = 0;
|
|
2068
|
-
const delimiter = /((?:[
|
|
2156
|
+
const delimiter = /((?:[^\\\u0039\u0061\u0064]) +|$)/g;
|
|
2069
2157
|
return Array.from(selector.matchAll(delimiter), (match) => {
|
|
2070
2158
|
const end = match.index + 1;
|
|
2071
|
-
const part = selector.slice(begin, end);
|
|
2159
|
+
const part = unescapeCodepoint(selector.slice(begin, end));
|
|
2072
2160
|
begin = end + 1;
|
|
2073
2161
|
return new Pattern(part);
|
|
2074
2162
|
});
|
|
@@ -2401,7 +2489,8 @@ class HtmlElement extends DOMNode {
|
|
|
2401
2489
|
return this.cacheSet(ROLE, role.value);
|
|
2402
2490
|
}
|
|
2403
2491
|
if (this.metaElement) {
|
|
2404
|
-
const
|
|
2492
|
+
const { aria } = this.metaElement;
|
|
2493
|
+
const implicitRole = aria.implicitRole(this._adapter);
|
|
2405
2494
|
return this.cacheSet(ROLE, implicitRole);
|
|
2406
2495
|
}
|
|
2407
2496
|
return this.cacheSet(ROLE, null);
|
|
@@ -3143,6 +3232,48 @@ function interpolate(text, data) {
|
|
|
3143
3232
|
});
|
|
3144
3233
|
}
|
|
3145
3234
|
|
|
3235
|
+
const cacheKey = Symbol("aria-naming");
|
|
3236
|
+
const defaultValue = "allowed";
|
|
3237
|
+
const prohibitedRoles = [
|
|
3238
|
+
"caption",
|
|
3239
|
+
"code",
|
|
3240
|
+
"deletion",
|
|
3241
|
+
"emphasis",
|
|
3242
|
+
"generic",
|
|
3243
|
+
"insertion",
|
|
3244
|
+
"paragraph",
|
|
3245
|
+
"presentation",
|
|
3246
|
+
"strong",
|
|
3247
|
+
"subscript",
|
|
3248
|
+
"superscript"
|
|
3249
|
+
];
|
|
3250
|
+
function byRole(role) {
|
|
3251
|
+
return prohibitedRoles.includes(role) ? "prohibited" : "allowed";
|
|
3252
|
+
}
|
|
3253
|
+
function byMeta(element, meta) {
|
|
3254
|
+
return meta.aria.naming(element._adapter);
|
|
3255
|
+
}
|
|
3256
|
+
function ariaNaming(element) {
|
|
3257
|
+
var _a;
|
|
3258
|
+
const cached = element.cacheGet(cacheKey);
|
|
3259
|
+
if (cached) {
|
|
3260
|
+
return cached;
|
|
3261
|
+
}
|
|
3262
|
+
const role = (_a = element.getAttribute("role")) == null ? void 0 : _a.value;
|
|
3263
|
+
if (role) {
|
|
3264
|
+
if (role instanceof DynamicValue) {
|
|
3265
|
+
return element.cacheSet(cacheKey, defaultValue);
|
|
3266
|
+
} else {
|
|
3267
|
+
return element.cacheSet(cacheKey, byRole(role));
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
const meta = element.meta;
|
|
3271
|
+
if (!meta) {
|
|
3272
|
+
return element.cacheSet(cacheKey, defaultValue);
|
|
3273
|
+
}
|
|
3274
|
+
return element.cacheSet(cacheKey, byMeta(element, meta));
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3146
3277
|
const patternCache = /* @__PURE__ */ new Map();
|
|
3147
3278
|
function compileStringPattern(pattern) {
|
|
3148
3279
|
const regexp = pattern.replace(/[*]+/g, ".+");
|
|
@@ -3661,7 +3792,7 @@ class Rule {
|
|
|
3661
3792
|
}
|
|
3662
3793
|
}
|
|
3663
3794
|
|
|
3664
|
-
const defaults$
|
|
3795
|
+
const defaults$v = {
|
|
3665
3796
|
allowExternal: true,
|
|
3666
3797
|
allowRelative: true,
|
|
3667
3798
|
allowAbsolute: true,
|
|
@@ -3702,7 +3833,7 @@ function matchList(value, list) {
|
|
|
3702
3833
|
}
|
|
3703
3834
|
class AllowedLinks extends Rule {
|
|
3704
3835
|
constructor(options) {
|
|
3705
|
-
super({ ...defaults$
|
|
3836
|
+
super({ ...defaults$v, ...options });
|
|
3706
3837
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3707
3838
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3708
3839
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3866,7 +3997,7 @@ class AllowedLinks extends Rule {
|
|
|
3866
3997
|
}
|
|
3867
3998
|
}
|
|
3868
3999
|
|
|
3869
|
-
const defaults$
|
|
4000
|
+
const defaults$u = {
|
|
3870
4001
|
accessible: true
|
|
3871
4002
|
};
|
|
3872
4003
|
function findByTarget(target, siblings) {
|
|
@@ -3896,7 +4027,7 @@ function getDescription$1(context) {
|
|
|
3896
4027
|
}
|
|
3897
4028
|
class AreaAlt extends Rule {
|
|
3898
4029
|
constructor(options) {
|
|
3899
|
-
super({ ...defaults$
|
|
4030
|
+
super({ ...defaults$u, ...options });
|
|
3900
4031
|
}
|
|
3901
4032
|
static schema() {
|
|
3902
4033
|
return {
|
|
@@ -3975,6 +4106,9 @@ class AriaHiddenBody extends Rule {
|
|
|
3975
4106
|
}
|
|
3976
4107
|
}
|
|
3977
4108
|
|
|
4109
|
+
const defaults$t = {
|
|
4110
|
+
allowAnyNamable: false
|
|
4111
|
+
};
|
|
3978
4112
|
const whitelisted = [
|
|
3979
4113
|
"main",
|
|
3980
4114
|
"nav",
|
|
@@ -4013,6 +4147,9 @@ function isValidUsage(target, meta) {
|
|
|
4013
4147
|
return false;
|
|
4014
4148
|
}
|
|
4015
4149
|
class AriaLabelMisuse extends Rule {
|
|
4150
|
+
constructor(options) {
|
|
4151
|
+
super({ ...defaults$t, ...options });
|
|
4152
|
+
}
|
|
4016
4153
|
documentation() {
|
|
4017
4154
|
const valid = [
|
|
4018
4155
|
"Interactive elements",
|
|
@@ -4055,6 +4192,9 @@ ${lines}`,
|
|
|
4055
4192
|
if (isValidUsage(target, meta)) {
|
|
4056
4193
|
return;
|
|
4057
4194
|
}
|
|
4195
|
+
if (this.options.allowAnyNamable && ariaNaming(target) === "allowed") {
|
|
4196
|
+
return;
|
|
4197
|
+
}
|
|
4058
4198
|
this.report(target, `"aria-label" cannot be used on this element`, attr.keyLocation);
|
|
4059
4199
|
}
|
|
4060
4200
|
}
|
|
@@ -7552,7 +7692,7 @@ class NoRedundantRole extends Rule {
|
|
|
7552
7692
|
if (!meta) {
|
|
7553
7693
|
return;
|
|
7554
7694
|
}
|
|
7555
|
-
const implicitRole = meta.implicitRole(target._adapter);
|
|
7695
|
+
const implicitRole = meta.aria.implicitRole(target._adapter);
|
|
7556
7696
|
if (!implicitRole) {
|
|
7557
7697
|
return;
|
|
7558
7698
|
}
|
|
@@ -9334,7 +9474,7 @@ const config$4 = {
|
|
|
9334
9474
|
rules: {
|
|
9335
9475
|
"area-alt": ["error", { accessible: true }],
|
|
9336
9476
|
"aria-hidden-body": "error",
|
|
9337
|
-
"aria-label-misuse": "error",
|
|
9477
|
+
"aria-label-misuse": ["error", { allowAnyNamable: false }],
|
|
9338
9478
|
"deprecated-rule": "warn",
|
|
9339
9479
|
"empty-heading": "error",
|
|
9340
9480
|
"empty-title": "error",
|
|
@@ -9386,7 +9526,7 @@ const config$1 = {
|
|
|
9386
9526
|
rules: {
|
|
9387
9527
|
"area-alt": ["error", { accessible: true }],
|
|
9388
9528
|
"aria-hidden-body": "error",
|
|
9389
|
-
"aria-label-misuse": "error",
|
|
9529
|
+
"aria-label-misuse": ["error", { allowAnyNamable: false }],
|
|
9390
9530
|
"attr-case": "error",
|
|
9391
9531
|
"attr-delimiter": "error",
|
|
9392
9532
|
"attr-quotes": "error",
|
|
@@ -9467,6 +9607,7 @@ var recommended = config$1;
|
|
|
9467
9607
|
const config = {
|
|
9468
9608
|
rules: {
|
|
9469
9609
|
"area-alt": ["error", { accessible: false }],
|
|
9610
|
+
"aria-label-misuse": ["error", { allowAnyNamable: true }],
|
|
9470
9611
|
"attr-spacing": "error",
|
|
9471
9612
|
"attribute-allowed-values": "error",
|
|
9472
9613
|
"attribute-misuse": "error",
|
|
@@ -11719,7 +11860,7 @@ class HtmlValidate {
|
|
|
11719
11860
|
}
|
|
11720
11861
|
|
|
11721
11862
|
const name = "html-validate";
|
|
11722
|
-
const version = "8.
|
|
11863
|
+
const version = "8.11.0";
|
|
11723
11864
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11724
11865
|
|
|
11725
11866
|
function definePlugin(plugin) {
|
|
@@ -12596,5 +12737,5 @@ function compatibilityCheckImpl(name, declared, options) {
|
|
|
12596
12737
|
return false;
|
|
12597
12738
|
}
|
|
12598
12739
|
|
|
12599
|
-
export { Attribute as A,
|
|
12740
|
+
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
12741
|
//# sourceMappingURL=core.js.map
|