html-validate 10.1.0 → 10.1.2
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 +200 -202
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +370 -315
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/html-validate.js +1 -2
- 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.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/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 +200 -201
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/core-browser.js.map +1 -1
- package/dist/esm/core-nodejs.js.map +1 -1
- package/dist/esm/core.js +371 -316
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/html-validate.js +1 -2
- 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.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/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 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
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";
|
|
@@ -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) {
|
|
@@ -2761,6 +2760,22 @@ class HtmlElement extends DOMNode {
|
|
|
2761
2760
|
}
|
|
2762
2761
|
return this.cacheSet(TABINDEX, parsed);
|
|
2763
2762
|
}
|
|
2763
|
+
/**
|
|
2764
|
+
* Read-only property with the type of the text content of this
|
|
2765
|
+
* element.
|
|
2766
|
+
*
|
|
2767
|
+
* @internal
|
|
2768
|
+
*/
|
|
2769
|
+
get textType() {
|
|
2770
|
+
const tagName = this.tagName.toLowerCase();
|
|
2771
|
+
if (tagName === "script") {
|
|
2772
|
+
return "script";
|
|
2773
|
+
} else if (tagName === "style") {
|
|
2774
|
+
return "css";
|
|
2775
|
+
} else {
|
|
2776
|
+
return "text";
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2764
2779
|
/**
|
|
2765
2780
|
* Get a list of all attributes on this node.
|
|
2766
2781
|
*/
|
|
@@ -3313,172 +3328,6 @@ function parseQuantifier(quantifier) {
|
|
|
3313
3328
|
}
|
|
3314
3329
|
}
|
|
3315
3330
|
|
|
3316
|
-
const $schema = "http://json-schema.org/draft-06/schema#";
|
|
3317
|
-
const $id = "https://html-validate.org/schemas/config.json";
|
|
3318
|
-
const type = "object";
|
|
3319
|
-
const additionalProperties = false;
|
|
3320
|
-
const properties = {
|
|
3321
|
-
$schema: {
|
|
3322
|
-
type: "string"
|
|
3323
|
-
},
|
|
3324
|
-
root: {
|
|
3325
|
-
type: "boolean",
|
|
3326
|
-
title: "Mark as root configuration",
|
|
3327
|
-
description: "If this is set to true no further configurations will be searched.",
|
|
3328
|
-
"default": false
|
|
3329
|
-
},
|
|
3330
|
-
"extends": {
|
|
3331
|
-
type: "array",
|
|
3332
|
-
items: {
|
|
3333
|
-
type: "string"
|
|
3334
|
-
},
|
|
3335
|
-
title: "Configurations to extend",
|
|
3336
|
-
description: "Array of shareable or builtin configurations to extend."
|
|
3337
|
-
},
|
|
3338
|
-
elements: {
|
|
3339
|
-
type: "array",
|
|
3340
|
-
items: {
|
|
3341
|
-
anyOf: [
|
|
3342
|
-
{
|
|
3343
|
-
type: "string"
|
|
3344
|
-
},
|
|
3345
|
-
{
|
|
3346
|
-
type: "object"
|
|
3347
|
-
}
|
|
3348
|
-
]
|
|
3349
|
-
},
|
|
3350
|
-
title: "Element metadata to load",
|
|
3351
|
-
description: "Array of modules, plugins or files to load element metadata from. Use <rootDir> to refer to the folder with the package.json file.",
|
|
3352
|
-
examples: [
|
|
3353
|
-
[
|
|
3354
|
-
"html-validate:recommended",
|
|
3355
|
-
"plugin:recommended",
|
|
3356
|
-
"module",
|
|
3357
|
-
"./local-file.json"
|
|
3358
|
-
]
|
|
3359
|
-
]
|
|
3360
|
-
},
|
|
3361
|
-
plugins: {
|
|
3362
|
-
type: "array",
|
|
3363
|
-
items: {
|
|
3364
|
-
anyOf: [
|
|
3365
|
-
{
|
|
3366
|
-
type: "string"
|
|
3367
|
-
},
|
|
3368
|
-
{
|
|
3369
|
-
type: "object"
|
|
3370
|
-
}
|
|
3371
|
-
]
|
|
3372
|
-
},
|
|
3373
|
-
title: "Plugins to load",
|
|
3374
|
-
description: "Array of plugins load. Use <rootDir> to refer to the folder with the package.json file.",
|
|
3375
|
-
examples: [
|
|
3376
|
-
[
|
|
3377
|
-
"my-plugin",
|
|
3378
|
-
"./local-plugin"
|
|
3379
|
-
]
|
|
3380
|
-
]
|
|
3381
|
-
},
|
|
3382
|
-
transform: {
|
|
3383
|
-
type: "object",
|
|
3384
|
-
additionalProperties: {
|
|
3385
|
-
anyOf: [
|
|
3386
|
-
{
|
|
3387
|
-
type: "string"
|
|
3388
|
-
},
|
|
3389
|
-
{
|
|
3390
|
-
"function": true
|
|
3391
|
-
}
|
|
3392
|
-
]
|
|
3393
|
-
},
|
|
3394
|
-
title: "File transformations to use.",
|
|
3395
|
-
description: "Object where key is regular expression to match filename and value is name of transformer or a function.",
|
|
3396
|
-
examples: [
|
|
3397
|
-
{
|
|
3398
|
-
"^.*\\.foo$": "my-transformer",
|
|
3399
|
-
"^.*\\.bar$": "my-plugin",
|
|
3400
|
-
"^.*\\.baz$": "my-plugin:named"
|
|
3401
|
-
}
|
|
3402
|
-
]
|
|
3403
|
-
},
|
|
3404
|
-
rules: {
|
|
3405
|
-
type: "object",
|
|
3406
|
-
patternProperties: {
|
|
3407
|
-
".*": {
|
|
3408
|
-
anyOf: [
|
|
3409
|
-
{
|
|
3410
|
-
"enum": [
|
|
3411
|
-
0,
|
|
3412
|
-
1,
|
|
3413
|
-
2,
|
|
3414
|
-
"off",
|
|
3415
|
-
"warn",
|
|
3416
|
-
"error"
|
|
3417
|
-
]
|
|
3418
|
-
},
|
|
3419
|
-
{
|
|
3420
|
-
type: "array",
|
|
3421
|
-
minItems: 1,
|
|
3422
|
-
maxItems: 1,
|
|
3423
|
-
items: [
|
|
3424
|
-
{
|
|
3425
|
-
"enum": [
|
|
3426
|
-
0,
|
|
3427
|
-
1,
|
|
3428
|
-
2,
|
|
3429
|
-
"off",
|
|
3430
|
-
"warn",
|
|
3431
|
-
"error"
|
|
3432
|
-
]
|
|
3433
|
-
}
|
|
3434
|
-
]
|
|
3435
|
-
},
|
|
3436
|
-
{
|
|
3437
|
-
type: "array",
|
|
3438
|
-
minItems: 2,
|
|
3439
|
-
maxItems: 2,
|
|
3440
|
-
items: [
|
|
3441
|
-
{
|
|
3442
|
-
"enum": [
|
|
3443
|
-
0,
|
|
3444
|
-
1,
|
|
3445
|
-
2,
|
|
3446
|
-
"off",
|
|
3447
|
-
"warn",
|
|
3448
|
-
"error"
|
|
3449
|
-
]
|
|
3450
|
-
},
|
|
3451
|
-
{
|
|
3452
|
-
}
|
|
3453
|
-
]
|
|
3454
|
-
}
|
|
3455
|
-
]
|
|
3456
|
-
}
|
|
3457
|
-
},
|
|
3458
|
-
title: "Rule configuration.",
|
|
3459
|
-
description: "Enable/disable rules, set severity. Some rules have additional configuration like style or patterns to use.",
|
|
3460
|
-
examples: [
|
|
3461
|
-
{
|
|
3462
|
-
foo: "error",
|
|
3463
|
-
bar: "off",
|
|
3464
|
-
baz: [
|
|
3465
|
-
"error",
|
|
3466
|
-
{
|
|
3467
|
-
style: "camelcase"
|
|
3468
|
-
}
|
|
3469
|
-
]
|
|
3470
|
-
}
|
|
3471
|
-
]
|
|
3472
|
-
}
|
|
3473
|
-
};
|
|
3474
|
-
var configurationSchema = {
|
|
3475
|
-
$schema: $schema,
|
|
3476
|
-
$id: $id,
|
|
3477
|
-
type: type,
|
|
3478
|
-
additionalProperties: additionalProperties,
|
|
3479
|
-
properties: properties
|
|
3480
|
-
};
|
|
3481
|
-
|
|
3482
3331
|
var Severity = /* @__PURE__ */ ((Severity2) => {
|
|
3483
3332
|
Severity2[Severity2["DISABLED"] = 0] = "DISABLED";
|
|
3484
3333
|
Severity2[Severity2["WARN"] = 1] = "WARN";
|
|
@@ -3501,35 +3350,6 @@ function parseSeverity(value) {
|
|
|
3501
3350
|
}
|
|
3502
3351
|
}
|
|
3503
3352
|
|
|
3504
|
-
function escape(value) {
|
|
3505
|
-
return JSON.stringify(value);
|
|
3506
|
-
}
|
|
3507
|
-
function format(value, quote = false) {
|
|
3508
|
-
if (value === null || value === void 0) {
|
|
3509
|
-
return "null";
|
|
3510
|
-
}
|
|
3511
|
-
if (typeof value === "number") {
|
|
3512
|
-
return value.toString();
|
|
3513
|
-
}
|
|
3514
|
-
if (typeof value === "string") {
|
|
3515
|
-
return quote ? escape(value) : value;
|
|
3516
|
-
}
|
|
3517
|
-
if (Array.isArray(value)) {
|
|
3518
|
-
const content = value.map((it) => format(it, true)).join(", ");
|
|
3519
|
-
return `[ ${content} ]`;
|
|
3520
|
-
}
|
|
3521
|
-
if (typeof value === "object") {
|
|
3522
|
-
const content = Object.entries(value).map(([key, nested]) => `${key}: ${format(nested, true)}`).join(", ");
|
|
3523
|
-
return `{ ${content} }`;
|
|
3524
|
-
}
|
|
3525
|
-
return String(value);
|
|
3526
|
-
}
|
|
3527
|
-
function interpolate(text, data) {
|
|
3528
|
-
return text.replace(/{{\s*([^\s{}]+)\s*}}/g, (match, key) => {
|
|
3529
|
-
return typeof data[key] !== "undefined" ? format(data[key]) : match;
|
|
3530
|
-
});
|
|
3531
|
-
}
|
|
3532
|
-
|
|
3533
3353
|
const cacheKey = Symbol("aria-naming");
|
|
3534
3354
|
const defaultValue = "allowed";
|
|
3535
3355
|
const prohibitedRoles = [
|
|
@@ -3571,6 +3391,31 @@ function ariaNaming(element) {
|
|
|
3571
3391
|
return element.cacheSet(cacheKey, byMeta(element, meta));
|
|
3572
3392
|
}
|
|
3573
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
|
+
|
|
3574
3419
|
const patternCache = /* @__PURE__ */ new Map();
|
|
3575
3420
|
function compileStringPattern(pattern) {
|
|
3576
3421
|
const regexp = pattern.replace(/[*]+/g, ".+");
|
|
@@ -3824,6 +3669,35 @@ function partition(values, predicate) {
|
|
|
3824
3669
|
}, initial);
|
|
3825
3670
|
}
|
|
3826
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
|
+
|
|
3827
3701
|
const ajv$1 = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
3828
3702
|
ajv$1.addMetaSchema(ajvSchemaDraft);
|
|
3829
3703
|
function getSchemaValidator(ruleId, properties) {
|
|
@@ -6512,6 +6386,18 @@ const defaults$l = {
|
|
|
6512
6386
|
};
|
|
6513
6387
|
const UNIQUE_CACHE_KEY = Symbol("form-elements-unique");
|
|
6514
6388
|
const SHARED_CACHE_KEY = Symbol("form-elements-shared");
|
|
6389
|
+
function isEnabled(element) {
|
|
6390
|
+
if (isHTMLHidden(element)) {
|
|
6391
|
+
return false;
|
|
6392
|
+
}
|
|
6393
|
+
if (isInert(element)) {
|
|
6394
|
+
return false;
|
|
6395
|
+
}
|
|
6396
|
+
if (isInputDisabled(element)) {
|
|
6397
|
+
return false;
|
|
6398
|
+
}
|
|
6399
|
+
return true;
|
|
6400
|
+
}
|
|
6515
6401
|
function haveName(name) {
|
|
6516
6402
|
return typeof name === "string" && name !== "";
|
|
6517
6403
|
}
|
|
@@ -6582,7 +6468,7 @@ class FormDupName extends Rule {
|
|
|
6582
6468
|
const { shared } = this.options;
|
|
6583
6469
|
this.on("dom:ready", (event) => {
|
|
6584
6470
|
const { document } = event;
|
|
6585
|
-
const controls = document.querySelectorAll(selector);
|
|
6471
|
+
const controls = document.querySelectorAll(selector).filter(isEnabled);
|
|
6586
6472
|
const [sharedControls, uniqueControls] = partition(controls, (it) => {
|
|
6587
6473
|
return allowSharedName(it, shared);
|
|
6588
6474
|
});
|
|
@@ -7338,69 +7224,6 @@ class LongTitle extends Rule {
|
|
|
7338
7224
|
}
|
|
7339
7225
|
}
|
|
7340
7226
|
|
|
7341
|
-
const defaults$h = {
|
|
7342
|
-
allowLongDelay: false
|
|
7343
|
-
};
|
|
7344
|
-
class MetaRefresh extends Rule {
|
|
7345
|
-
constructor(options) {
|
|
7346
|
-
super({ ...defaults$h, ...options });
|
|
7347
|
-
}
|
|
7348
|
-
documentation() {
|
|
7349
|
-
return {
|
|
7350
|
-
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.`,
|
|
7351
|
-
url: "https://html-validate.org/rules/meta-refresh.html"
|
|
7352
|
-
};
|
|
7353
|
-
}
|
|
7354
|
-
setup() {
|
|
7355
|
-
this.on("element:ready", ({ target }) => {
|
|
7356
|
-
if (!target.is("meta")) {
|
|
7357
|
-
return;
|
|
7358
|
-
}
|
|
7359
|
-
const httpEquiv = target.getAttributeValue("http-equiv");
|
|
7360
|
-
if (httpEquiv !== "refresh") {
|
|
7361
|
-
return;
|
|
7362
|
-
}
|
|
7363
|
-
const content = target.getAttribute("content");
|
|
7364
|
-
if (!content?.value || content.isDynamic) {
|
|
7365
|
-
return;
|
|
7366
|
-
}
|
|
7367
|
-
const location = content.valueLocation;
|
|
7368
|
-
const value = parseContent(content.value.toString());
|
|
7369
|
-
if (!value) {
|
|
7370
|
-
this.report(target, "Malformed meta refresh directive", location);
|
|
7371
|
-
return;
|
|
7372
|
-
}
|
|
7373
|
-
const { delay, url } = value;
|
|
7374
|
-
this.validateDelay(target, location, delay, url);
|
|
7375
|
-
});
|
|
7376
|
-
}
|
|
7377
|
-
validateDelay(target, location, delay, url) {
|
|
7378
|
-
const { allowLongDelay } = this.options;
|
|
7379
|
-
if (allowLongDelay && delay > 72e3) {
|
|
7380
|
-
return;
|
|
7381
|
-
}
|
|
7382
|
-
if (!url && delay === 0) {
|
|
7383
|
-
this.report(target, "Don't use instant meta refresh to reload the page", location);
|
|
7384
|
-
return;
|
|
7385
|
-
}
|
|
7386
|
-
if (delay !== 0) {
|
|
7387
|
-
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)";
|
|
7388
|
-
this.report(target, message, location);
|
|
7389
|
-
}
|
|
7390
|
-
}
|
|
7391
|
-
}
|
|
7392
|
-
function parseContent(text) {
|
|
7393
|
-
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
7394
|
-
if (match) {
|
|
7395
|
-
return {
|
|
7396
|
-
delay: parseInt(match[1], 10),
|
|
7397
|
-
url: match[2]
|
|
7398
|
-
};
|
|
7399
|
-
} else {
|
|
7400
|
-
return null;
|
|
7401
|
-
}
|
|
7402
|
-
}
|
|
7403
|
-
|
|
7404
7227
|
function getName(attr) {
|
|
7405
7228
|
const name = attr.value;
|
|
7406
7229
|
if (!name || name instanceof DynamicValue) {
|
|
@@ -7463,16 +7286,79 @@ class MapIdName extends Rule {
|
|
|
7463
7286
|
if (!hasStaticValue(id) || !hasStaticValue(name)) {
|
|
7464
7287
|
return;
|
|
7465
7288
|
}
|
|
7466
|
-
if (id.value === name.value) {
|
|
7289
|
+
if (id.value === name.value) {
|
|
7290
|
+
return;
|
|
7291
|
+
}
|
|
7292
|
+
this.report({
|
|
7293
|
+
node: event.target,
|
|
7294
|
+
message: `"id" and "name" attribute must be the same on <map> elements`,
|
|
7295
|
+
location: id.valueLocation ?? name.valueLocation
|
|
7296
|
+
});
|
|
7297
|
+
});
|
|
7298
|
+
}
|
|
7299
|
+
}
|
|
7300
|
+
|
|
7301
|
+
const defaults$h = {
|
|
7302
|
+
allowLongDelay: false
|
|
7303
|
+
};
|
|
7304
|
+
class MetaRefresh extends Rule {
|
|
7305
|
+
constructor(options) {
|
|
7306
|
+
super({ ...defaults$h, ...options });
|
|
7307
|
+
}
|
|
7308
|
+
documentation() {
|
|
7309
|
+
return {
|
|
7310
|
+
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.`,
|
|
7311
|
+
url: "https://html-validate.org/rules/meta-refresh.html"
|
|
7312
|
+
};
|
|
7313
|
+
}
|
|
7314
|
+
setup() {
|
|
7315
|
+
this.on("element:ready", ({ target }) => {
|
|
7316
|
+
if (!target.is("meta")) {
|
|
7317
|
+
return;
|
|
7318
|
+
}
|
|
7319
|
+
const httpEquiv = target.getAttributeValue("http-equiv");
|
|
7320
|
+
if (httpEquiv !== "refresh") {
|
|
7321
|
+
return;
|
|
7322
|
+
}
|
|
7323
|
+
const content = target.getAttribute("content");
|
|
7324
|
+
if (!content?.value || content.isDynamic) {
|
|
7325
|
+
return;
|
|
7326
|
+
}
|
|
7327
|
+
const location = content.valueLocation;
|
|
7328
|
+
const value = parseContent(content.value.toString());
|
|
7329
|
+
if (!value) {
|
|
7330
|
+
this.report(target, "Malformed meta refresh directive", location);
|
|
7467
7331
|
return;
|
|
7468
7332
|
}
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
message: `"id" and "name" attribute must be the same on <map> elements`,
|
|
7472
|
-
location: id.valueLocation ?? name.valueLocation
|
|
7473
|
-
});
|
|
7333
|
+
const { delay, url } = value;
|
|
7334
|
+
this.validateDelay(target, location, delay, url);
|
|
7474
7335
|
});
|
|
7475
7336
|
}
|
|
7337
|
+
validateDelay(target, location, delay, url) {
|
|
7338
|
+
const { allowLongDelay } = this.options;
|
|
7339
|
+
if (allowLongDelay && delay > 72e3) {
|
|
7340
|
+
return;
|
|
7341
|
+
}
|
|
7342
|
+
if (!url && delay === 0) {
|
|
7343
|
+
this.report(target, "Don't use instant meta refresh to reload the page", location);
|
|
7344
|
+
return;
|
|
7345
|
+
}
|
|
7346
|
+
if (delay !== 0) {
|
|
7347
|
+
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)";
|
|
7348
|
+
this.report(target, message, location);
|
|
7349
|
+
}
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7352
|
+
function parseContent(text) {
|
|
7353
|
+
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
7354
|
+
if (match) {
|
|
7355
|
+
return {
|
|
7356
|
+
delay: parseInt(match[1], 10),
|
|
7357
|
+
url: match[2]
|
|
7358
|
+
};
|
|
7359
|
+
} else {
|
|
7360
|
+
return null;
|
|
7361
|
+
}
|
|
7476
7362
|
}
|
|
7477
7363
|
|
|
7478
7364
|
class MissingDoctype extends Rule {
|
|
@@ -7871,30 +7757,6 @@ class NoImplicitButtonType extends Rule {
|
|
|
7871
7757
|
}
|
|
7872
7758
|
}
|
|
7873
7759
|
|
|
7874
|
-
function isRelevant$1(event) {
|
|
7875
|
-
return event.target.is("input");
|
|
7876
|
-
}
|
|
7877
|
-
class NoImplicitInputType extends Rule {
|
|
7878
|
-
documentation() {
|
|
7879
|
-
return {
|
|
7880
|
-
description: ["`<input>` is missing recommended `type` attribute"].join("\n"),
|
|
7881
|
-
url: "https://html-validate.org/rules/no-implicit-input-type.html"
|
|
7882
|
-
};
|
|
7883
|
-
}
|
|
7884
|
-
setup() {
|
|
7885
|
-
this.on("element:ready", isRelevant$1, (event) => {
|
|
7886
|
-
const { target } = event;
|
|
7887
|
-
const attr = target.getAttribute("type");
|
|
7888
|
-
if (!attr) {
|
|
7889
|
-
this.report({
|
|
7890
|
-
node: event.target,
|
|
7891
|
-
message: `<input> is missing recommended "type" attribute`
|
|
7892
|
-
});
|
|
7893
|
-
}
|
|
7894
|
-
});
|
|
7895
|
-
}
|
|
7896
|
-
}
|
|
7897
|
-
|
|
7898
7760
|
class NoImplicitClose extends Rule {
|
|
7899
7761
|
documentation() {
|
|
7900
7762
|
return {
|
|
@@ -7947,6 +7809,30 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7947
7809
|
}
|
|
7948
7810
|
}
|
|
7949
7811
|
|
|
7812
|
+
function isRelevant$1(event) {
|
|
7813
|
+
return event.target.is("input");
|
|
7814
|
+
}
|
|
7815
|
+
class NoImplicitInputType extends Rule {
|
|
7816
|
+
documentation() {
|
|
7817
|
+
return {
|
|
7818
|
+
description: ["`<input>` is missing recommended `type` attribute"].join("\n"),
|
|
7819
|
+
url: "https://html-validate.org/rules/no-implicit-input-type.html"
|
|
7820
|
+
};
|
|
7821
|
+
}
|
|
7822
|
+
setup() {
|
|
7823
|
+
this.on("element:ready", isRelevant$1, (event) => {
|
|
7824
|
+
const { target } = event;
|
|
7825
|
+
const attr = target.getAttribute("type");
|
|
7826
|
+
if (!attr) {
|
|
7827
|
+
this.report({
|
|
7828
|
+
node: event.target,
|
|
7829
|
+
message: `<input> is missing recommended "type" attribute`
|
|
7830
|
+
});
|
|
7831
|
+
}
|
|
7832
|
+
});
|
|
7833
|
+
}
|
|
7834
|
+
}
|
|
7835
|
+
|
|
7950
7836
|
const defaults$e = {
|
|
7951
7837
|
include: null,
|
|
7952
7838
|
exclude: null,
|
|
@@ -8177,7 +8063,7 @@ class NoRawCharacters extends Rule {
|
|
|
8177
8063
|
setup() {
|
|
8178
8064
|
this.on("element:ready", (event) => {
|
|
8179
8065
|
const node = event.target;
|
|
8180
|
-
if (node.
|
|
8066
|
+
if (node.textType !== "text") {
|
|
8181
8067
|
return;
|
|
8182
8068
|
}
|
|
8183
8069
|
for (const child of node.childNodes) {
|
|
@@ -9472,6 +9358,9 @@ class UnknownCharReference extends Rule {
|
|
|
9472
9358
|
setup() {
|
|
9473
9359
|
this.on("element:ready", (event) => {
|
|
9474
9360
|
const node = event.target;
|
|
9361
|
+
if (node.textType !== "text") {
|
|
9362
|
+
return;
|
|
9363
|
+
}
|
|
9475
9364
|
for (const child of node.childNodes) {
|
|
9476
9365
|
if (child.nodeType !== NodeType.TEXT_NODE) {
|
|
9477
9366
|
continue;
|
|
@@ -10697,6 +10586,172 @@ const bundledRules = {
|
|
|
10697
10586
|
...bundledRules$1
|
|
10698
10587
|
};
|
|
10699
10588
|
|
|
10589
|
+
const $schema = "http://json-schema.org/draft-06/schema#";
|
|
10590
|
+
const $id = "https://html-validate.org/schemas/config.json";
|
|
10591
|
+
const type = "object";
|
|
10592
|
+
const additionalProperties = false;
|
|
10593
|
+
const properties = {
|
|
10594
|
+
$schema: {
|
|
10595
|
+
type: "string"
|
|
10596
|
+
},
|
|
10597
|
+
root: {
|
|
10598
|
+
type: "boolean",
|
|
10599
|
+
title: "Mark as root configuration",
|
|
10600
|
+
description: "If this is set to true no further configurations will be searched.",
|
|
10601
|
+
"default": false
|
|
10602
|
+
},
|
|
10603
|
+
"extends": {
|
|
10604
|
+
type: "array",
|
|
10605
|
+
items: {
|
|
10606
|
+
type: "string"
|
|
10607
|
+
},
|
|
10608
|
+
title: "Configurations to extend",
|
|
10609
|
+
description: "Array of shareable or builtin configurations to extend."
|
|
10610
|
+
},
|
|
10611
|
+
elements: {
|
|
10612
|
+
type: "array",
|
|
10613
|
+
items: {
|
|
10614
|
+
anyOf: [
|
|
10615
|
+
{
|
|
10616
|
+
type: "string"
|
|
10617
|
+
},
|
|
10618
|
+
{
|
|
10619
|
+
type: "object"
|
|
10620
|
+
}
|
|
10621
|
+
]
|
|
10622
|
+
},
|
|
10623
|
+
title: "Element metadata to load",
|
|
10624
|
+
description: "Array of modules, plugins or files to load element metadata from. Use <rootDir> to refer to the folder with the package.json file.",
|
|
10625
|
+
examples: [
|
|
10626
|
+
[
|
|
10627
|
+
"html-validate:recommended",
|
|
10628
|
+
"plugin:recommended",
|
|
10629
|
+
"module",
|
|
10630
|
+
"./local-file.json"
|
|
10631
|
+
]
|
|
10632
|
+
]
|
|
10633
|
+
},
|
|
10634
|
+
plugins: {
|
|
10635
|
+
type: "array",
|
|
10636
|
+
items: {
|
|
10637
|
+
anyOf: [
|
|
10638
|
+
{
|
|
10639
|
+
type: "string"
|
|
10640
|
+
},
|
|
10641
|
+
{
|
|
10642
|
+
type: "object"
|
|
10643
|
+
}
|
|
10644
|
+
]
|
|
10645
|
+
},
|
|
10646
|
+
title: "Plugins to load",
|
|
10647
|
+
description: "Array of plugins load. Use <rootDir> to refer to the folder with the package.json file.",
|
|
10648
|
+
examples: [
|
|
10649
|
+
[
|
|
10650
|
+
"my-plugin",
|
|
10651
|
+
"./local-plugin"
|
|
10652
|
+
]
|
|
10653
|
+
]
|
|
10654
|
+
},
|
|
10655
|
+
transform: {
|
|
10656
|
+
type: "object",
|
|
10657
|
+
additionalProperties: {
|
|
10658
|
+
anyOf: [
|
|
10659
|
+
{
|
|
10660
|
+
type: "string"
|
|
10661
|
+
},
|
|
10662
|
+
{
|
|
10663
|
+
"function": true
|
|
10664
|
+
}
|
|
10665
|
+
]
|
|
10666
|
+
},
|
|
10667
|
+
title: "File transformations to use.",
|
|
10668
|
+
description: "Object where key is regular expression to match filename and value is name of transformer or a function.",
|
|
10669
|
+
examples: [
|
|
10670
|
+
{
|
|
10671
|
+
"^.*\\.foo$": "my-transformer",
|
|
10672
|
+
"^.*\\.bar$": "my-plugin",
|
|
10673
|
+
"^.*\\.baz$": "my-plugin:named"
|
|
10674
|
+
}
|
|
10675
|
+
]
|
|
10676
|
+
},
|
|
10677
|
+
rules: {
|
|
10678
|
+
type: "object",
|
|
10679
|
+
patternProperties: {
|
|
10680
|
+
".*": {
|
|
10681
|
+
anyOf: [
|
|
10682
|
+
{
|
|
10683
|
+
"enum": [
|
|
10684
|
+
0,
|
|
10685
|
+
1,
|
|
10686
|
+
2,
|
|
10687
|
+
"off",
|
|
10688
|
+
"warn",
|
|
10689
|
+
"error"
|
|
10690
|
+
]
|
|
10691
|
+
},
|
|
10692
|
+
{
|
|
10693
|
+
type: "array",
|
|
10694
|
+
minItems: 1,
|
|
10695
|
+
maxItems: 1,
|
|
10696
|
+
items: [
|
|
10697
|
+
{
|
|
10698
|
+
"enum": [
|
|
10699
|
+
0,
|
|
10700
|
+
1,
|
|
10701
|
+
2,
|
|
10702
|
+
"off",
|
|
10703
|
+
"warn",
|
|
10704
|
+
"error"
|
|
10705
|
+
]
|
|
10706
|
+
}
|
|
10707
|
+
]
|
|
10708
|
+
},
|
|
10709
|
+
{
|
|
10710
|
+
type: "array",
|
|
10711
|
+
minItems: 2,
|
|
10712
|
+
maxItems: 2,
|
|
10713
|
+
items: [
|
|
10714
|
+
{
|
|
10715
|
+
"enum": [
|
|
10716
|
+
0,
|
|
10717
|
+
1,
|
|
10718
|
+
2,
|
|
10719
|
+
"off",
|
|
10720
|
+
"warn",
|
|
10721
|
+
"error"
|
|
10722
|
+
]
|
|
10723
|
+
},
|
|
10724
|
+
{
|
|
10725
|
+
}
|
|
10726
|
+
]
|
|
10727
|
+
}
|
|
10728
|
+
]
|
|
10729
|
+
}
|
|
10730
|
+
},
|
|
10731
|
+
title: "Rule configuration.",
|
|
10732
|
+
description: "Enable/disable rules, set severity. Some rules have additional configuration like style or patterns to use.",
|
|
10733
|
+
examples: [
|
|
10734
|
+
{
|
|
10735
|
+
foo: "error",
|
|
10736
|
+
bar: "off",
|
|
10737
|
+
baz: [
|
|
10738
|
+
"error",
|
|
10739
|
+
{
|
|
10740
|
+
style: "camelcase"
|
|
10741
|
+
}
|
|
10742
|
+
]
|
|
10743
|
+
}
|
|
10744
|
+
]
|
|
10745
|
+
}
|
|
10746
|
+
};
|
|
10747
|
+
var configurationSchema = {
|
|
10748
|
+
$schema: $schema,
|
|
10749
|
+
$id: $id,
|
|
10750
|
+
type: type,
|
|
10751
|
+
additionalProperties: additionalProperties,
|
|
10752
|
+
properties: properties
|
|
10753
|
+
};
|
|
10754
|
+
|
|
10700
10755
|
function dumpTree(root) {
|
|
10701
10756
|
const lines = [];
|
|
10702
10757
|
function decoration(node) {
|
|
@@ -11832,7 +11887,7 @@ class EventHandler {
|
|
|
11832
11887
|
}
|
|
11833
11888
|
|
|
11834
11889
|
const name = "html-validate";
|
|
11835
|
-
const version = "10.1.
|
|
11890
|
+
const version = "10.1.2";
|
|
11836
11891
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11837
11892
|
|
|
11838
11893
|
function freeze(src) {
|