html-validate 10.1.1 → 10.2.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/cli.js +201 -203
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js +3 -3
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +431 -368
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +2 -2
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +2 -3
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/jest-diff.js +2 -0
- package/dist/cjs/jest-diff.js.map +1 -1
- package/dist/cjs/jest-worker.js.map +1 -1
- package/dist/cjs/jest.js +1 -1
- package/dist/cjs/jest.js.map +1 -1
- package/dist/cjs/matchers-jestonly.js +1 -1
- package/dist/cjs/matchers-jestonly.js.map +1 -1
- package/dist/cjs/matchers.js.map +1 -1
- package/dist/cjs/meta-helper.js +4 -4
- package/dist/cjs/meta-helper.js.map +1 -1
- package/dist/cjs/test-utils.js +2 -2
- package/dist/cjs/test-utils.js.map +2 -2
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/cjs/vitest.js.map +1 -1
- package/dist/esm/browser.js +1 -1
- package/dist/esm/cli.js +201 -202
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/core-browser.js.map +1 -1
- package/dist/esm/core-nodejs.js +3 -3
- package/dist/esm/core-nodejs.js.map +1 -1
- package/dist/esm/core.js +432 -369
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/elements.js +3 -3
- package/dist/esm/elements.js.map +1 -1
- package/dist/esm/html-validate.js +2 -3
- package/dist/esm/html-validate.js.map +1 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/jest-diff.js +2 -0
- package/dist/esm/jest-diff.js.map +1 -1
- package/dist/esm/jest-worker.js.map +1 -1
- package/dist/esm/jest.js +1 -1
- package/dist/esm/jest.js.map +1 -1
- package/dist/esm/matchers-jestonly.js +1 -1
- package/dist/esm/matchers-jestonly.js.map +1 -1
- package/dist/esm/matchers.js.map +1 -1
- package/dist/esm/meta-helper.js +4 -4
- package/dist/esm/meta-helper.js.map +1 -1
- package/dist/esm/test-utils.js +1 -1
- package/dist/esm/test-utils.js.map +1 -1
- package/dist/esm/vitest.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/cjs/core.js
CHANGED
|
@@ -505,27 +505,6 @@ class SchemaValidationError extends UserError {
|
|
|
505
505
|
}
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
-
function cyrb53(str) {
|
|
509
|
-
const a = 2654435761;
|
|
510
|
-
const b = 1597334677;
|
|
511
|
-
const c = 2246822507;
|
|
512
|
-
const d = 3266489909;
|
|
513
|
-
const e = 4294967296;
|
|
514
|
-
const f = 2097151;
|
|
515
|
-
const seed = 0;
|
|
516
|
-
let h1 = 3735928559 ^ seed;
|
|
517
|
-
let h2 = 1103547991 ^ seed;
|
|
518
|
-
for (let i = 0, ch; i < str.length; i++) {
|
|
519
|
-
ch = str.charCodeAt(i);
|
|
520
|
-
h1 = Math.imul(h1 ^ ch, a);
|
|
521
|
-
h2 = Math.imul(h2 ^ ch, b);
|
|
522
|
-
}
|
|
523
|
-
h1 = Math.imul(h1 ^ h1 >>> 16, c) ^ Math.imul(h2 ^ h2 >>> 13, d);
|
|
524
|
-
h2 = Math.imul(h2 ^ h2 >>> 16, c) ^ Math.imul(h1 ^ h1 >>> 13, d);
|
|
525
|
-
return e * (f & h2) + (h1 >>> 0);
|
|
526
|
-
}
|
|
527
|
-
const computeHash = cyrb53;
|
|
528
|
-
|
|
529
508
|
const $schema$1 = "http://json-schema.org/draft-06/schema#";
|
|
530
509
|
const $id$1 = "https://html-validate.org/schemas/elements.json";
|
|
531
510
|
const type$1 = "object";
|
|
@@ -1001,6 +980,27 @@ const ajvFunctionKeyword = {
|
|
|
1001
980
|
validate: ajvFunctionValidate
|
|
1002
981
|
};
|
|
1003
982
|
|
|
983
|
+
function cyrb53(str) {
|
|
984
|
+
const a = 2654435761;
|
|
985
|
+
const b = 1597334677;
|
|
986
|
+
const c = 2246822507;
|
|
987
|
+
const d = 3266489909;
|
|
988
|
+
const e = 4294967296;
|
|
989
|
+
const f = 2097151;
|
|
990
|
+
const seed = 0;
|
|
991
|
+
let h1 = 3735928559 ^ seed;
|
|
992
|
+
let h2 = 1103547991 ^ seed;
|
|
993
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
994
|
+
ch = str.charCodeAt(i);
|
|
995
|
+
h1 = Math.imul(h1 ^ ch, a);
|
|
996
|
+
h2 = Math.imul(h2 ^ ch, b);
|
|
997
|
+
}
|
|
998
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, c) ^ Math.imul(h2 ^ h2 >>> 13, d);
|
|
999
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, c) ^ Math.imul(h1 ^ h1 >>> 13, d);
|
|
1000
|
+
return e * (f & h2) + (h1 >>> 0);
|
|
1001
|
+
}
|
|
1002
|
+
const computeHash = cyrb53;
|
|
1003
|
+
|
|
1004
1004
|
var TextContent$1 = /* @__PURE__ */ ((TextContent2) => {
|
|
1005
1005
|
TextContent2["NONE"] = "none";
|
|
1006
1006
|
TextContent2["DEFAULT"] = "default";
|
|
@@ -1495,7 +1495,7 @@ function sliceLocation(location, begin, end, wrap) {
|
|
|
1495
1495
|
if (wrap) {
|
|
1496
1496
|
let index = -1;
|
|
1497
1497
|
const col = sliced.column;
|
|
1498
|
-
|
|
1498
|
+
for (; ; ) {
|
|
1499
1499
|
index = wrap.indexOf("\n", index + 1);
|
|
1500
1500
|
if (index >= 0 && index < begin) {
|
|
1501
1501
|
sliced.column = col - (index + 1);
|
|
@@ -1503,7 +1503,7 @@ function sliceLocation(location, begin, end, wrap) {
|
|
|
1503
1503
|
} else {
|
|
1504
1504
|
break;
|
|
1505
1505
|
}
|
|
1506
|
-
}
|
|
1506
|
+
}
|
|
1507
1507
|
}
|
|
1508
1508
|
return sliced;
|
|
1509
1509
|
}
|
|
@@ -1601,7 +1601,6 @@ class DOMNode {
|
|
|
1601
1601
|
* @internal
|
|
1602
1602
|
*/
|
|
1603
1603
|
unique;
|
|
1604
|
-
/* eslint-disable-next-line sonarjs/use-type-alias -- technical debt */
|
|
1605
1604
|
cache;
|
|
1606
1605
|
/**
|
|
1607
1606
|
* Set of disabled rules for this node.
|
|
@@ -1641,8 +1640,8 @@ class DOMNode {
|
|
|
1641
1640
|
*
|
|
1642
1641
|
* @internal
|
|
1643
1642
|
*/
|
|
1644
|
-
cacheEnable() {
|
|
1645
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
1643
|
+
cacheEnable(enable = true) {
|
|
1644
|
+
this.cache = enable ? /* @__PURE__ */ new Map() : null;
|
|
1646
1645
|
}
|
|
1647
1646
|
cacheGet(key) {
|
|
1648
1647
|
if (this.cache) {
|
|
@@ -3329,172 +3328,6 @@ function parseQuantifier(quantifier) {
|
|
|
3329
3328
|
}
|
|
3330
3329
|
}
|
|
3331
3330
|
|
|
3332
|
-
const $schema = "http://json-schema.org/draft-06/schema#";
|
|
3333
|
-
const $id = "https://html-validate.org/schemas/config.json";
|
|
3334
|
-
const type = "object";
|
|
3335
|
-
const additionalProperties = false;
|
|
3336
|
-
const properties = {
|
|
3337
|
-
$schema: {
|
|
3338
|
-
type: "string"
|
|
3339
|
-
},
|
|
3340
|
-
root: {
|
|
3341
|
-
type: "boolean",
|
|
3342
|
-
title: "Mark as root configuration",
|
|
3343
|
-
description: "If this is set to true no further configurations will be searched.",
|
|
3344
|
-
"default": false
|
|
3345
|
-
},
|
|
3346
|
-
"extends": {
|
|
3347
|
-
type: "array",
|
|
3348
|
-
items: {
|
|
3349
|
-
type: "string"
|
|
3350
|
-
},
|
|
3351
|
-
title: "Configurations to extend",
|
|
3352
|
-
description: "Array of shareable or builtin configurations to extend."
|
|
3353
|
-
},
|
|
3354
|
-
elements: {
|
|
3355
|
-
type: "array",
|
|
3356
|
-
items: {
|
|
3357
|
-
anyOf: [
|
|
3358
|
-
{
|
|
3359
|
-
type: "string"
|
|
3360
|
-
},
|
|
3361
|
-
{
|
|
3362
|
-
type: "object"
|
|
3363
|
-
}
|
|
3364
|
-
]
|
|
3365
|
-
},
|
|
3366
|
-
title: "Element metadata to load",
|
|
3367
|
-
description: "Array of modules, plugins or files to load element metadata from. Use <rootDir> to refer to the folder with the package.json file.",
|
|
3368
|
-
examples: [
|
|
3369
|
-
[
|
|
3370
|
-
"html-validate:recommended",
|
|
3371
|
-
"plugin:recommended",
|
|
3372
|
-
"module",
|
|
3373
|
-
"./local-file.json"
|
|
3374
|
-
]
|
|
3375
|
-
]
|
|
3376
|
-
},
|
|
3377
|
-
plugins: {
|
|
3378
|
-
type: "array",
|
|
3379
|
-
items: {
|
|
3380
|
-
anyOf: [
|
|
3381
|
-
{
|
|
3382
|
-
type: "string"
|
|
3383
|
-
},
|
|
3384
|
-
{
|
|
3385
|
-
type: "object"
|
|
3386
|
-
}
|
|
3387
|
-
]
|
|
3388
|
-
},
|
|
3389
|
-
title: "Plugins to load",
|
|
3390
|
-
description: "Array of plugins load. Use <rootDir> to refer to the folder with the package.json file.",
|
|
3391
|
-
examples: [
|
|
3392
|
-
[
|
|
3393
|
-
"my-plugin",
|
|
3394
|
-
"./local-plugin"
|
|
3395
|
-
]
|
|
3396
|
-
]
|
|
3397
|
-
},
|
|
3398
|
-
transform: {
|
|
3399
|
-
type: "object",
|
|
3400
|
-
additionalProperties: {
|
|
3401
|
-
anyOf: [
|
|
3402
|
-
{
|
|
3403
|
-
type: "string"
|
|
3404
|
-
},
|
|
3405
|
-
{
|
|
3406
|
-
"function": true
|
|
3407
|
-
}
|
|
3408
|
-
]
|
|
3409
|
-
},
|
|
3410
|
-
title: "File transformations to use.",
|
|
3411
|
-
description: "Object where key is regular expression to match filename and value is name of transformer or a function.",
|
|
3412
|
-
examples: [
|
|
3413
|
-
{
|
|
3414
|
-
"^.*\\.foo$": "my-transformer",
|
|
3415
|
-
"^.*\\.bar$": "my-plugin",
|
|
3416
|
-
"^.*\\.baz$": "my-plugin:named"
|
|
3417
|
-
}
|
|
3418
|
-
]
|
|
3419
|
-
},
|
|
3420
|
-
rules: {
|
|
3421
|
-
type: "object",
|
|
3422
|
-
patternProperties: {
|
|
3423
|
-
".*": {
|
|
3424
|
-
anyOf: [
|
|
3425
|
-
{
|
|
3426
|
-
"enum": [
|
|
3427
|
-
0,
|
|
3428
|
-
1,
|
|
3429
|
-
2,
|
|
3430
|
-
"off",
|
|
3431
|
-
"warn",
|
|
3432
|
-
"error"
|
|
3433
|
-
]
|
|
3434
|
-
},
|
|
3435
|
-
{
|
|
3436
|
-
type: "array",
|
|
3437
|
-
minItems: 1,
|
|
3438
|
-
maxItems: 1,
|
|
3439
|
-
items: [
|
|
3440
|
-
{
|
|
3441
|
-
"enum": [
|
|
3442
|
-
0,
|
|
3443
|
-
1,
|
|
3444
|
-
2,
|
|
3445
|
-
"off",
|
|
3446
|
-
"warn",
|
|
3447
|
-
"error"
|
|
3448
|
-
]
|
|
3449
|
-
}
|
|
3450
|
-
]
|
|
3451
|
-
},
|
|
3452
|
-
{
|
|
3453
|
-
type: "array",
|
|
3454
|
-
minItems: 2,
|
|
3455
|
-
maxItems: 2,
|
|
3456
|
-
items: [
|
|
3457
|
-
{
|
|
3458
|
-
"enum": [
|
|
3459
|
-
0,
|
|
3460
|
-
1,
|
|
3461
|
-
2,
|
|
3462
|
-
"off",
|
|
3463
|
-
"warn",
|
|
3464
|
-
"error"
|
|
3465
|
-
]
|
|
3466
|
-
},
|
|
3467
|
-
{
|
|
3468
|
-
}
|
|
3469
|
-
]
|
|
3470
|
-
}
|
|
3471
|
-
]
|
|
3472
|
-
}
|
|
3473
|
-
},
|
|
3474
|
-
title: "Rule configuration.",
|
|
3475
|
-
description: "Enable/disable rules, set severity. Some rules have additional configuration like style or patterns to use.",
|
|
3476
|
-
examples: [
|
|
3477
|
-
{
|
|
3478
|
-
foo: "error",
|
|
3479
|
-
bar: "off",
|
|
3480
|
-
baz: [
|
|
3481
|
-
"error",
|
|
3482
|
-
{
|
|
3483
|
-
style: "camelcase"
|
|
3484
|
-
}
|
|
3485
|
-
]
|
|
3486
|
-
}
|
|
3487
|
-
]
|
|
3488
|
-
}
|
|
3489
|
-
};
|
|
3490
|
-
var configurationSchema = {
|
|
3491
|
-
$schema: $schema,
|
|
3492
|
-
$id: $id,
|
|
3493
|
-
type: type,
|
|
3494
|
-
additionalProperties: additionalProperties,
|
|
3495
|
-
properties: properties
|
|
3496
|
-
};
|
|
3497
|
-
|
|
3498
3331
|
var Severity = /* @__PURE__ */ ((Severity2) => {
|
|
3499
3332
|
Severity2[Severity2["DISABLED"] = 0] = "DISABLED";
|
|
3500
3333
|
Severity2[Severity2["WARN"] = 1] = "WARN";
|
|
@@ -3517,35 +3350,6 @@ function parseSeverity(value) {
|
|
|
3517
3350
|
}
|
|
3518
3351
|
}
|
|
3519
3352
|
|
|
3520
|
-
function escape(value) {
|
|
3521
|
-
return JSON.stringify(value);
|
|
3522
|
-
}
|
|
3523
|
-
function format(value, quote = false) {
|
|
3524
|
-
if (value === null || value === void 0) {
|
|
3525
|
-
return "null";
|
|
3526
|
-
}
|
|
3527
|
-
if (typeof value === "number") {
|
|
3528
|
-
return value.toString();
|
|
3529
|
-
}
|
|
3530
|
-
if (typeof value === "string") {
|
|
3531
|
-
return quote ? escape(value) : value;
|
|
3532
|
-
}
|
|
3533
|
-
if (Array.isArray(value)) {
|
|
3534
|
-
const content = value.map((it) => format(it, true)).join(", ");
|
|
3535
|
-
return `[ ${content} ]`;
|
|
3536
|
-
}
|
|
3537
|
-
if (typeof value === "object") {
|
|
3538
|
-
const content = Object.entries(value).map(([key, nested]) => `${key}: ${format(nested, true)}`).join(", ");
|
|
3539
|
-
return `{ ${content} }`;
|
|
3540
|
-
}
|
|
3541
|
-
return String(value);
|
|
3542
|
-
}
|
|
3543
|
-
function interpolate(text, data) {
|
|
3544
|
-
return text.replace(/{{\s*([^\s{}]+)\s*}}/g, (match, key) => {
|
|
3545
|
-
return typeof data[key] !== "undefined" ? format(data[key]) : match;
|
|
3546
|
-
});
|
|
3547
|
-
}
|
|
3548
|
-
|
|
3549
3353
|
const cacheKey = Symbol("aria-naming");
|
|
3550
3354
|
const defaultValue = "allowed";
|
|
3551
3355
|
const prohibitedRoles = [
|
|
@@ -3587,6 +3391,31 @@ function ariaNaming(element) {
|
|
|
3587
3391
|
return element.cacheSet(cacheKey, byMeta(element, meta));
|
|
3588
3392
|
}
|
|
3589
3393
|
|
|
3394
|
+
const INPUT_DISABLED_CACHE = Symbol(isInputDisabled.name);
|
|
3395
|
+
function isInputDisabled(node, details) {
|
|
3396
|
+
const cached = node.cacheGet(INPUT_DISABLED_CACHE);
|
|
3397
|
+
if (cached) {
|
|
3398
|
+
return details ? cached : cached.byFieldset || cached.bySelf;
|
|
3399
|
+
}
|
|
3400
|
+
const result = node.cacheSet(INPUT_DISABLED_CACHE, isInputDisabledImpl(node));
|
|
3401
|
+
return details ? result : result.byFieldset || result.bySelf;
|
|
3402
|
+
}
|
|
3403
|
+
function isInputDisabledImpl(node) {
|
|
3404
|
+
const hasDisabledAttr = (node2) => {
|
|
3405
|
+
const disabled = node2.getAttribute("disabled");
|
|
3406
|
+
return Boolean(disabled?.isStatic);
|
|
3407
|
+
};
|
|
3408
|
+
const hasDisabledFieldset = (node2) => {
|
|
3409
|
+
const fieldset = node2.closest("fieldset[disabled]");
|
|
3410
|
+
const disabled = fieldset?.getAttribute("disabled");
|
|
3411
|
+
return Boolean(disabled?.isStatic);
|
|
3412
|
+
};
|
|
3413
|
+
return {
|
|
3414
|
+
byFieldset: hasDisabledFieldset(node),
|
|
3415
|
+
bySelf: hasDisabledAttr(node)
|
|
3416
|
+
};
|
|
3417
|
+
}
|
|
3418
|
+
|
|
3590
3419
|
const patternCache = /* @__PURE__ */ new Map();
|
|
3591
3420
|
function compileStringPattern(pattern) {
|
|
3592
3421
|
const regexp = pattern.replace(/[*]+/g, ".+");
|
|
@@ -3651,7 +3480,7 @@ function inAccessibilityTree(node) {
|
|
|
3651
3480
|
function isAriaHiddenImpl(node) {
|
|
3652
3481
|
const getAriaHiddenAttr = (node2) => {
|
|
3653
3482
|
const ariaHidden = node2.getAttribute("aria-hidden");
|
|
3654
|
-
return
|
|
3483
|
+
return ariaHidden?.value === "true";
|
|
3655
3484
|
};
|
|
3656
3485
|
return {
|
|
3657
3486
|
byParent: node.parent ? isAriaHidden(node.parent) : false,
|
|
@@ -3840,6 +3669,35 @@ function partition(values, predicate) {
|
|
|
3840
3669
|
}, initial);
|
|
3841
3670
|
}
|
|
3842
3671
|
|
|
3672
|
+
function escape(value) {
|
|
3673
|
+
return JSON.stringify(value);
|
|
3674
|
+
}
|
|
3675
|
+
function format(value, quote = false) {
|
|
3676
|
+
if (value === null || value === void 0) {
|
|
3677
|
+
return "null";
|
|
3678
|
+
}
|
|
3679
|
+
if (typeof value === "number") {
|
|
3680
|
+
return value.toString();
|
|
3681
|
+
}
|
|
3682
|
+
if (typeof value === "string") {
|
|
3683
|
+
return quote ? escape(value) : value;
|
|
3684
|
+
}
|
|
3685
|
+
if (Array.isArray(value)) {
|
|
3686
|
+
const content = value.map((it) => format(it, true)).join(", ");
|
|
3687
|
+
return `[ ${content} ]`;
|
|
3688
|
+
}
|
|
3689
|
+
if (typeof value === "object") {
|
|
3690
|
+
const content = Object.entries(value).map(([key, nested]) => `${key}: ${format(nested, true)}`).join(", ");
|
|
3691
|
+
return `{ ${content} }`;
|
|
3692
|
+
}
|
|
3693
|
+
return String(value);
|
|
3694
|
+
}
|
|
3695
|
+
function interpolate(text, data) {
|
|
3696
|
+
return text.replace(/{{\s*([^\s{}]+)\s*}}/g, (match, key) => {
|
|
3697
|
+
return typeof data[key] !== "undefined" ? format(data[key]) : match;
|
|
3698
|
+
});
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3843
3701
|
const ajv$1 = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
3844
3702
|
ajv$1.addMetaSchema(ajvSchemaDraft);
|
|
3845
3703
|
function getSchemaValidator(ruleId, properties) {
|
|
@@ -3857,7 +3715,7 @@ function getSchemaValidator(ruleId, properties) {
|
|
|
3857
3715
|
return ajv$1.compile(schema);
|
|
3858
3716
|
}
|
|
3859
3717
|
function isErrorDescriptor(value) {
|
|
3860
|
-
return Boolean(value[0] && value[0]
|
|
3718
|
+
return Boolean(value[0] && value[0]["message"]);
|
|
3861
3719
|
}
|
|
3862
3720
|
function unpackErrorDescriptor(value) {
|
|
3863
3721
|
if (isErrorDescriptor(value)) {
|
|
@@ -4128,8 +3986,7 @@ class Rule {
|
|
|
4128
3986
|
* @returns Rule documentation and url with additional details or `null` if no
|
|
4129
3987
|
* additional documentation is available.
|
|
4130
3988
|
*/
|
|
4131
|
-
|
|
4132
|
-
documentation(context) {
|
|
3989
|
+
documentation(_context) {
|
|
4133
3990
|
return null;
|
|
4134
3991
|
}
|
|
4135
3992
|
}
|
|
@@ -4458,7 +4315,7 @@ class AriaHiddenBody extends Rule {
|
|
|
4458
4315
|
const defaults$w = {
|
|
4459
4316
|
allowAnyNamable: false
|
|
4460
4317
|
};
|
|
4461
|
-
const
|
|
4318
|
+
const allowlist = /* @__PURE__ */ new Set([
|
|
4462
4319
|
"main",
|
|
4463
4320
|
"nav",
|
|
4464
4321
|
"table",
|
|
@@ -4471,18 +4328,19 @@ const whitelisted = [
|
|
|
4471
4328
|
"article",
|
|
4472
4329
|
"dialog",
|
|
4473
4330
|
"form",
|
|
4331
|
+
"iframe",
|
|
4474
4332
|
"img",
|
|
4475
4333
|
"area",
|
|
4476
4334
|
"fieldset",
|
|
4477
4335
|
"summary",
|
|
4478
4336
|
"figure"
|
|
4479
|
-
];
|
|
4337
|
+
]);
|
|
4480
4338
|
function isValidUsage(target, meta) {
|
|
4481
4339
|
const explicit = meta.attributes["aria-label"];
|
|
4482
4340
|
if (explicit) {
|
|
4483
4341
|
return true;
|
|
4484
4342
|
}
|
|
4485
|
-
if (
|
|
4343
|
+
if (allowlist.has(target.tagName)) {
|
|
4486
4344
|
return true;
|
|
4487
4345
|
}
|
|
4488
4346
|
if (target.hasAttribute("role")) {
|
|
@@ -4500,7 +4358,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4500
4358
|
constructor(options) {
|
|
4501
4359
|
super({ ...defaults$w, ...options });
|
|
4502
4360
|
}
|
|
4503
|
-
documentation() {
|
|
4361
|
+
documentation(context) {
|
|
4504
4362
|
const valid = [
|
|
4505
4363
|
"Interactive elements",
|
|
4506
4364
|
"Labelable elements",
|
|
@@ -4514,25 +4372,41 @@ class AriaLabelMisuse extends Rule {
|
|
|
4514
4372
|
"`<summary>`",
|
|
4515
4373
|
"`<table>`, `<td>` and `<th>`"
|
|
4516
4374
|
];
|
|
4517
|
-
const lines = valid.map((it) => `- ${it}
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4375
|
+
const lines = valid.map((it) => `- ${it}`);
|
|
4376
|
+
const url = "https://html-validate.org/rules/aria-label-misuse.html";
|
|
4377
|
+
if (context.allowsNaming) {
|
|
4378
|
+
return {
|
|
4379
|
+
description: [
|
|
4380
|
+
`\`${context.attr}\` is strictly allowed but is not recommended to be used on this element.`,
|
|
4381
|
+
`\`${context.attr}\` can only be used on:`,
|
|
4382
|
+
"",
|
|
4383
|
+
...lines
|
|
4384
|
+
].join("\n"),
|
|
4385
|
+
url
|
|
4386
|
+
};
|
|
4387
|
+
} else {
|
|
4388
|
+
return {
|
|
4389
|
+
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4390
|
+
url
|
|
4391
|
+
};
|
|
4392
|
+
}
|
|
4525
4393
|
}
|
|
4526
4394
|
setup() {
|
|
4527
4395
|
this.on("dom:ready", (event) => {
|
|
4528
4396
|
const { document } = event;
|
|
4529
|
-
for (const target of document.querySelectorAll("[aria-label]")) {
|
|
4530
|
-
|
|
4397
|
+
for (const target of document.querySelectorAll("[aria-label], [aria-labelledby]")) {
|
|
4398
|
+
const ariaLabel = target.getAttribute("aria-label");
|
|
4399
|
+
if (ariaLabel) {
|
|
4400
|
+
this.validateElement(target, ariaLabel, "aria-label");
|
|
4401
|
+
}
|
|
4402
|
+
const ariaLabelledby = target.getAttribute("aria-labelledby");
|
|
4403
|
+
if (ariaLabelledby) {
|
|
4404
|
+
this.validateElement(target, ariaLabelledby, "aria-labelledby");
|
|
4405
|
+
}
|
|
4531
4406
|
}
|
|
4532
4407
|
});
|
|
4533
4408
|
}
|
|
4534
|
-
validateElement(target) {
|
|
4535
|
-
const attr = target.getAttribute("aria-label");
|
|
4409
|
+
validateElement(target, attr, key) {
|
|
4536
4410
|
if (!attr.value || attr.valueMatches("", false)) {
|
|
4537
4411
|
return;
|
|
4538
4412
|
}
|
|
@@ -4543,10 +4417,26 @@ ${lines}`,
|
|
|
4543
4417
|
if (isValidUsage(target, meta)) {
|
|
4544
4418
|
return;
|
|
4545
4419
|
}
|
|
4546
|
-
|
|
4420
|
+
const allowsNaming = ariaNaming(target) === "allowed";
|
|
4421
|
+
if (allowsNaming && this.options.allowAnyNamable) {
|
|
4547
4422
|
return;
|
|
4548
4423
|
}
|
|
4549
|
-
|
|
4424
|
+
const context = { attr: key, allowsNaming };
|
|
4425
|
+
if (allowsNaming) {
|
|
4426
|
+
this.report({
|
|
4427
|
+
node: target,
|
|
4428
|
+
location: attr.keyLocation,
|
|
4429
|
+
context,
|
|
4430
|
+
message: `"{{ attr }}" is strictly allowed but is not recommended to be used on this element`
|
|
4431
|
+
});
|
|
4432
|
+
} else {
|
|
4433
|
+
this.report({
|
|
4434
|
+
node: target,
|
|
4435
|
+
location: attr.keyLocation,
|
|
4436
|
+
context,
|
|
4437
|
+
message: `"{{ attr }}" cannot be used on this element`
|
|
4438
|
+
});
|
|
4439
|
+
}
|
|
4550
4440
|
}
|
|
4551
4441
|
}
|
|
4552
4442
|
|
|
@@ -5241,9 +5131,6 @@ class AttributeAllowedValues extends Rule {
|
|
|
5241
5131
|
description: "Attribute has invalid value.",
|
|
5242
5132
|
url: "https://html-validate.org/rules/attribute-allowed-values.html"
|
|
5243
5133
|
};
|
|
5244
|
-
if (!context) {
|
|
5245
|
-
return docs;
|
|
5246
|
-
}
|
|
5247
5134
|
const { allowed, attribute, element, value } = context;
|
|
5248
5135
|
if (allowed.enum) {
|
|
5249
5136
|
const allowedList = allowed.enum.map((value2) => {
|
|
@@ -6078,7 +5965,10 @@ class ElementName extends Rule {
|
|
|
6078
5965
|
|
|
6079
5966
|
function isNativeTemplate(node) {
|
|
6080
5967
|
const { tagName, meta } = node;
|
|
6081
|
-
|
|
5968
|
+
if (!meta) {
|
|
5969
|
+
return false;
|
|
5970
|
+
}
|
|
5971
|
+
return Boolean(tagName === "template" && meta.templateRoot && meta.scriptSupporting);
|
|
6082
5972
|
}
|
|
6083
5973
|
function getTransparentChildren(node, transparent) {
|
|
6084
5974
|
if (typeof transparent === "boolean") {
|
|
@@ -6307,7 +6197,7 @@ class ElementPermittedParent extends Rule {
|
|
|
6307
6197
|
}
|
|
6308
6198
|
const rules = node.meta?.permittedParent;
|
|
6309
6199
|
if (!rules) {
|
|
6310
|
-
return
|
|
6200
|
+
return;
|
|
6311
6201
|
}
|
|
6312
6202
|
if (Validator.validatePermitted(parent, rules)) {
|
|
6313
6203
|
return;
|
|
@@ -6374,14 +6264,10 @@ class ElementRequiredAncestor extends Rule {
|
|
|
6374
6264
|
|
|
6375
6265
|
class ElementRequiredAttributes extends Rule {
|
|
6376
6266
|
documentation(context) {
|
|
6377
|
-
|
|
6378
|
-
description:
|
|
6267
|
+
return {
|
|
6268
|
+
description: `The \`<${context.element}>\` element is required to have a \`${context.attribute}\` attribute.`,
|
|
6379
6269
|
url: "https://html-validate.org/rules/element-required-attributes.html"
|
|
6380
6270
|
};
|
|
6381
|
-
if (context) {
|
|
6382
|
-
docs.description = `The <${context.element}> element is required to have a "${context.attribute}" attribute.`;
|
|
6383
|
-
}
|
|
6384
|
-
return docs;
|
|
6385
6271
|
}
|
|
6386
6272
|
setup() {
|
|
6387
6273
|
this.on("tag:end", (event) => {
|
|
@@ -6528,6 +6414,18 @@ const defaults$l = {
|
|
|
6528
6414
|
};
|
|
6529
6415
|
const UNIQUE_CACHE_KEY = Symbol("form-elements-unique");
|
|
6530
6416
|
const SHARED_CACHE_KEY = Symbol("form-elements-shared");
|
|
6417
|
+
function isEnabled(element) {
|
|
6418
|
+
if (isHTMLHidden(element)) {
|
|
6419
|
+
return false;
|
|
6420
|
+
}
|
|
6421
|
+
if (isInert(element)) {
|
|
6422
|
+
return false;
|
|
6423
|
+
}
|
|
6424
|
+
if (isInputDisabled(element)) {
|
|
6425
|
+
return false;
|
|
6426
|
+
}
|
|
6427
|
+
return true;
|
|
6428
|
+
}
|
|
6531
6429
|
function haveName(name) {
|
|
6532
6430
|
return typeof name === "string" && name !== "";
|
|
6533
6431
|
}
|
|
@@ -6598,7 +6496,7 @@ class FormDupName extends Rule {
|
|
|
6598
6496
|
const { shared } = this.options;
|
|
6599
6497
|
this.on("dom:ready", (event) => {
|
|
6600
6498
|
const { document } = event;
|
|
6601
|
-
const controls = document.querySelectorAll(selector);
|
|
6499
|
+
const controls = document.querySelectorAll(selector).filter(isEnabled);
|
|
6602
6500
|
const [sharedControls, uniqueControls] = partition(controls, (it) => {
|
|
6603
6501
|
return allowSharedName(it, shared);
|
|
6604
6502
|
});
|
|
@@ -7354,69 +7252,6 @@ class LongTitle extends Rule {
|
|
|
7354
7252
|
}
|
|
7355
7253
|
}
|
|
7356
7254
|
|
|
7357
|
-
const defaults$h = {
|
|
7358
|
-
allowLongDelay: false
|
|
7359
|
-
};
|
|
7360
|
-
class MetaRefresh extends Rule {
|
|
7361
|
-
constructor(options) {
|
|
7362
|
-
super({ ...defaults$h, ...options });
|
|
7363
|
-
}
|
|
7364
|
-
documentation() {
|
|
7365
|
-
return {
|
|
7366
|
-
description: `Meta refresh directive must use the \`0;url=...\` format. Non-zero values for time interval is disallowed as people with assistive technology might be unable to read and understand the page content before automatically reloading. For the same reason skipping the url is disallowed as it would put the browser in an infinite loop reloading the same page over and over again.`,
|
|
7367
|
-
url: "https://html-validate.org/rules/meta-refresh.html"
|
|
7368
|
-
};
|
|
7369
|
-
}
|
|
7370
|
-
setup() {
|
|
7371
|
-
this.on("element:ready", ({ target }) => {
|
|
7372
|
-
if (!target.is("meta")) {
|
|
7373
|
-
return;
|
|
7374
|
-
}
|
|
7375
|
-
const httpEquiv = target.getAttributeValue("http-equiv");
|
|
7376
|
-
if (httpEquiv !== "refresh") {
|
|
7377
|
-
return;
|
|
7378
|
-
}
|
|
7379
|
-
const content = target.getAttribute("content");
|
|
7380
|
-
if (!content?.value || content.isDynamic) {
|
|
7381
|
-
return;
|
|
7382
|
-
}
|
|
7383
|
-
const location = content.valueLocation;
|
|
7384
|
-
const value = parseContent(content.value.toString());
|
|
7385
|
-
if (!value) {
|
|
7386
|
-
this.report(target, "Malformed meta refresh directive", location);
|
|
7387
|
-
return;
|
|
7388
|
-
}
|
|
7389
|
-
const { delay, url } = value;
|
|
7390
|
-
this.validateDelay(target, location, delay, url);
|
|
7391
|
-
});
|
|
7392
|
-
}
|
|
7393
|
-
validateDelay(target, location, delay, url) {
|
|
7394
|
-
const { allowLongDelay } = this.options;
|
|
7395
|
-
if (allowLongDelay && delay > 72e3) {
|
|
7396
|
-
return;
|
|
7397
|
-
}
|
|
7398
|
-
if (!url && delay === 0) {
|
|
7399
|
-
this.report(target, "Don't use instant meta refresh to reload the page", location);
|
|
7400
|
-
return;
|
|
7401
|
-
}
|
|
7402
|
-
if (delay !== 0) {
|
|
7403
|
-
const message = allowLongDelay ? "Meta refresh must be instant (0 second delay) or greater than 20 hours (72000 second delay)" : "Meta refresh must be instant (0 second delay)";
|
|
7404
|
-
this.report(target, message, location);
|
|
7405
|
-
}
|
|
7406
|
-
}
|
|
7407
|
-
}
|
|
7408
|
-
function parseContent(text) {
|
|
7409
|
-
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
7410
|
-
if (match) {
|
|
7411
|
-
return {
|
|
7412
|
-
delay: parseInt(match[1], 10),
|
|
7413
|
-
url: match[2]
|
|
7414
|
-
};
|
|
7415
|
-
} else {
|
|
7416
|
-
return null;
|
|
7417
|
-
}
|
|
7418
|
-
}
|
|
7419
|
-
|
|
7420
7255
|
function getName(attr) {
|
|
7421
7256
|
const name = attr.value;
|
|
7422
7257
|
if (!name || name instanceof DynamicValue) {
|
|
@@ -7479,16 +7314,79 @@ class MapIdName extends Rule {
|
|
|
7479
7314
|
if (!hasStaticValue(id) || !hasStaticValue(name)) {
|
|
7480
7315
|
return;
|
|
7481
7316
|
}
|
|
7482
|
-
if (id.value === name.value) {
|
|
7317
|
+
if (id.value === name.value) {
|
|
7318
|
+
return;
|
|
7319
|
+
}
|
|
7320
|
+
this.report({
|
|
7321
|
+
node: event.target,
|
|
7322
|
+
message: `"id" and "name" attribute must be the same on <map> elements`,
|
|
7323
|
+
location: id.valueLocation ?? name.valueLocation
|
|
7324
|
+
});
|
|
7325
|
+
});
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
|
|
7329
|
+
const defaults$h = {
|
|
7330
|
+
allowLongDelay: false
|
|
7331
|
+
};
|
|
7332
|
+
class MetaRefresh extends Rule {
|
|
7333
|
+
constructor(options) {
|
|
7334
|
+
super({ ...defaults$h, ...options });
|
|
7335
|
+
}
|
|
7336
|
+
documentation() {
|
|
7337
|
+
return {
|
|
7338
|
+
description: `Meta refresh directive must use the \`0;url=...\` format. Non-zero values for time interval is disallowed as people with assistive technology might be unable to read and understand the page content before automatically reloading. For the same reason skipping the url is disallowed as it would put the browser in an infinite loop reloading the same page over and over again.`,
|
|
7339
|
+
url: "https://html-validate.org/rules/meta-refresh.html"
|
|
7340
|
+
};
|
|
7341
|
+
}
|
|
7342
|
+
setup() {
|
|
7343
|
+
this.on("element:ready", ({ target }) => {
|
|
7344
|
+
if (!target.is("meta")) {
|
|
7345
|
+
return;
|
|
7346
|
+
}
|
|
7347
|
+
const httpEquiv = target.getAttributeValue("http-equiv");
|
|
7348
|
+
if (httpEquiv !== "refresh") {
|
|
7349
|
+
return;
|
|
7350
|
+
}
|
|
7351
|
+
const content = target.getAttribute("content");
|
|
7352
|
+
if (!content?.value || content.isDynamic) {
|
|
7353
|
+
return;
|
|
7354
|
+
}
|
|
7355
|
+
const location = content.valueLocation;
|
|
7356
|
+
const value = parseContent(content.value.toString());
|
|
7357
|
+
if (!value) {
|
|
7358
|
+
this.report(target, "Malformed meta refresh directive", location);
|
|
7483
7359
|
return;
|
|
7484
7360
|
}
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
message: `"id" and "name" attribute must be the same on <map> elements`,
|
|
7488
|
-
location: id.valueLocation ?? name.valueLocation
|
|
7489
|
-
});
|
|
7361
|
+
const { delay, url } = value;
|
|
7362
|
+
this.validateDelay(target, location, delay, url);
|
|
7490
7363
|
});
|
|
7491
7364
|
}
|
|
7365
|
+
validateDelay(target, location, delay, url) {
|
|
7366
|
+
const { allowLongDelay } = this.options;
|
|
7367
|
+
if (allowLongDelay && delay > 72e3) {
|
|
7368
|
+
return;
|
|
7369
|
+
}
|
|
7370
|
+
if (!url && delay === 0) {
|
|
7371
|
+
this.report(target, "Don't use instant meta refresh to reload the page", location);
|
|
7372
|
+
return;
|
|
7373
|
+
}
|
|
7374
|
+
if (delay !== 0) {
|
|
7375
|
+
const message = allowLongDelay ? "Meta refresh must be instant (0 second delay) or greater than 20 hours (72000 second delay)" : "Meta refresh must be instant (0 second delay)";
|
|
7376
|
+
this.report(target, message, location);
|
|
7377
|
+
}
|
|
7378
|
+
}
|
|
7379
|
+
}
|
|
7380
|
+
function parseContent(text) {
|
|
7381
|
+
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
7382
|
+
if (match) {
|
|
7383
|
+
return {
|
|
7384
|
+
delay: parseInt(match[1], 10),
|
|
7385
|
+
url: match[2]
|
|
7386
|
+
};
|
|
7387
|
+
} else {
|
|
7388
|
+
return null;
|
|
7389
|
+
}
|
|
7492
7390
|
}
|
|
7493
7391
|
|
|
7494
7392
|
class MissingDoctype extends Rule {
|
|
@@ -7887,30 +7785,6 @@ class NoImplicitButtonType extends Rule {
|
|
|
7887
7785
|
}
|
|
7888
7786
|
}
|
|
7889
7787
|
|
|
7890
|
-
function isRelevant$1(event) {
|
|
7891
|
-
return event.target.is("input");
|
|
7892
|
-
}
|
|
7893
|
-
class NoImplicitInputType extends Rule {
|
|
7894
|
-
documentation() {
|
|
7895
|
-
return {
|
|
7896
|
-
description: ["`<input>` is missing recommended `type` attribute"].join("\n"),
|
|
7897
|
-
url: "https://html-validate.org/rules/no-implicit-input-type.html"
|
|
7898
|
-
};
|
|
7899
|
-
}
|
|
7900
|
-
setup() {
|
|
7901
|
-
this.on("element:ready", isRelevant$1, (event) => {
|
|
7902
|
-
const { target } = event;
|
|
7903
|
-
const attr = target.getAttribute("type");
|
|
7904
|
-
if (!attr) {
|
|
7905
|
-
this.report({
|
|
7906
|
-
node: event.target,
|
|
7907
|
-
message: `<input> is missing recommended "type" attribute`
|
|
7908
|
-
});
|
|
7909
|
-
}
|
|
7910
|
-
});
|
|
7911
|
-
}
|
|
7912
|
-
}
|
|
7913
|
-
|
|
7914
7788
|
class NoImplicitClose extends Rule {
|
|
7915
7789
|
documentation() {
|
|
7916
7790
|
return {
|
|
@@ -7963,6 +7837,30 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7963
7837
|
}
|
|
7964
7838
|
}
|
|
7965
7839
|
|
|
7840
|
+
function isRelevant$1(event) {
|
|
7841
|
+
return event.target.is("input");
|
|
7842
|
+
}
|
|
7843
|
+
class NoImplicitInputType extends Rule {
|
|
7844
|
+
documentation() {
|
|
7845
|
+
return {
|
|
7846
|
+
description: ["`<input>` is missing recommended `type` attribute"].join("\n"),
|
|
7847
|
+
url: "https://html-validate.org/rules/no-implicit-input-type.html"
|
|
7848
|
+
};
|
|
7849
|
+
}
|
|
7850
|
+
setup() {
|
|
7851
|
+
this.on("element:ready", isRelevant$1, (event) => {
|
|
7852
|
+
const { target } = event;
|
|
7853
|
+
const attr = target.getAttribute("type");
|
|
7854
|
+
if (!attr) {
|
|
7855
|
+
this.report({
|
|
7856
|
+
node: event.target,
|
|
7857
|
+
message: `<input> is missing recommended "type" attribute`
|
|
7858
|
+
});
|
|
7859
|
+
}
|
|
7860
|
+
});
|
|
7861
|
+
}
|
|
7862
|
+
}
|
|
7863
|
+
|
|
7966
7864
|
const defaults$e = {
|
|
7967
7865
|
include: null,
|
|
7968
7866
|
exclude: null,
|
|
@@ -8372,10 +8270,9 @@ class NoSelfClosing extends Rule {
|
|
|
8372
8270
|
}
|
|
8373
8271
|
};
|
|
8374
8272
|
}
|
|
8375
|
-
documentation(
|
|
8376
|
-
tagName = tagName || "element";
|
|
8273
|
+
documentation(context) {
|
|
8377
8274
|
return {
|
|
8378
|
-
description: `Self-closing elements are disallowed. Use regular end tag <${
|
|
8275
|
+
description: `Self-closing elements are disallowed. Use regular end tag <${context}></${context}> instead of self-closing <${context}/>.`,
|
|
8379
8276
|
url: "https://html-validate.org/rules/no-self-closing.html"
|
|
8380
8277
|
};
|
|
8381
8278
|
}
|
|
@@ -8953,7 +8850,7 @@ class ScriptElement extends Rule {
|
|
|
8953
8850
|
setup() {
|
|
8954
8851
|
this.on("tag:end", (event) => {
|
|
8955
8852
|
const node = event.target;
|
|
8956
|
-
if (
|
|
8853
|
+
if (node?.tagName !== "script") {
|
|
8957
8854
|
return;
|
|
8958
8855
|
}
|
|
8959
8856
|
if (node.closed !== NodeClosed.EndTag) {
|
|
@@ -10166,13 +10063,13 @@ class ValidID extends Rule {
|
|
|
10166
10063
|
}
|
|
10167
10064
|
|
|
10168
10065
|
class VoidContent extends Rule {
|
|
10169
|
-
documentation(
|
|
10066
|
+
documentation(context) {
|
|
10170
10067
|
const doc = {
|
|
10171
10068
|
description: "HTML void elements cannot have any content and must not have content or end tag.",
|
|
10172
10069
|
url: "https://html-validate.org/rules/void-content.html"
|
|
10173
10070
|
};
|
|
10174
|
-
if (
|
|
10175
|
-
doc.description = `<${
|
|
10071
|
+
if (context) {
|
|
10072
|
+
doc.description = `<${context}> is a void element and must not have content or end tag.`;
|
|
10176
10073
|
}
|
|
10177
10074
|
return doc;
|
|
10178
10075
|
}
|
|
@@ -10475,7 +10372,7 @@ class H37 extends Rule {
|
|
|
10475
10372
|
const defaults$1 = {
|
|
10476
10373
|
strict: false
|
|
10477
10374
|
};
|
|
10478
|
-
const { enum: validScopes } = elements.html5.th.attributes
|
|
10375
|
+
const { enum: validScopes } = elements.html5.th.attributes.scope;
|
|
10479
10376
|
const joinedScopes = utils_naturalJoin.naturalJoin(validScopes);
|
|
10480
10377
|
const td = 0;
|
|
10481
10378
|
const th = 1;
|
|
@@ -10573,7 +10470,7 @@ class H67 extends Rule {
|
|
|
10573
10470
|
setup() {
|
|
10574
10471
|
this.on("tag:end", (event) => {
|
|
10575
10472
|
const node = event.target;
|
|
10576
|
-
if (
|
|
10473
|
+
if (node?.tagName !== "img") {
|
|
10577
10474
|
return;
|
|
10578
10475
|
}
|
|
10579
10476
|
const title = node.getAttribute("title");
|
|
@@ -10716,6 +10613,172 @@ const bundledRules = {
|
|
|
10716
10613
|
...bundledRules$1
|
|
10717
10614
|
};
|
|
10718
10615
|
|
|
10616
|
+
const $schema = "http://json-schema.org/draft-06/schema#";
|
|
10617
|
+
const $id = "https://html-validate.org/schemas/config.json";
|
|
10618
|
+
const type = "object";
|
|
10619
|
+
const additionalProperties = false;
|
|
10620
|
+
const properties = {
|
|
10621
|
+
$schema: {
|
|
10622
|
+
type: "string"
|
|
10623
|
+
},
|
|
10624
|
+
root: {
|
|
10625
|
+
type: "boolean",
|
|
10626
|
+
title: "Mark as root configuration",
|
|
10627
|
+
description: "If this is set to true no further configurations will be searched.",
|
|
10628
|
+
"default": false
|
|
10629
|
+
},
|
|
10630
|
+
"extends": {
|
|
10631
|
+
type: "array",
|
|
10632
|
+
items: {
|
|
10633
|
+
type: "string"
|
|
10634
|
+
},
|
|
10635
|
+
title: "Configurations to extend",
|
|
10636
|
+
description: "Array of shareable or builtin configurations to extend."
|
|
10637
|
+
},
|
|
10638
|
+
elements: {
|
|
10639
|
+
type: "array",
|
|
10640
|
+
items: {
|
|
10641
|
+
anyOf: [
|
|
10642
|
+
{
|
|
10643
|
+
type: "string"
|
|
10644
|
+
},
|
|
10645
|
+
{
|
|
10646
|
+
type: "object"
|
|
10647
|
+
}
|
|
10648
|
+
]
|
|
10649
|
+
},
|
|
10650
|
+
title: "Element metadata to load",
|
|
10651
|
+
description: "Array of modules, plugins or files to load element metadata from. Use <rootDir> to refer to the folder with the package.json file.",
|
|
10652
|
+
examples: [
|
|
10653
|
+
[
|
|
10654
|
+
"html-validate:recommended",
|
|
10655
|
+
"plugin:recommended",
|
|
10656
|
+
"module",
|
|
10657
|
+
"./local-file.json"
|
|
10658
|
+
]
|
|
10659
|
+
]
|
|
10660
|
+
},
|
|
10661
|
+
plugins: {
|
|
10662
|
+
type: "array",
|
|
10663
|
+
items: {
|
|
10664
|
+
anyOf: [
|
|
10665
|
+
{
|
|
10666
|
+
type: "string"
|
|
10667
|
+
},
|
|
10668
|
+
{
|
|
10669
|
+
type: "object"
|
|
10670
|
+
}
|
|
10671
|
+
]
|
|
10672
|
+
},
|
|
10673
|
+
title: "Plugins to load",
|
|
10674
|
+
description: "Array of plugins load. Use <rootDir> to refer to the folder with the package.json file.",
|
|
10675
|
+
examples: [
|
|
10676
|
+
[
|
|
10677
|
+
"my-plugin",
|
|
10678
|
+
"./local-plugin"
|
|
10679
|
+
]
|
|
10680
|
+
]
|
|
10681
|
+
},
|
|
10682
|
+
transform: {
|
|
10683
|
+
type: "object",
|
|
10684
|
+
additionalProperties: {
|
|
10685
|
+
anyOf: [
|
|
10686
|
+
{
|
|
10687
|
+
type: "string"
|
|
10688
|
+
},
|
|
10689
|
+
{
|
|
10690
|
+
"function": true
|
|
10691
|
+
}
|
|
10692
|
+
]
|
|
10693
|
+
},
|
|
10694
|
+
title: "File transformations to use.",
|
|
10695
|
+
description: "Object where key is regular expression to match filename and value is name of transformer or a function.",
|
|
10696
|
+
examples: [
|
|
10697
|
+
{
|
|
10698
|
+
"^.*\\.foo$": "my-transformer",
|
|
10699
|
+
"^.*\\.bar$": "my-plugin",
|
|
10700
|
+
"^.*\\.baz$": "my-plugin:named"
|
|
10701
|
+
}
|
|
10702
|
+
]
|
|
10703
|
+
},
|
|
10704
|
+
rules: {
|
|
10705
|
+
type: "object",
|
|
10706
|
+
patternProperties: {
|
|
10707
|
+
".*": {
|
|
10708
|
+
anyOf: [
|
|
10709
|
+
{
|
|
10710
|
+
"enum": [
|
|
10711
|
+
0,
|
|
10712
|
+
1,
|
|
10713
|
+
2,
|
|
10714
|
+
"off",
|
|
10715
|
+
"warn",
|
|
10716
|
+
"error"
|
|
10717
|
+
]
|
|
10718
|
+
},
|
|
10719
|
+
{
|
|
10720
|
+
type: "array",
|
|
10721
|
+
minItems: 1,
|
|
10722
|
+
maxItems: 1,
|
|
10723
|
+
items: [
|
|
10724
|
+
{
|
|
10725
|
+
"enum": [
|
|
10726
|
+
0,
|
|
10727
|
+
1,
|
|
10728
|
+
2,
|
|
10729
|
+
"off",
|
|
10730
|
+
"warn",
|
|
10731
|
+
"error"
|
|
10732
|
+
]
|
|
10733
|
+
}
|
|
10734
|
+
]
|
|
10735
|
+
},
|
|
10736
|
+
{
|
|
10737
|
+
type: "array",
|
|
10738
|
+
minItems: 2,
|
|
10739
|
+
maxItems: 2,
|
|
10740
|
+
items: [
|
|
10741
|
+
{
|
|
10742
|
+
"enum": [
|
|
10743
|
+
0,
|
|
10744
|
+
1,
|
|
10745
|
+
2,
|
|
10746
|
+
"off",
|
|
10747
|
+
"warn",
|
|
10748
|
+
"error"
|
|
10749
|
+
]
|
|
10750
|
+
},
|
|
10751
|
+
{
|
|
10752
|
+
}
|
|
10753
|
+
]
|
|
10754
|
+
}
|
|
10755
|
+
]
|
|
10756
|
+
}
|
|
10757
|
+
},
|
|
10758
|
+
title: "Rule configuration.",
|
|
10759
|
+
description: "Enable/disable rules, set severity. Some rules have additional configuration like style or patterns to use.",
|
|
10760
|
+
examples: [
|
|
10761
|
+
{
|
|
10762
|
+
foo: "error",
|
|
10763
|
+
bar: "off",
|
|
10764
|
+
baz: [
|
|
10765
|
+
"error",
|
|
10766
|
+
{
|
|
10767
|
+
style: "camelcase"
|
|
10768
|
+
}
|
|
10769
|
+
]
|
|
10770
|
+
}
|
|
10771
|
+
]
|
|
10772
|
+
}
|
|
10773
|
+
};
|
|
10774
|
+
var configurationSchema = {
|
|
10775
|
+
$schema: $schema,
|
|
10776
|
+
$id: $id,
|
|
10777
|
+
type: type,
|
|
10778
|
+
additionalProperties: additionalProperties,
|
|
10779
|
+
properties: properties
|
|
10780
|
+
};
|
|
10781
|
+
|
|
10719
10782
|
function dumpTree(root) {
|
|
10720
10783
|
const lines = [];
|
|
10721
10784
|
function decoration(node) {
|
|
@@ -11851,7 +11914,7 @@ class EventHandler {
|
|
|
11851
11914
|
}
|
|
11852
11915
|
|
|
11853
11916
|
const name = "html-validate";
|
|
11854
|
-
const version = "10.
|
|
11917
|
+
const version = "10.2.1";
|
|
11855
11918
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11856
11919
|
|
|
11857
11920
|
function freeze(src) {
|
|
@@ -12584,9 +12647,9 @@ class Parser {
|
|
|
12584
12647
|
* Trigger close events for any still open elements.
|
|
12585
12648
|
*/
|
|
12586
12649
|
closeTree(source, location) {
|
|
12587
|
-
let active;
|
|
12588
12650
|
const documentElement = this.dom.root;
|
|
12589
|
-
|
|
12651
|
+
let active = this.dom.getActive();
|
|
12652
|
+
while (!active.isRootElement()) {
|
|
12590
12653
|
if (active.meta?.implicitClosed) {
|
|
12591
12654
|
active.closed = NodeClosed.ImplicitClosed;
|
|
12592
12655
|
this.closeElement(source, documentElement, active, location);
|
|
@@ -12594,6 +12657,7 @@ class Parser {
|
|
|
12594
12657
|
this.closeElement(source, null, active, location);
|
|
12595
12658
|
}
|
|
12596
12659
|
this.dom.popActive();
|
|
12660
|
+
active = this.dom.getActive();
|
|
12597
12661
|
}
|
|
12598
12662
|
}
|
|
12599
12663
|
}
|
|
@@ -12960,8 +13024,8 @@ function getUnnamedTransformerFromPlugin(name, plugin) {
|
|
|
12960
13024
|
throw new ConfigError(`Plugin does not expose any transformers`);
|
|
12961
13025
|
}
|
|
12962
13026
|
if (typeof plugin.transformer !== "function") {
|
|
12963
|
-
if (plugin.transformer
|
|
12964
|
-
return plugin.transformer
|
|
13027
|
+
if (plugin.transformer["default"]) {
|
|
13028
|
+
return plugin.transformer["default"];
|
|
12965
13029
|
}
|
|
12966
13030
|
throw new ConfigError(
|
|
12967
13031
|
`Transformer "${name}" refers to unnamed transformer but plugin exposes only named.`
|
|
@@ -13190,7 +13254,7 @@ function checkstyleFormatter(results) {
|
|
|
13190
13254
|
output += "</checkstyle>\n";
|
|
13191
13255
|
return output;
|
|
13192
13256
|
}
|
|
13193
|
-
const formatter$
|
|
13257
|
+
const formatter$2 = checkstyleFormatter;
|
|
13194
13258
|
|
|
13195
13259
|
const defaults = {
|
|
13196
13260
|
showLink: true,
|
|
@@ -13365,7 +13429,7 @@ function codeframe(results, options) {
|
|
|
13365
13429
|
function jsonFormatter(results) {
|
|
13366
13430
|
return JSON.stringify(results);
|
|
13367
13431
|
}
|
|
13368
|
-
const formatter$
|
|
13432
|
+
const formatter$1 = jsonFormatter;
|
|
13369
13433
|
|
|
13370
13434
|
function linkSummary(results) {
|
|
13371
13435
|
const urls = results.reduce((result, it) => {
|
|
@@ -13394,7 +13458,6 @@ function stylish(results) {
|
|
|
13394
13458
|
const links = linkSummary(results);
|
|
13395
13459
|
return `${errors}${links}`;
|
|
13396
13460
|
}
|
|
13397
|
-
const formatter$1 = stylish;
|
|
13398
13461
|
|
|
13399
13462
|
function textFormatter(results) {
|
|
13400
13463
|
let output = "";
|
|
@@ -13424,10 +13487,10 @@ function textFormatter(results) {
|
|
|
13424
13487
|
const formatter = textFormatter;
|
|
13425
13488
|
|
|
13426
13489
|
const availableFormatters = {
|
|
13427
|
-
checkstyle: formatter$
|
|
13490
|
+
checkstyle: formatter$2,
|
|
13428
13491
|
codeframe,
|
|
13429
|
-
json: formatter$
|
|
13430
|
-
stylish
|
|
13492
|
+
json: formatter$1,
|
|
13493
|
+
stylish,
|
|
13431
13494
|
text: formatter
|
|
13432
13495
|
};
|
|
13433
13496
|
function getFormatter(name) {
|