html-validate 7.18.0 → 8.0.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 +4 -4
- package/dist/cjs/cli.js +23 -9
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core.js +632 -598
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/html-validate.js +13 -3
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/index.js +5 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/jest-lib.js +2 -2
- package/dist/cjs/jest-lib.js.map +1 -1
- package/dist/cjs/jest.js +3 -3
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/es/browser.js +5 -5
- package/dist/es/cli.js +24 -10
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core.js +628 -576
- package/dist/es/core.js.map +1 -1
- package/dist/es/html-validate.js +13 -4
- package/dist/es/html-validate.js.map +1 -1
- package/dist/es/index.js +5 -5
- package/dist/es/jest-lib.js +2 -2
- package/dist/es/jest-lib.js.map +1 -1
- package/dist/es/jest.js +4 -4
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +343 -91
- package/dist/types/index.d.ts +402 -94
- package/package.json +13 -16
package/dist/cjs/core.js
CHANGED
|
@@ -1,47 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var fs = require('fs');
|
|
4
|
-
var espree = require('espree');
|
|
5
|
-
var walk = require('acorn-walk');
|
|
6
3
|
var path = require('path');
|
|
7
4
|
var semver = require('semver');
|
|
8
5
|
var kleur = require('kleur');
|
|
6
|
+
var fs$1 = require('node:fs');
|
|
7
|
+
var path$1 = require('node:path');
|
|
9
8
|
var Ajv = require('ajv');
|
|
10
9
|
var deepmerge = require('deepmerge');
|
|
11
10
|
var elements = require('./elements.js');
|
|
12
11
|
var rulesHelper = require('./rules-helper.js');
|
|
12
|
+
var fs = require('fs');
|
|
13
13
|
var betterAjvErrors = require('@sidvind/better-ajv-errors');
|
|
14
14
|
var codeFrame = require('@babel/code-frame');
|
|
15
15
|
var stylish$2 = require('@html-validate/stylish');
|
|
16
16
|
|
|
17
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
18
|
|
|
19
|
-
function _interopNamespace(e) {
|
|
20
|
-
if (e && e.__esModule) return e;
|
|
21
|
-
var n = Object.create(null);
|
|
22
|
-
if (e) {
|
|
23
|
-
Object.keys(e).forEach(function (k) {
|
|
24
|
-
if (k !== 'default') {
|
|
25
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
26
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
27
|
-
enumerable: true,
|
|
28
|
-
get: function () { return e[k]; }
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
n.default = e;
|
|
34
|
-
return Object.freeze(n);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
38
|
-
var espree__namespace = /*#__PURE__*/_interopNamespace(espree);
|
|
39
|
-
var walk__namespace = /*#__PURE__*/_interopNamespace(walk);
|
|
40
19
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
41
20
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
42
21
|
var kleur__default = /*#__PURE__*/_interopDefault(kleur);
|
|
22
|
+
var fs__default$1 = /*#__PURE__*/_interopDefault(fs$1);
|
|
23
|
+
var path__default$1 = /*#__PURE__*/_interopDefault(path$1);
|
|
43
24
|
var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
44
25
|
var deepmerge__default = /*#__PURE__*/_interopDefault(deepmerge);
|
|
26
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
45
27
|
var betterAjvErrors__default = /*#__PURE__*/_interopDefault(betterAjvErrors);
|
|
46
28
|
|
|
47
29
|
const $schema$2 = "http://json-schema.org/draft-06/schema#";
|
|
@@ -3188,232 +3170,11 @@ var configurationSchema = {
|
|
|
3188
3170
|
properties: properties
|
|
3189
3171
|
};
|
|
3190
3172
|
|
|
3191
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion -- declarations say
|
|
3192
|
-
* location fields are optional but they are always present when `{loc: true}` */
|
|
3193
|
-
function joinTemplateLiteral(nodes) {
|
|
3194
|
-
let offset = nodes[0].start + 1;
|
|
3195
|
-
let output = "";
|
|
3196
|
-
for (const node of nodes) {
|
|
3197
|
-
output += " ".repeat(node.start + 1 - offset);
|
|
3198
|
-
output += node.value.raw;
|
|
3199
|
-
offset = node.end - 2;
|
|
3200
|
-
}
|
|
3201
|
-
return output;
|
|
3202
|
-
}
|
|
3203
|
-
/**
|
|
3204
|
-
* Compute source offset from line and column and the given markup.
|
|
3205
|
-
*
|
|
3206
|
-
* @param position - Line and column.
|
|
3207
|
-
* @param data - Source markup.
|
|
3208
|
-
* @returns The byte offset into the markup which line and column corresponds to.
|
|
3209
|
-
*/
|
|
3210
|
-
function computeOffset(position, data) {
|
|
3211
|
-
let line = position.line;
|
|
3212
|
-
let column = position.column + 1;
|
|
3213
|
-
for (let i = 0; i < data.length; i++) {
|
|
3214
|
-
if (line > 1) {
|
|
3215
|
-
/* not yet on the correct line */
|
|
3216
|
-
if (data[i] === "\n") {
|
|
3217
|
-
line--;
|
|
3218
|
-
}
|
|
3219
|
-
}
|
|
3220
|
-
else if (column > 1) {
|
|
3221
|
-
/* not yet on the correct column */
|
|
3222
|
-
column--;
|
|
3223
|
-
}
|
|
3224
|
-
else {
|
|
3225
|
-
/* line/column found, return current position */
|
|
3226
|
-
return i;
|
|
3227
|
-
}
|
|
3228
|
-
}
|
|
3229
|
-
/* istanbul ignore next: should never reach this line unless espree passes bad
|
|
3230
|
-
* positions, no sane way to test */
|
|
3231
|
-
throw new Error("Failed to compute location offset from position");
|
|
3232
|
-
}
|
|
3233
|
-
function extractLiteral(node, filename, data) {
|
|
3234
|
-
switch (node.type) {
|
|
3235
|
-
/* ignored nodes */
|
|
3236
|
-
case "FunctionExpression":
|
|
3237
|
-
case "Identifier":
|
|
3238
|
-
return null;
|
|
3239
|
-
case "Literal":
|
|
3240
|
-
if (typeof node.value !== "string") {
|
|
3241
|
-
return null;
|
|
3242
|
-
}
|
|
3243
|
-
return {
|
|
3244
|
-
data: node.value.toString(),
|
|
3245
|
-
filename,
|
|
3246
|
-
line: node.loc.start.line,
|
|
3247
|
-
column: node.loc.start.column + 1,
|
|
3248
|
-
offset: computeOffset(node.loc.start, data) + 1,
|
|
3249
|
-
};
|
|
3250
|
-
case "TemplateLiteral":
|
|
3251
|
-
return {
|
|
3252
|
-
data: joinTemplateLiteral(node.quasis),
|
|
3253
|
-
filename,
|
|
3254
|
-
line: node.loc.start.line,
|
|
3255
|
-
column: node.loc.start.column + 1,
|
|
3256
|
-
offset: computeOffset(node.loc.start, data) + 1,
|
|
3257
|
-
};
|
|
3258
|
-
case "TaggedTemplateExpression":
|
|
3259
|
-
return {
|
|
3260
|
-
data: joinTemplateLiteral(node.quasi.quasis),
|
|
3261
|
-
filename,
|
|
3262
|
-
line: node.quasi.loc.start.line,
|
|
3263
|
-
column: node.quasi.loc.start.column + 1,
|
|
3264
|
-
offset: computeOffset(node.quasi.loc.start, data) + 1,
|
|
3265
|
-
};
|
|
3266
|
-
case "ArrowFunctionExpression": {
|
|
3267
|
-
const whitelist = ["Literal", "TemplateLiteral"];
|
|
3268
|
-
if (whitelist.includes(node.body.type)) {
|
|
3269
|
-
return extractLiteral(node.body, filename, data);
|
|
3270
|
-
}
|
|
3271
|
-
else {
|
|
3272
|
-
return null;
|
|
3273
|
-
}
|
|
3274
|
-
}
|
|
3275
|
-
/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
|
|
3276
|
-
default: {
|
|
3277
|
-
const loc = node.loc.start;
|
|
3278
|
-
const context = `${filename}:${loc.line}:${loc.column}`;
|
|
3279
|
-
throw new Error(`Unhandled node type "${node.type}" at "${context}" in extractLiteral`);
|
|
3280
|
-
}
|
|
3281
|
-
}
|
|
3282
|
-
}
|
|
3283
|
-
function compareKey(node, key, filename) {
|
|
3284
|
-
switch (node.type) {
|
|
3285
|
-
case "Identifier":
|
|
3286
|
-
return node.name === key;
|
|
3287
|
-
case "Literal":
|
|
3288
|
-
return node.value === key;
|
|
3289
|
-
/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
|
|
3290
|
-
default: {
|
|
3291
|
-
const loc = node.loc.start;
|
|
3292
|
-
const context = `${filename}:${loc.line}:${loc.column}`;
|
|
3293
|
-
throw new Error(`Unhandled node type "${node.type}" at "${context}" in compareKey`);
|
|
3294
|
-
}
|
|
3295
|
-
}
|
|
3296
|
-
}
|
|
3297
|
-
/**
|
|
3298
|
-
* @public
|
|
3299
|
-
*/
|
|
3300
|
-
class TemplateExtractor {
|
|
3301
|
-
constructor(ast, filename, data) {
|
|
3302
|
-
this.ast = ast;
|
|
3303
|
-
this.filename = filename;
|
|
3304
|
-
this.data = data;
|
|
3305
|
-
}
|
|
3306
|
-
static fromFilename(filename) {
|
|
3307
|
-
const source = fs__default.default.readFileSync(filename, "utf-8");
|
|
3308
|
-
const ast = espree__namespace.parse(source, {
|
|
3309
|
-
ecmaVersion: 2017,
|
|
3310
|
-
sourceType: "module",
|
|
3311
|
-
loc: true,
|
|
3312
|
-
});
|
|
3313
|
-
return new TemplateExtractor(ast, filename, source);
|
|
3314
|
-
}
|
|
3315
|
-
/**
|
|
3316
|
-
* Create a new [[TemplateExtractor]] from javascript source code.
|
|
3317
|
-
*
|
|
3318
|
-
* `Source` offsets will be relative to the string, i.e. offset 0 is the first
|
|
3319
|
-
* character of the string. If the string is only a subset of a larger string
|
|
3320
|
-
* the offsets must be adjusted manually.
|
|
3321
|
-
*
|
|
3322
|
-
* @param source - Source code.
|
|
3323
|
-
* @param filename - Optional filename to set in the resulting
|
|
3324
|
-
* `Source`. Defauls to `"inline"`.
|
|
3325
|
-
*/
|
|
3326
|
-
static fromString(source, filename) {
|
|
3327
|
-
const ast = espree__namespace.parse(source, {
|
|
3328
|
-
ecmaVersion: 2017,
|
|
3329
|
-
sourceType: "module",
|
|
3330
|
-
loc: true,
|
|
3331
|
-
});
|
|
3332
|
-
return new TemplateExtractor(ast, filename || "inline", source);
|
|
3333
|
-
}
|
|
3334
|
-
/**
|
|
3335
|
-
* Convenience function to create a [[Source]] instance from an existing file.
|
|
3336
|
-
*
|
|
3337
|
-
* @param filename - Filename with javascript source code. The file must exist
|
|
3338
|
-
* and be readable by the user.
|
|
3339
|
-
* @returns An array of Source's suitable for passing to [[Engine]] linting
|
|
3340
|
-
* functions.
|
|
3341
|
-
*/
|
|
3342
|
-
static createSource(filename) {
|
|
3343
|
-
const data = fs__default.default.readFileSync(filename, "utf-8");
|
|
3344
|
-
return [
|
|
3345
|
-
{
|
|
3346
|
-
column: 1,
|
|
3347
|
-
data,
|
|
3348
|
-
filename,
|
|
3349
|
-
line: 1,
|
|
3350
|
-
offset: 0,
|
|
3351
|
-
},
|
|
3352
|
-
];
|
|
3353
|
-
}
|
|
3354
|
-
/**
|
|
3355
|
-
* Extract object properties.
|
|
3356
|
-
*
|
|
3357
|
-
* Given a key `"template"` this method finds all objects literals with a
|
|
3358
|
-
* `"template"` property and creates a [[Source]] instance with proper offsets
|
|
3359
|
-
* with the value of the property. For instance:
|
|
3360
|
-
*
|
|
3361
|
-
* ```
|
|
3362
|
-
* const myObj = {
|
|
3363
|
-
* foo: 'bar',
|
|
3364
|
-
* };
|
|
3365
|
-
* ```
|
|
3366
|
-
*
|
|
3367
|
-
* The above snippet would yield a `Source` with the content `bar`.
|
|
3368
|
-
*
|
|
3369
|
-
*/
|
|
3370
|
-
extractObjectProperty(key) {
|
|
3371
|
-
const result = [];
|
|
3372
|
-
const { filename, data } = this;
|
|
3373
|
-
const node = this.ast;
|
|
3374
|
-
walk__namespace.simple(node, {
|
|
3375
|
-
Property(node) {
|
|
3376
|
-
if (compareKey(node.key, key, filename)) {
|
|
3377
|
-
const source = extractLiteral(node.value, filename, data);
|
|
3378
|
-
if (source) {
|
|
3379
|
-
source.filename = filename;
|
|
3380
|
-
result.push(source);
|
|
3381
|
-
}
|
|
3382
|
-
}
|
|
3383
|
-
},
|
|
3384
|
-
});
|
|
3385
|
-
return result;
|
|
3386
|
-
}
|
|
3387
|
-
}
|
|
3388
|
-
|
|
3389
3173
|
var TRANSFORMER_API;
|
|
3390
3174
|
(function (TRANSFORMER_API) {
|
|
3391
3175
|
TRANSFORMER_API[TRANSFORMER_API["VERSION"] = 1] = "VERSION";
|
|
3392
3176
|
})(TRANSFORMER_API || (TRANSFORMER_API = {}));
|
|
3393
3177
|
|
|
3394
|
-
/**
|
|
3395
|
-
* Similar to `require(..)` but removes the cached copy first.
|
|
3396
|
-
*/
|
|
3397
|
-
function requireUncached(require, moduleId) {
|
|
3398
|
-
const filename = require.resolve(moduleId);
|
|
3399
|
-
/* remove references from the parent module to prevent memory leak */
|
|
3400
|
-
const m = require.cache[filename];
|
|
3401
|
-
if (m && m.parent) {
|
|
3402
|
-
const { parent } = m;
|
|
3403
|
-
for (let i = parent.children.length - 1; i >= 0; i--) {
|
|
3404
|
-
if (parent.children[i].id === filename) {
|
|
3405
|
-
parent.children.splice(i, 1);
|
|
3406
|
-
}
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
/* remove old module from cache */
|
|
3410
|
-
delete require.cache[filename];
|
|
3411
|
-
/* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
|
|
3412
|
-
return require(filename);
|
|
3413
|
-
}
|
|
3414
|
-
|
|
3415
|
-
const legacyRequire = require;
|
|
3416
|
-
|
|
3417
3178
|
/**
|
|
3418
3179
|
* @public
|
|
3419
3180
|
*/
|
|
@@ -3431,11 +3192,6 @@ function parseSeverity(value) {
|
|
|
3431
3192
|
case 0:
|
|
3432
3193
|
case "off":
|
|
3433
3194
|
return exports.Severity.DISABLED;
|
|
3434
|
-
/* istanbul ignore next: deprecated code which will be removed later */
|
|
3435
|
-
case "disable":
|
|
3436
|
-
// eslint-disable-next-line no-console -- expected to log
|
|
3437
|
-
console.warn(`Deprecated alias "disabled" will be removed, replace with severity "off"`);
|
|
3438
|
-
return exports.Severity.DISABLED;
|
|
3439
3195
|
case 1:
|
|
3440
3196
|
case "warn":
|
|
3441
3197
|
return exports.Severity.WARN;
|
|
@@ -3770,6 +3526,8 @@ class Rule {
|
|
|
3770
3526
|
* Called when requesting additional documentation for a rule. Some rules
|
|
3771
3527
|
* provide additional context to provide context-aware suggestions.
|
|
3772
3528
|
*
|
|
3529
|
+
* @public
|
|
3530
|
+
* @virtual
|
|
3773
3531
|
* @param context - Error context given by a reported error.
|
|
3774
3532
|
* @returns Rule documentation and url with additional details or `null` if no
|
|
3775
3533
|
* additional documentation is available.
|
|
@@ -3780,15 +3538,15 @@ class Rule {
|
|
|
3780
3538
|
}
|
|
3781
3539
|
}
|
|
3782
3540
|
|
|
3783
|
-
var Style$
|
|
3541
|
+
var Style$1;
|
|
3784
3542
|
(function (Style) {
|
|
3785
3543
|
Style["EXTERNAL"] = "external";
|
|
3786
3544
|
Style["RELATIVE_BASE"] = "relative-base";
|
|
3787
3545
|
Style["RELATIVE_PATH"] = "relative-path";
|
|
3788
3546
|
Style["ABSOLUTE"] = "absolute";
|
|
3789
3547
|
Style["ANCHOR"] = "anchor";
|
|
3790
|
-
})(Style$
|
|
3791
|
-
const defaults$
|
|
3548
|
+
})(Style$1 || (Style$1 = {}));
|
|
3549
|
+
const defaults$v = {
|
|
3792
3550
|
allowExternal: true,
|
|
3793
3551
|
allowRelative: true,
|
|
3794
3552
|
allowAbsolute: true,
|
|
@@ -3801,11 +3559,11 @@ const mapping$1 = {
|
|
|
3801
3559
|
script: "src",
|
|
3802
3560
|
};
|
|
3803
3561
|
const description = {
|
|
3804
|
-
[Style$
|
|
3805
|
-
[Style$
|
|
3806
|
-
[Style$
|
|
3807
|
-
[Style$
|
|
3808
|
-
[Style$
|
|
3562
|
+
[Style$1.EXTERNAL]: "External links are not allowed by current configuration.",
|
|
3563
|
+
[Style$1.RELATIVE_BASE]: "Links relative to <base> are not allowed by current configuration.",
|
|
3564
|
+
[Style$1.RELATIVE_PATH]: "Relative links are not allowed by current configuration.",
|
|
3565
|
+
[Style$1.ABSOLUTE]: "Absolute links are not allowed by current configuration.",
|
|
3566
|
+
[Style$1.ANCHOR]: null,
|
|
3809
3567
|
};
|
|
3810
3568
|
function parseAllow(value) {
|
|
3811
3569
|
if (typeof value === "boolean") {
|
|
@@ -3832,7 +3590,7 @@ function matchList(value, list) {
|
|
|
3832
3590
|
}
|
|
3833
3591
|
class AllowedLinks extends Rule {
|
|
3834
3592
|
constructor(options) {
|
|
3835
|
-
super({ ...defaults$
|
|
3593
|
+
super({ ...defaults$v, ...options });
|
|
3836
3594
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3837
3595
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3838
3596
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3878,19 +3636,19 @@ class AllowedLinks extends Rule {
|
|
|
3878
3636
|
const link = event.value.toString();
|
|
3879
3637
|
const style = this.getStyle(link);
|
|
3880
3638
|
switch (style) {
|
|
3881
|
-
case Style$
|
|
3639
|
+
case Style$1.ANCHOR:
|
|
3882
3640
|
/* anchor links are always allowed by this rule */
|
|
3883
3641
|
break;
|
|
3884
|
-
case Style$
|
|
3642
|
+
case Style$1.ABSOLUTE:
|
|
3885
3643
|
this.handleAbsolute(link, event, style);
|
|
3886
3644
|
break;
|
|
3887
|
-
case Style$
|
|
3645
|
+
case Style$1.EXTERNAL:
|
|
3888
3646
|
this.handleExternal(link, event, style);
|
|
3889
3647
|
break;
|
|
3890
|
-
case Style$
|
|
3648
|
+
case Style$1.RELATIVE_BASE:
|
|
3891
3649
|
this.handleRelativeBase(link, event, style);
|
|
3892
3650
|
break;
|
|
3893
|
-
case Style$
|
|
3651
|
+
case Style$1.RELATIVE_PATH:
|
|
3894
3652
|
this.handleRelativePath(link, event, style);
|
|
3895
3653
|
break;
|
|
3896
3654
|
}
|
|
@@ -3908,21 +3666,21 @@ class AllowedLinks extends Rule {
|
|
|
3908
3666
|
getStyle(value) {
|
|
3909
3667
|
/* http://example.net or //example.net */
|
|
3910
3668
|
if (value.match(/^([a-z]+:)?\/\//g)) {
|
|
3911
|
-
return Style$
|
|
3669
|
+
return Style$1.EXTERNAL;
|
|
3912
3670
|
}
|
|
3913
3671
|
switch (value[0]) {
|
|
3914
3672
|
/* /foo/bar */
|
|
3915
3673
|
case "/":
|
|
3916
|
-
return Style$
|
|
3674
|
+
return Style$1.ABSOLUTE;
|
|
3917
3675
|
/* ../foo/bar */
|
|
3918
3676
|
case ".":
|
|
3919
|
-
return Style$
|
|
3677
|
+
return Style$1.RELATIVE_PATH;
|
|
3920
3678
|
/* #foo */
|
|
3921
3679
|
case "#":
|
|
3922
|
-
return Style$
|
|
3680
|
+
return Style$1.ANCHOR;
|
|
3923
3681
|
/* foo/bar */
|
|
3924
3682
|
default:
|
|
3925
|
-
return Style$
|
|
3683
|
+
return Style$1.RELATIVE_BASE;
|
|
3926
3684
|
}
|
|
3927
3685
|
}
|
|
3928
3686
|
handleAbsolute(target, event, style) {
|
|
@@ -3980,7 +3738,7 @@ var RuleContext$1;
|
|
|
3980
3738
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
3981
3739
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
3982
3740
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
3983
|
-
const defaults$
|
|
3741
|
+
const defaults$u = {
|
|
3984
3742
|
accessible: true,
|
|
3985
3743
|
};
|
|
3986
3744
|
function findByTarget(target, siblings) {
|
|
@@ -4018,7 +3776,7 @@ function getDescription$1(context) {
|
|
|
4018
3776
|
}
|
|
4019
3777
|
class AreaAlt extends Rule {
|
|
4020
3778
|
constructor(options) {
|
|
4021
|
-
super({ ...defaults$
|
|
3779
|
+
super({ ...defaults$u, ...options });
|
|
4022
3780
|
}
|
|
4023
3781
|
static schema() {
|
|
4024
3782
|
return {
|
|
@@ -4198,13 +3956,13 @@ class ConfigError extends UserError {
|
|
|
4198
3956
|
}
|
|
4199
3957
|
}
|
|
4200
3958
|
|
|
4201
|
-
const defaults$
|
|
3959
|
+
const defaults$t = {
|
|
4202
3960
|
style: "lowercase",
|
|
4203
3961
|
ignoreForeign: true,
|
|
4204
3962
|
};
|
|
4205
3963
|
class AttrCase extends Rule {
|
|
4206
3964
|
constructor(options) {
|
|
4207
|
-
super({ ...defaults$
|
|
3965
|
+
super({ ...defaults$t, ...options });
|
|
4208
3966
|
this.style = new rulesHelper.CaseStyle(this.options.style, "attr-case");
|
|
4209
3967
|
}
|
|
4210
3968
|
static schema() {
|
|
@@ -4552,7 +4310,7 @@ class AttrDelimiter extends Rule {
|
|
|
4552
4310
|
}
|
|
4553
4311
|
|
|
4554
4312
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4555
|
-
const defaults$
|
|
4313
|
+
const defaults$s = {
|
|
4556
4314
|
pattern: DEFAULT_PATTERN,
|
|
4557
4315
|
ignoreForeign: true,
|
|
4558
4316
|
};
|
|
@@ -4589,7 +4347,7 @@ function generateDescription(name, pattern) {
|
|
|
4589
4347
|
}
|
|
4590
4348
|
class AttrPattern extends Rule {
|
|
4591
4349
|
constructor(options) {
|
|
4592
|
-
super({ ...defaults$
|
|
4350
|
+
super({ ...defaults$s, ...options });
|
|
4593
4351
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4594
4352
|
}
|
|
4595
4353
|
static schema() {
|
|
@@ -4650,7 +4408,7 @@ var QuoteStyle;
|
|
|
4650
4408
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4651
4409
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4652
4410
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4653
|
-
const defaults$
|
|
4411
|
+
const defaults$r = {
|
|
4654
4412
|
style: "auto",
|
|
4655
4413
|
unquoted: false,
|
|
4656
4414
|
};
|
|
@@ -4717,8 +4475,8 @@ class AttrQuotes extends Rule {
|
|
|
4717
4475
|
};
|
|
4718
4476
|
}
|
|
4719
4477
|
constructor(options) {
|
|
4720
|
-
super({ ...defaults$
|
|
4721
|
-
this.style = parseStyle$
|
|
4478
|
+
super({ ...defaults$r, ...options });
|
|
4479
|
+
this.style = parseStyle$3(this.options.style);
|
|
4722
4480
|
}
|
|
4723
4481
|
setup() {
|
|
4724
4482
|
this.on("attr", (event) => {
|
|
@@ -4765,7 +4523,7 @@ class AttrQuotes extends Rule {
|
|
|
4765
4523
|
}
|
|
4766
4524
|
}
|
|
4767
4525
|
}
|
|
4768
|
-
function parseStyle$
|
|
4526
|
+
function parseStyle$3(style) {
|
|
4769
4527
|
switch (style.toLowerCase()) {
|
|
4770
4528
|
case "auto":
|
|
4771
4529
|
return QuoteStyle.AUTO_QUOTE;
|
|
@@ -4887,13 +4645,13 @@ class AttributeAllowedValues extends Rule {
|
|
|
4887
4645
|
}
|
|
4888
4646
|
}
|
|
4889
4647
|
|
|
4890
|
-
const defaults$
|
|
4648
|
+
const defaults$q = {
|
|
4891
4649
|
style: "omit",
|
|
4892
4650
|
};
|
|
4893
4651
|
class AttributeBooleanStyle extends Rule {
|
|
4894
4652
|
constructor(options) {
|
|
4895
|
-
super({ ...defaults$
|
|
4896
|
-
this.hasInvalidStyle = parseStyle$
|
|
4653
|
+
super({ ...defaults$q, ...options });
|
|
4654
|
+
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4897
4655
|
}
|
|
4898
4656
|
static schema() {
|
|
4899
4657
|
return {
|
|
@@ -4941,7 +4699,7 @@ class AttributeBooleanStyle extends Rule {
|
|
|
4941
4699
|
return Boolean((_a = rules[attr.key]) === null || _a === void 0 ? void 0 : _a.boolean);
|
|
4942
4700
|
}
|
|
4943
4701
|
}
|
|
4944
|
-
function parseStyle$
|
|
4702
|
+
function parseStyle$2(style) {
|
|
4945
4703
|
switch (style.toLowerCase()) {
|
|
4946
4704
|
case "omit":
|
|
4947
4705
|
return (attr) => attr.value !== null;
|
|
@@ -4968,13 +4726,13 @@ function reportMessage$1(attr, style) {
|
|
|
4968
4726
|
return "";
|
|
4969
4727
|
}
|
|
4970
4728
|
|
|
4971
|
-
const defaults$
|
|
4729
|
+
const defaults$p = {
|
|
4972
4730
|
style: "omit",
|
|
4973
4731
|
};
|
|
4974
4732
|
class AttributeEmptyStyle extends Rule {
|
|
4975
4733
|
constructor(options) {
|
|
4976
|
-
super({ ...defaults$
|
|
4977
|
-
this.hasInvalidStyle = parseStyle$
|
|
4734
|
+
super({ ...defaults$p, ...options });
|
|
4735
|
+
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
4978
4736
|
}
|
|
4979
4737
|
static schema() {
|
|
4980
4738
|
return {
|
|
@@ -5032,7 +4790,7 @@ function isEmptyValue(attr) {
|
|
|
5032
4790
|
}
|
|
5033
4791
|
return attr.value === null || attr.value === "";
|
|
5034
4792
|
}
|
|
5035
|
-
function parseStyle$
|
|
4793
|
+
function parseStyle$1(style) {
|
|
5036
4794
|
switch (style.toLowerCase()) {
|
|
5037
4795
|
case "omit":
|
|
5038
4796
|
return (attr) => attr.value !== null;
|
|
@@ -5129,12 +4887,12 @@ function describePattern(pattern) {
|
|
|
5129
4887
|
}
|
|
5130
4888
|
}
|
|
5131
4889
|
|
|
5132
|
-
const defaults$
|
|
4890
|
+
const defaults$o = {
|
|
5133
4891
|
pattern: "kebabcase",
|
|
5134
4892
|
};
|
|
5135
4893
|
class ClassPattern extends Rule {
|
|
5136
4894
|
constructor(options) {
|
|
5137
|
-
super({ ...defaults$
|
|
4895
|
+
super({ ...defaults$o, ...options });
|
|
5138
4896
|
this.pattern = parsePattern(this.options.pattern);
|
|
5139
4897
|
}
|
|
5140
4898
|
static schema() {
|
|
@@ -5243,13 +5001,13 @@ class CloseOrder extends Rule {
|
|
|
5243
5001
|
}
|
|
5244
5002
|
}
|
|
5245
5003
|
|
|
5246
|
-
const defaults$
|
|
5004
|
+
const defaults$n = {
|
|
5247
5005
|
include: null,
|
|
5248
5006
|
exclude: null,
|
|
5249
5007
|
};
|
|
5250
5008
|
class Deprecated extends Rule {
|
|
5251
5009
|
constructor(options) {
|
|
5252
|
-
super({ ...defaults$
|
|
5010
|
+
super({ ...defaults$n, ...options });
|
|
5253
5011
|
}
|
|
5254
5012
|
static schema() {
|
|
5255
5013
|
return {
|
|
@@ -5412,12 +5170,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5412
5170
|
}
|
|
5413
5171
|
};
|
|
5414
5172
|
|
|
5415
|
-
const defaults$
|
|
5173
|
+
const defaults$m = {
|
|
5416
5174
|
style: "uppercase",
|
|
5417
5175
|
};
|
|
5418
5176
|
class DoctypeStyle extends Rule {
|
|
5419
5177
|
constructor(options) {
|
|
5420
|
-
super({ ...defaults$
|
|
5178
|
+
super({ ...defaults$m, ...options });
|
|
5421
5179
|
}
|
|
5422
5180
|
static schema() {
|
|
5423
5181
|
return {
|
|
@@ -5449,12 +5207,12 @@ class DoctypeStyle extends Rule {
|
|
|
5449
5207
|
}
|
|
5450
5208
|
}
|
|
5451
5209
|
|
|
5452
|
-
const defaults$
|
|
5210
|
+
const defaults$l = {
|
|
5453
5211
|
style: "lowercase",
|
|
5454
5212
|
};
|
|
5455
5213
|
class ElementCase extends Rule {
|
|
5456
5214
|
constructor(options) {
|
|
5457
|
-
super({ ...defaults$
|
|
5215
|
+
super({ ...defaults$l, ...options });
|
|
5458
5216
|
this.style = new rulesHelper.CaseStyle(this.options.style, "element-case");
|
|
5459
5217
|
}
|
|
5460
5218
|
static schema() {
|
|
@@ -5520,14 +5278,14 @@ class ElementCase extends Rule {
|
|
|
5520
5278
|
}
|
|
5521
5279
|
}
|
|
5522
5280
|
|
|
5523
|
-
const defaults$
|
|
5281
|
+
const defaults$k = {
|
|
5524
5282
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5525
5283
|
whitelist: [],
|
|
5526
5284
|
blacklist: [],
|
|
5527
5285
|
};
|
|
5528
5286
|
class ElementName extends Rule {
|
|
5529
5287
|
constructor(options) {
|
|
5530
|
-
super({ ...defaults$
|
|
5288
|
+
super({ ...defaults$k, ...options });
|
|
5531
5289
|
/* eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp */
|
|
5532
5290
|
this.pattern = new RegExp(this.options.pattern);
|
|
5533
5291
|
}
|
|
@@ -5568,7 +5326,7 @@ class ElementName extends Rule {
|
|
|
5568
5326
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5569
5327
|
];
|
|
5570
5328
|
}
|
|
5571
|
-
if (context.pattern !== defaults$
|
|
5329
|
+
if (context.pattern !== defaults$k.pattern) {
|
|
5572
5330
|
return [
|
|
5573
5331
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5574
5332
|
"",
|
|
@@ -6112,7 +5870,7 @@ class EmptyTitle extends Rule {
|
|
|
6112
5870
|
}
|
|
6113
5871
|
}
|
|
6114
5872
|
|
|
6115
|
-
const defaults$
|
|
5873
|
+
const defaults$j = {
|
|
6116
5874
|
allowArrayBrackets: true,
|
|
6117
5875
|
shared: ["radio", "button", "reset", "submit"],
|
|
6118
5876
|
};
|
|
@@ -6145,7 +5903,7 @@ function getDocumentation(context) {
|
|
|
6145
5903
|
}
|
|
6146
5904
|
class FormDupName extends Rule {
|
|
6147
5905
|
constructor(options) {
|
|
6148
|
-
super({ ...defaults$
|
|
5906
|
+
super({ ...defaults$j, ...options });
|
|
6149
5907
|
}
|
|
6150
5908
|
static schema() {
|
|
6151
5909
|
return {
|
|
@@ -6305,7 +6063,7 @@ class FormDupName extends Rule {
|
|
|
6305
6063
|
}
|
|
6306
6064
|
}
|
|
6307
6065
|
|
|
6308
|
-
const defaults$
|
|
6066
|
+
const defaults$i = {
|
|
6309
6067
|
allowMultipleH1: false,
|
|
6310
6068
|
minInitialRank: "h1",
|
|
6311
6069
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
|
|
@@ -6336,7 +6094,7 @@ function parseMaxInitial(value) {
|
|
|
6336
6094
|
}
|
|
6337
6095
|
class HeadingLevel extends Rule {
|
|
6338
6096
|
constructor(options) {
|
|
6339
|
-
super({ ...defaults$
|
|
6097
|
+
super({ ...defaults$i, ...options });
|
|
6340
6098
|
this.stack = [];
|
|
6341
6099
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
6342
6100
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6494,12 +6252,12 @@ class HeadingLevel extends Rule {
|
|
|
6494
6252
|
}
|
|
6495
6253
|
}
|
|
6496
6254
|
|
|
6497
|
-
const defaults$
|
|
6255
|
+
const defaults$h = {
|
|
6498
6256
|
pattern: "kebabcase",
|
|
6499
6257
|
};
|
|
6500
6258
|
class IdPattern extends Rule {
|
|
6501
6259
|
constructor(options) {
|
|
6502
|
-
super({ ...defaults$
|
|
6260
|
+
super({ ...defaults$h, ...options });
|
|
6503
6261
|
this.pattern = parsePattern(this.options.pattern);
|
|
6504
6262
|
}
|
|
6505
6263
|
static schema() {
|
|
@@ -6781,12 +6539,12 @@ function findLabelByParent(el) {
|
|
|
6781
6539
|
return [];
|
|
6782
6540
|
}
|
|
6783
6541
|
|
|
6784
|
-
const defaults$
|
|
6542
|
+
const defaults$g = {
|
|
6785
6543
|
maxlength: 70,
|
|
6786
6544
|
};
|
|
6787
6545
|
class LongTitle extends Rule {
|
|
6788
6546
|
constructor(options) {
|
|
6789
|
-
super({ ...defaults$
|
|
6547
|
+
super({ ...defaults$g, ...options });
|
|
6790
6548
|
this.maxlength = this.options.maxlength;
|
|
6791
6549
|
}
|
|
6792
6550
|
static schema() {
|
|
@@ -7012,13 +6770,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
7012
6770
|
}
|
|
7013
6771
|
}
|
|
7014
6772
|
|
|
7015
|
-
const defaults$
|
|
6773
|
+
const defaults$f = {
|
|
7016
6774
|
include: null,
|
|
7017
6775
|
exclude: null,
|
|
7018
6776
|
};
|
|
7019
6777
|
class NoAutoplay extends Rule {
|
|
7020
6778
|
constructor(options) {
|
|
7021
|
-
super({ ...defaults$
|
|
6779
|
+
super({ ...defaults$f, ...options });
|
|
7022
6780
|
}
|
|
7023
6781
|
documentation(context) {
|
|
7024
6782
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -7259,14 +7017,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7259
7017
|
}
|
|
7260
7018
|
}
|
|
7261
7019
|
|
|
7262
|
-
const defaults$
|
|
7020
|
+
const defaults$e = {
|
|
7263
7021
|
include: null,
|
|
7264
7022
|
exclude: null,
|
|
7265
7023
|
allowedProperties: ["display"],
|
|
7266
7024
|
};
|
|
7267
7025
|
class NoInlineStyle extends Rule {
|
|
7268
7026
|
constructor(options) {
|
|
7269
|
-
super({ ...defaults$
|
|
7027
|
+
super({ ...defaults$e, ...options });
|
|
7270
7028
|
}
|
|
7271
7029
|
static schema() {
|
|
7272
7030
|
return {
|
|
@@ -7468,7 +7226,7 @@ class NoMultipleMain extends Rule {
|
|
|
7468
7226
|
}
|
|
7469
7227
|
}
|
|
7470
7228
|
|
|
7471
|
-
const defaults$
|
|
7229
|
+
const defaults$d = {
|
|
7472
7230
|
relaxed: false,
|
|
7473
7231
|
};
|
|
7474
7232
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -7485,7 +7243,7 @@ const replacementTable = {
|
|
|
7485
7243
|
};
|
|
7486
7244
|
class NoRawCharacters extends Rule {
|
|
7487
7245
|
constructor(options) {
|
|
7488
|
-
super({ ...defaults$
|
|
7246
|
+
super({ ...defaults$d, ...options });
|
|
7489
7247
|
this.relaxed = this.options.relaxed;
|
|
7490
7248
|
}
|
|
7491
7249
|
static schema() {
|
|
@@ -7663,13 +7421,13 @@ class NoRedundantRole extends Rule {
|
|
|
7663
7421
|
}
|
|
7664
7422
|
|
|
7665
7423
|
const xmlns = /^(.+):.+$/;
|
|
7666
|
-
const defaults$
|
|
7424
|
+
const defaults$c = {
|
|
7667
7425
|
ignoreForeign: true,
|
|
7668
7426
|
ignoreXML: true,
|
|
7669
7427
|
};
|
|
7670
7428
|
class NoSelfClosing extends Rule {
|
|
7671
7429
|
constructor(options) {
|
|
7672
|
-
super({ ...defaults$
|
|
7430
|
+
super({ ...defaults$c, ...options });
|
|
7673
7431
|
}
|
|
7674
7432
|
static schema() {
|
|
7675
7433
|
return {
|
|
@@ -7758,13 +7516,13 @@ class NoTrailingWhitespace extends Rule {
|
|
|
7758
7516
|
}
|
|
7759
7517
|
}
|
|
7760
7518
|
|
|
7761
|
-
const defaults$
|
|
7519
|
+
const defaults$b = {
|
|
7762
7520
|
include: null,
|
|
7763
7521
|
exclude: null,
|
|
7764
7522
|
};
|
|
7765
7523
|
class NoUnknownElements extends Rule {
|
|
7766
7524
|
constructor(options) {
|
|
7767
|
-
super({ ...defaults$
|
|
7525
|
+
super({ ...defaults$b, ...options });
|
|
7768
7526
|
}
|
|
7769
7527
|
static schema() {
|
|
7770
7528
|
return {
|
|
@@ -7876,13 +7634,13 @@ const replacement = {
|
|
|
7876
7634
|
reset: '<button type="reset">',
|
|
7877
7635
|
image: '<button type="button">',
|
|
7878
7636
|
};
|
|
7879
|
-
const defaults$
|
|
7637
|
+
const defaults$a = {
|
|
7880
7638
|
include: null,
|
|
7881
7639
|
exclude: null,
|
|
7882
7640
|
};
|
|
7883
7641
|
class PreferButton extends Rule {
|
|
7884
7642
|
constructor(options) {
|
|
7885
|
-
super({ ...defaults$
|
|
7643
|
+
super({ ...defaults$a, ...options });
|
|
7886
7644
|
}
|
|
7887
7645
|
static schema() {
|
|
7888
7646
|
return {
|
|
@@ -7957,7 +7715,7 @@ class PreferButton extends Rule {
|
|
|
7957
7715
|
}
|
|
7958
7716
|
}
|
|
7959
7717
|
|
|
7960
|
-
const defaults$
|
|
7718
|
+
const defaults$9 = {
|
|
7961
7719
|
mapping: {
|
|
7962
7720
|
article: "article",
|
|
7963
7721
|
banner: "header",
|
|
@@ -7987,7 +7745,7 @@ const defaults$a = {
|
|
|
7987
7745
|
};
|
|
7988
7746
|
class PreferNativeElement extends Rule {
|
|
7989
7747
|
constructor(options) {
|
|
7990
|
-
super({ ...defaults$
|
|
7748
|
+
super({ ...defaults$9, ...options });
|
|
7991
7749
|
}
|
|
7992
7750
|
static schema() {
|
|
7993
7751
|
return {
|
|
@@ -8107,12 +7865,12 @@ class PreferTbody extends Rule {
|
|
|
8107
7865
|
}
|
|
8108
7866
|
}
|
|
8109
7867
|
|
|
8110
|
-
const defaults$
|
|
7868
|
+
const defaults$8 = {
|
|
8111
7869
|
tags: ["script", "style"],
|
|
8112
7870
|
};
|
|
8113
7871
|
class RequireCSPNonce extends Rule {
|
|
8114
7872
|
constructor(options) {
|
|
8115
|
-
super({ ...defaults$
|
|
7873
|
+
super({ ...defaults$8, ...options });
|
|
8116
7874
|
}
|
|
8117
7875
|
static schema() {
|
|
8118
7876
|
return {
|
|
@@ -8163,7 +7921,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8163
7921
|
}
|
|
8164
7922
|
}
|
|
8165
7923
|
|
|
8166
|
-
const defaults$
|
|
7924
|
+
const defaults$7 = {
|
|
8167
7925
|
target: "all",
|
|
8168
7926
|
include: null,
|
|
8169
7927
|
exclude: null,
|
|
@@ -8175,7 +7933,7 @@ const supportSri = {
|
|
|
8175
7933
|
};
|
|
8176
7934
|
class RequireSri extends Rule {
|
|
8177
7935
|
constructor(options) {
|
|
8178
|
-
super({ ...defaults$
|
|
7936
|
+
super({ ...defaults$7, ...options });
|
|
8179
7937
|
this.target = this.options.target;
|
|
8180
7938
|
}
|
|
8181
7939
|
static schema() {
|
|
@@ -8337,7 +8095,7 @@ class SvgFocusable extends Rule {
|
|
|
8337
8095
|
}
|
|
8338
8096
|
}
|
|
8339
8097
|
|
|
8340
|
-
const defaults$
|
|
8098
|
+
const defaults$6 = {
|
|
8341
8099
|
characters: [
|
|
8342
8100
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
8343
8101
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" },
|
|
@@ -8376,7 +8134,7 @@ function matchAll(text, regexp) {
|
|
|
8376
8134
|
}
|
|
8377
8135
|
class TelNonBreaking extends Rule {
|
|
8378
8136
|
constructor(options) {
|
|
8379
|
-
super({ ...defaults$
|
|
8137
|
+
super({ ...defaults$6, ...options });
|
|
8380
8138
|
this.regex = constructRegex(this.options.characters);
|
|
8381
8139
|
}
|
|
8382
8140
|
static schema() {
|
|
@@ -8664,7 +8422,7 @@ class TextContent extends Rule {
|
|
|
8664
8422
|
}
|
|
8665
8423
|
}
|
|
8666
8424
|
|
|
8667
|
-
const defaults$
|
|
8425
|
+
const defaults$5 = {
|
|
8668
8426
|
ignoreCase: false,
|
|
8669
8427
|
requireSemicolon: true,
|
|
8670
8428
|
};
|
|
@@ -8706,7 +8464,7 @@ function getDescription(context, options) {
|
|
|
8706
8464
|
}
|
|
8707
8465
|
class UnknownCharReference extends Rule {
|
|
8708
8466
|
constructor(options) {
|
|
8709
|
-
super({ ...defaults$
|
|
8467
|
+
super({ ...defaults$5, ...options });
|
|
8710
8468
|
}
|
|
8711
8469
|
static schema() {
|
|
8712
8470
|
return {
|
|
@@ -8823,12 +8581,12 @@ var RuleContext;
|
|
|
8823
8581
|
RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
|
|
8824
8582
|
RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
|
|
8825
8583
|
})(RuleContext || (RuleContext = {}));
|
|
8826
|
-
const defaults$
|
|
8584
|
+
const defaults$4 = {
|
|
8827
8585
|
relaxed: false,
|
|
8828
8586
|
};
|
|
8829
8587
|
class ValidID extends Rule {
|
|
8830
8588
|
constructor(options) {
|
|
8831
|
-
super({ ...defaults$
|
|
8589
|
+
super({ ...defaults$4, ...options });
|
|
8832
8590
|
}
|
|
8833
8591
|
static schema() {
|
|
8834
8592
|
return {
|
|
@@ -8905,119 +8663,39 @@ class ValidID extends Rule {
|
|
|
8905
8663
|
}
|
|
8906
8664
|
}
|
|
8907
8665
|
|
|
8908
|
-
|
|
8666
|
+
class VoidContent extends Rule {
|
|
8667
|
+
documentation(tagName) {
|
|
8668
|
+
const doc = {
|
|
8669
|
+
description: "HTML void elements cannot have any content and must not have content or end tag.",
|
|
8670
|
+
url: "https://html-validate.org/rules/void-content.html",
|
|
8671
|
+
};
|
|
8672
|
+
if (tagName) {
|
|
8673
|
+
doc.description = `<${tagName}> is a void element and must not have content or end tag.`;
|
|
8674
|
+
}
|
|
8675
|
+
return doc;
|
|
8676
|
+
}
|
|
8677
|
+
setup() {
|
|
8678
|
+
this.on("tag:end", (event) => {
|
|
8679
|
+
const node = event.target; // The current element being closed.
|
|
8680
|
+
if (!node) {
|
|
8681
|
+
return;
|
|
8682
|
+
}
|
|
8683
|
+
if (!node.voidElement) {
|
|
8684
|
+
return;
|
|
8685
|
+
}
|
|
8686
|
+
if (node.closed === exports.NodeClosed.EndTag) {
|
|
8687
|
+
this.report(null, `End tag for <${node.tagName}> must be omitted`, node.location, node.tagName);
|
|
8688
|
+
}
|
|
8689
|
+
});
|
|
8690
|
+
}
|
|
8691
|
+
}
|
|
8692
|
+
|
|
8693
|
+
var Style;
|
|
8909
8694
|
(function (Style) {
|
|
8910
|
-
Style[Style["Any"] = 0] = "Any";
|
|
8911
8695
|
Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
|
|
8912
8696
|
Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
|
|
8913
|
-
})(Style
|
|
8914
|
-
const defaults$
|
|
8915
|
-
style: "omit",
|
|
8916
|
-
};
|
|
8917
|
-
class Void extends Rule {
|
|
8918
|
-
get deprecated() {
|
|
8919
|
-
return true;
|
|
8920
|
-
}
|
|
8921
|
-
static schema() {
|
|
8922
|
-
return {
|
|
8923
|
-
style: {
|
|
8924
|
-
enum: ["any", "omit", "selfclose", "selfclosing"],
|
|
8925
|
-
type: "string",
|
|
8926
|
-
},
|
|
8927
|
-
};
|
|
8928
|
-
}
|
|
8929
|
-
documentation() {
|
|
8930
|
-
return {
|
|
8931
|
-
description: "HTML void elements cannot have any content and must not have an end tag.",
|
|
8932
|
-
url: "https://html-validate.org/rules/void.html",
|
|
8933
|
-
};
|
|
8934
|
-
}
|
|
8935
|
-
constructor(options) {
|
|
8936
|
-
super({ ...defaults$4, ...options });
|
|
8937
|
-
this.style = parseStyle$1(this.options.style);
|
|
8938
|
-
}
|
|
8939
|
-
setup() {
|
|
8940
|
-
this.on("tag:end", (event) => {
|
|
8941
|
-
const current = event.target; // The current element being closed
|
|
8942
|
-
const active = event.previous; // The current active element (that is, the current element on the stack)
|
|
8943
|
-
if (current && current.meta) {
|
|
8944
|
-
this.validateCurrent(current);
|
|
8945
|
-
}
|
|
8946
|
-
if (active && active.meta) {
|
|
8947
|
-
this.validateActive(active, active.meta);
|
|
8948
|
-
}
|
|
8949
|
-
});
|
|
8950
|
-
}
|
|
8951
|
-
validateCurrent(node) {
|
|
8952
|
-
if (node.voidElement && node.closed === exports.NodeClosed.EndTag) {
|
|
8953
|
-
this.report(null, `End tag for <${node.tagName}> must be omitted`, node.location);
|
|
8954
|
-
}
|
|
8955
|
-
}
|
|
8956
|
-
validateActive(node, meta) {
|
|
8957
|
-
/* ignore foreign elements, they may or may not be self-closed and both are
|
|
8958
|
-
* valid */
|
|
8959
|
-
if (meta.foreign) {
|
|
8960
|
-
return;
|
|
8961
|
-
}
|
|
8962
|
-
const selfOrOmitted = node.closed === exports.NodeClosed.VoidOmitted || node.closed === exports.NodeClosed.VoidSelfClosed;
|
|
8963
|
-
if (node.voidElement) {
|
|
8964
|
-
if (this.style === Style$1.AlwaysOmit && node.closed === exports.NodeClosed.VoidSelfClosed) {
|
|
8965
|
-
this.report(node, `Expected omitted end tag <${node.tagName}> instead of self-closing element <${node.tagName}/>`);
|
|
8966
|
-
}
|
|
8967
|
-
if (this.style === Style$1.AlwaysSelfclose && node.closed === exports.NodeClosed.VoidOmitted) {
|
|
8968
|
-
this.report(node, `Expected self-closing element <${node.tagName}/> instead of omitted end-tag <${node.tagName}>`);
|
|
8969
|
-
}
|
|
8970
|
-
}
|
|
8971
|
-
if (selfOrOmitted && node.voidElement === false) {
|
|
8972
|
-
this.report(node, `End tag for <${node.tagName}> must not be omitted`);
|
|
8973
|
-
}
|
|
8974
|
-
}
|
|
8975
|
-
}
|
|
8976
|
-
function parseStyle$1(name) {
|
|
8977
|
-
switch (name) {
|
|
8978
|
-
case "any":
|
|
8979
|
-
return Style$1.Any;
|
|
8980
|
-
case "omit":
|
|
8981
|
-
return Style$1.AlwaysOmit;
|
|
8982
|
-
case "selfclose":
|
|
8983
|
-
case "selfclosing":
|
|
8984
|
-
return Style$1.AlwaysSelfclose;
|
|
8985
|
-
}
|
|
8986
|
-
}
|
|
8987
|
-
|
|
8988
|
-
class VoidContent extends Rule {
|
|
8989
|
-
documentation(tagName) {
|
|
8990
|
-
const doc = {
|
|
8991
|
-
description: "HTML void elements cannot have any content and must not have content or end tag.",
|
|
8992
|
-
url: "https://html-validate.org/rules/void-content.html",
|
|
8993
|
-
};
|
|
8994
|
-
if (tagName) {
|
|
8995
|
-
doc.description = `<${tagName}> is a void element and must not have content or end tag.`;
|
|
8996
|
-
}
|
|
8997
|
-
return doc;
|
|
8998
|
-
}
|
|
8999
|
-
setup() {
|
|
9000
|
-
this.on("tag:end", (event) => {
|
|
9001
|
-
const node = event.target; // The current element being closed.
|
|
9002
|
-
if (!node) {
|
|
9003
|
-
return;
|
|
9004
|
-
}
|
|
9005
|
-
if (!node.voidElement) {
|
|
9006
|
-
return;
|
|
9007
|
-
}
|
|
9008
|
-
if (node.closed === exports.NodeClosed.EndTag) {
|
|
9009
|
-
this.report(null, `End tag for <${node.tagName}> must be omitted`, node.location, node.tagName);
|
|
9010
|
-
}
|
|
9011
|
-
});
|
|
9012
|
-
}
|
|
9013
|
-
}
|
|
9014
|
-
|
|
9015
|
-
var Style;
|
|
9016
|
-
(function (Style) {
|
|
9017
|
-
Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
|
|
9018
|
-
Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
|
|
9019
|
-
})(Style || (Style = {}));
|
|
9020
|
-
const defaults$3 = {
|
|
8697
|
+
})(Style || (Style = {}));
|
|
8698
|
+
const defaults$3 = {
|
|
9021
8699
|
style: "omit",
|
|
9022
8700
|
};
|
|
9023
8701
|
class VoidStyle extends Rule {
|
|
@@ -9486,7 +9164,6 @@ const bundledRules = {
|
|
|
9486
9164
|
"text-content": TextContent,
|
|
9487
9165
|
"unrecognized-char-ref": UnknownCharReference,
|
|
9488
9166
|
"valid-id": ValidID,
|
|
9489
|
-
void: Void,
|
|
9490
9167
|
"void-content": VoidContent,
|
|
9491
9168
|
"void-style": VoidStyle,
|
|
9492
9169
|
...WCAG,
|
|
@@ -9779,7 +9456,112 @@ class ResolvedConfig {
|
|
|
9779
9456
|
}
|
|
9780
9457
|
}
|
|
9781
9458
|
|
|
9782
|
-
|
|
9459
|
+
function haveResolver(key, value) {
|
|
9460
|
+
return key in value;
|
|
9461
|
+
}
|
|
9462
|
+
function haveConfigResolver(value) {
|
|
9463
|
+
return haveResolver("resolveConfig", value);
|
|
9464
|
+
}
|
|
9465
|
+
function haveElementsResolver(value) {
|
|
9466
|
+
return haveResolver("resolveElements", value);
|
|
9467
|
+
}
|
|
9468
|
+
function havePluginResolver(value) {
|
|
9469
|
+
return haveResolver("resolvePlugin", value);
|
|
9470
|
+
}
|
|
9471
|
+
function haveTransformerResolver(value) {
|
|
9472
|
+
return haveResolver("resolveTransformer", value);
|
|
9473
|
+
}
|
|
9474
|
+
/**
|
|
9475
|
+
* @internal
|
|
9476
|
+
*/
|
|
9477
|
+
function resolveConfig(resolvers, id, options) {
|
|
9478
|
+
for (const resolver of resolvers.filter(haveConfigResolver)) {
|
|
9479
|
+
const config = resolver.resolveConfig(id, options);
|
|
9480
|
+
if (config) {
|
|
9481
|
+
return config;
|
|
9482
|
+
}
|
|
9483
|
+
}
|
|
9484
|
+
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
9485
|
+
}
|
|
9486
|
+
/**
|
|
9487
|
+
* @internal
|
|
9488
|
+
*/
|
|
9489
|
+
function resolveElements(resolvers, id, options) {
|
|
9490
|
+
for (const resolver of resolvers.filter(haveElementsResolver)) {
|
|
9491
|
+
const elements = resolver.resolveElements(id, options);
|
|
9492
|
+
if (elements) {
|
|
9493
|
+
return elements;
|
|
9494
|
+
}
|
|
9495
|
+
}
|
|
9496
|
+
throw new UserError(`Failed to load elements from "${id}"`);
|
|
9497
|
+
}
|
|
9498
|
+
/**
|
|
9499
|
+
* @internal
|
|
9500
|
+
*/
|
|
9501
|
+
function resolvePlugin(resolvers, id, options) {
|
|
9502
|
+
for (const resolver of resolvers.filter(havePluginResolver)) {
|
|
9503
|
+
const plugin = resolver.resolvePlugin(id, options);
|
|
9504
|
+
if (plugin) {
|
|
9505
|
+
return plugin;
|
|
9506
|
+
}
|
|
9507
|
+
}
|
|
9508
|
+
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
9509
|
+
}
|
|
9510
|
+
/**
|
|
9511
|
+
* @internal
|
|
9512
|
+
*/
|
|
9513
|
+
function resolveTransformer(resolvers, id, options) {
|
|
9514
|
+
for (const resolver of resolvers.filter(haveTransformerResolver)) {
|
|
9515
|
+
const transformer = resolver.resolveTransformer(id, options);
|
|
9516
|
+
if (transformer) {
|
|
9517
|
+
return transformer;
|
|
9518
|
+
}
|
|
9519
|
+
}
|
|
9520
|
+
throw new UserError(`Failed to load transformer from "${id}"`);
|
|
9521
|
+
}
|
|
9522
|
+
|
|
9523
|
+
/**
|
|
9524
|
+
* Create a new resolver for static content, i.e. plugins or transformers known
|
|
9525
|
+
* at compile time.
|
|
9526
|
+
*
|
|
9527
|
+
* @public
|
|
9528
|
+
* @since 8.0.0
|
|
9529
|
+
*/
|
|
9530
|
+
function staticResolver(map = {}) {
|
|
9531
|
+
const { elements = {}, configs = {}, plugins = {}, transformers = {} } = map;
|
|
9532
|
+
return {
|
|
9533
|
+
name: "static-qresolver",
|
|
9534
|
+
addElements(id, value) {
|
|
9535
|
+
elements[id] = value;
|
|
9536
|
+
},
|
|
9537
|
+
addConfig(id, value) {
|
|
9538
|
+
configs[id] = value;
|
|
9539
|
+
},
|
|
9540
|
+
addPlugin(id, value) {
|
|
9541
|
+
plugins[id] = value;
|
|
9542
|
+
},
|
|
9543
|
+
addTransformer(id, value) {
|
|
9544
|
+
transformers[id] = value;
|
|
9545
|
+
},
|
|
9546
|
+
resolveElements(id) {
|
|
9547
|
+
var _a;
|
|
9548
|
+
return (_a = elements[id]) !== null && _a !== void 0 ? _a : null;
|
|
9549
|
+
},
|
|
9550
|
+
resolveConfig(id) {
|
|
9551
|
+
var _a;
|
|
9552
|
+
return (_a = configs[id]) !== null && _a !== void 0 ? _a : null;
|
|
9553
|
+
},
|
|
9554
|
+
resolvePlugin(id) {
|
|
9555
|
+
var _a;
|
|
9556
|
+
return (_a = plugins[id]) !== null && _a !== void 0 ? _a : null;
|
|
9557
|
+
},
|
|
9558
|
+
resolveTransformer(id) {
|
|
9559
|
+
var _a;
|
|
9560
|
+
return (_a = transformers[id]) !== null && _a !== void 0 ? _a : null;
|
|
9561
|
+
},
|
|
9562
|
+
};
|
|
9563
|
+
}
|
|
9564
|
+
|
|
9783
9565
|
const ajv = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
9784
9566
|
ajv.addMetaSchema(ajvSchemaDraft);
|
|
9785
9567
|
const validator = ajv.compile(configurationSchema);
|
|
@@ -9802,30 +9584,13 @@ function mergeInternal(base, rhs) {
|
|
|
9802
9584
|
}
|
|
9803
9585
|
return dst;
|
|
9804
9586
|
}
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
/* load using require as it can process both js and json */
|
|
9812
|
-
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, should be refactored into something more typesafe */
|
|
9813
|
-
json = requireUncached(legacyRequire, filename);
|
|
9814
|
-
}
|
|
9815
|
-
catch (err) {
|
|
9816
|
-
throw new ConfigError(`Failed to read configuration from "${filename}"`, ensureError(err));
|
|
9817
|
-
}
|
|
9818
|
-
/* expand any relative paths */
|
|
9819
|
-
for (const key of ["extends", "elements", "plugins"]) {
|
|
9820
|
-
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, should be refactored into something more typesafe */
|
|
9821
|
-
const value = json[key];
|
|
9822
|
-
if (!value)
|
|
9823
|
-
continue;
|
|
9824
|
-
json[key] = value.map((ref) => {
|
|
9825
|
-
return Config.expandRelative(ref, path__default.default.dirname(filename));
|
|
9826
|
-
});
|
|
9587
|
+
function toArray(value) {
|
|
9588
|
+
if (Array.isArray(value)) {
|
|
9589
|
+
return value;
|
|
9590
|
+
}
|
|
9591
|
+
else {
|
|
9592
|
+
return [value];
|
|
9827
9593
|
}
|
|
9828
|
-
return json;
|
|
9829
9594
|
}
|
|
9830
9595
|
/**
|
|
9831
9596
|
* Configuration holder.
|
|
@@ -9839,7 +9604,7 @@ class Config {
|
|
|
9839
9604
|
* Create a new blank configuration. See also `Config.defaultConfig()`.
|
|
9840
9605
|
*/
|
|
9841
9606
|
static empty() {
|
|
9842
|
-
return new Config({
|
|
9607
|
+
return new Config([], {
|
|
9843
9608
|
extends: [],
|
|
9844
9609
|
rules: {},
|
|
9845
9610
|
plugins: [],
|
|
@@ -9849,9 +9614,9 @@ class Config {
|
|
|
9849
9614
|
/**
|
|
9850
9615
|
* Create configuration from object.
|
|
9851
9616
|
*/
|
|
9852
|
-
static fromObject(options, filename = null) {
|
|
9617
|
+
static fromObject(resolvers, options, filename = null) {
|
|
9853
9618
|
Config.validate(options, filename);
|
|
9854
|
-
return new Config(options);
|
|
9619
|
+
return new Config(resolvers, options);
|
|
9855
9620
|
}
|
|
9856
9621
|
/**
|
|
9857
9622
|
* Read configuration from filename.
|
|
@@ -9862,9 +9627,9 @@ class Config {
|
|
|
9862
9627
|
* @internal
|
|
9863
9628
|
* @param filename - The file to read from
|
|
9864
9629
|
*/
|
|
9865
|
-
static fromFile(filename) {
|
|
9866
|
-
const
|
|
9867
|
-
return Config.fromObject(
|
|
9630
|
+
static fromFile(resolvers, filename) {
|
|
9631
|
+
const configData = resolveConfig(toArray(resolvers), filename, { cache: false });
|
|
9632
|
+
return Config.fromObject(resolvers, configData, filename);
|
|
9868
9633
|
}
|
|
9869
9634
|
/**
|
|
9870
9635
|
* Validate configuration data.
|
|
@@ -9894,12 +9659,12 @@ class Config {
|
|
|
9894
9659
|
* Load a default configuration object.
|
|
9895
9660
|
*/
|
|
9896
9661
|
static defaultConfig() {
|
|
9897
|
-
return new Config(defaultConfig);
|
|
9662
|
+
return new Config([], defaultConfig);
|
|
9898
9663
|
}
|
|
9899
9664
|
/**
|
|
9900
9665
|
* @internal
|
|
9901
9666
|
*/
|
|
9902
|
-
constructor(options) {
|
|
9667
|
+
constructor(resolvers, options) {
|
|
9903
9668
|
var _a;
|
|
9904
9669
|
this.transformers = [];
|
|
9905
9670
|
const initial = {
|
|
@@ -9908,10 +9673,10 @@ class Config {
|
|
|
9908
9673
|
rules: {},
|
|
9909
9674
|
transform: {},
|
|
9910
9675
|
};
|
|
9911
|
-
this.config = mergeInternal(initial, options
|
|
9676
|
+
this.config = mergeInternal(initial, options);
|
|
9912
9677
|
this.metaTable = null;
|
|
9913
|
-
this.rootDir = this.findRootDir();
|
|
9914
9678
|
this.initialized = false;
|
|
9679
|
+
this.resolvers = toArray(resolvers);
|
|
9915
9680
|
/* load plugins */
|
|
9916
9681
|
this.plugins = this.loadPlugins(this.config.plugins || []);
|
|
9917
9682
|
this.configurations = this.loadConfigurations(this.plugins);
|
|
@@ -9957,8 +9722,8 @@ class Config {
|
|
|
9957
9722
|
* @public
|
|
9958
9723
|
* @param rhs - Configuration to merge with this one.
|
|
9959
9724
|
*/
|
|
9960
|
-
merge(rhs) {
|
|
9961
|
-
return new Config(mergeInternal(this.config, rhs.config));
|
|
9725
|
+
merge(resolvers, rhs) {
|
|
9726
|
+
return new Config(resolvers, mergeInternal(this.config, rhs.config));
|
|
9962
9727
|
}
|
|
9963
9728
|
extendConfig(entries) {
|
|
9964
9729
|
if (entries.length === 0) {
|
|
@@ -9972,7 +9737,7 @@ class Config {
|
|
|
9972
9737
|
extended = this.configurations.get(entry);
|
|
9973
9738
|
}
|
|
9974
9739
|
else {
|
|
9975
|
-
extended = Config.fromFile(entry).config;
|
|
9740
|
+
extended = Config.fromFile(this.resolvers, entry).config;
|
|
9976
9741
|
}
|
|
9977
9742
|
base = mergeInternal(base, extended);
|
|
9978
9743
|
}
|
|
@@ -10009,30 +9774,20 @@ class Config {
|
|
|
10009
9774
|
metaTable.loadFromObject(bundled);
|
|
10010
9775
|
continue;
|
|
10011
9776
|
}
|
|
10012
|
-
/*
|
|
10013
|
-
const id = entry.replace("<rootDir>", this.rootDir);
|
|
9777
|
+
/* load with resolver */
|
|
10014
9778
|
try {
|
|
10015
|
-
const data =
|
|
10016
|
-
metaTable.loadFromObject(data,
|
|
9779
|
+
const data = resolveElements(this.resolvers, entry, { cache: false });
|
|
9780
|
+
metaTable.loadFromObject(data, entry);
|
|
10017
9781
|
}
|
|
10018
9782
|
catch (err) {
|
|
10019
9783
|
/* istanbul ignore next: only used as a fallback */
|
|
10020
9784
|
const message = err instanceof Error ? err.message : String(err);
|
|
10021
|
-
throw new ConfigError(`Failed to load elements from "${
|
|
9785
|
+
throw new ConfigError(`Failed to load elements from "${entry}": ${message}`, ensureError(err));
|
|
10022
9786
|
}
|
|
10023
9787
|
}
|
|
10024
9788
|
metaTable.init();
|
|
10025
9789
|
return (this.metaTable = metaTable);
|
|
10026
9790
|
}
|
|
10027
|
-
/**
|
|
10028
|
-
* @internal exposed for testing only
|
|
10029
|
-
*/
|
|
10030
|
-
static expandRelative(src, currentPath) {
|
|
10031
|
-
if (src[0] === ".") {
|
|
10032
|
-
return path__default.default.normalize(`${currentPath}/${src}`);
|
|
10033
|
-
}
|
|
10034
|
-
return src;
|
|
10035
|
-
}
|
|
10036
9791
|
/**
|
|
10037
9792
|
* Get a copy of internal configuration data.
|
|
10038
9793
|
*
|
|
@@ -10084,7 +9839,7 @@ class Config {
|
|
|
10084
9839
|
return plugin;
|
|
10085
9840
|
}
|
|
10086
9841
|
try {
|
|
10087
|
-
const plugin =
|
|
9842
|
+
const plugin = resolvePlugin(this.resolvers, moduleName, { cache: true });
|
|
10088
9843
|
plugin.name = plugin.name || moduleName;
|
|
10089
9844
|
plugin.originalName = moduleName;
|
|
10090
9845
|
return plugin;
|
|
@@ -10257,57 +10012,7 @@ class Config {
|
|
|
10257
10012
|
return plugin.transformer;
|
|
10258
10013
|
}
|
|
10259
10014
|
getTransformerFromModule(name) {
|
|
10260
|
-
|
|
10261
|
-
const moduleName = name.replace("<rootDir>", this.rootDir);
|
|
10262
|
-
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, the code kinda does the right thing but it should be reflected in the typing too */
|
|
10263
|
-
const fn = legacyRequire(moduleName);
|
|
10264
|
-
/* sanity check */
|
|
10265
|
-
if (typeof fn !== "function") {
|
|
10266
|
-
/* this is not a proper transformer, is it a plugin exposing a transformer? */
|
|
10267
|
-
if (fn.transformer) {
|
|
10268
|
-
throw new ConfigError(`Module is not a valid transformer. This looks like a plugin, did you forget to load the plugin first?`);
|
|
10269
|
-
}
|
|
10270
|
-
throw new ConfigError(`Module is not a valid transformer.`);
|
|
10271
|
-
}
|
|
10272
|
-
return fn;
|
|
10273
|
-
}
|
|
10274
|
-
/**
|
|
10275
|
-
* @internal
|
|
10276
|
-
*/
|
|
10277
|
-
get rootDirCache() {
|
|
10278
|
-
/* return global instance */
|
|
10279
|
-
return rootDirCache;
|
|
10280
|
-
}
|
|
10281
|
-
set rootDirCache(value) {
|
|
10282
|
-
/* set global instance */
|
|
10283
|
-
rootDirCache = value;
|
|
10284
|
-
}
|
|
10285
|
-
/**
|
|
10286
|
-
* @internal
|
|
10287
|
-
*/
|
|
10288
|
-
findRootDir() {
|
|
10289
|
-
const cache = this.rootDirCache;
|
|
10290
|
-
if (cache !== null) {
|
|
10291
|
-
return cache;
|
|
10292
|
-
}
|
|
10293
|
-
/* try to locate package.json */
|
|
10294
|
-
let current = process.cwd();
|
|
10295
|
-
// eslint-disable-next-line no-constant-condition -- break outs when filesystem is traversed
|
|
10296
|
-
while (true) {
|
|
10297
|
-
const search = path__default.default.join(current, "package.json");
|
|
10298
|
-
if (fs__default.default.existsSync(search)) {
|
|
10299
|
-
return (this.rootDirCache = current);
|
|
10300
|
-
}
|
|
10301
|
-
/* get the parent directory */
|
|
10302
|
-
const child = current;
|
|
10303
|
-
current = path__default.default.dirname(current);
|
|
10304
|
-
/* stop if this is the root directory */
|
|
10305
|
-
if (current === child) {
|
|
10306
|
-
break;
|
|
10307
|
-
}
|
|
10308
|
-
}
|
|
10309
|
-
/* default to working directory if no package.json is found */
|
|
10310
|
-
return (this.rootDirCache = process.cwd());
|
|
10015
|
+
return resolveTransformer(this.resolvers, name, { cache: true });
|
|
10311
10016
|
}
|
|
10312
10017
|
}
|
|
10313
10018
|
|
|
@@ -10320,19 +10025,25 @@ class Config {
|
|
|
10320
10025
|
* @public
|
|
10321
10026
|
*/
|
|
10322
10027
|
class ConfigLoader {
|
|
10323
|
-
constructor(
|
|
10324
|
-
const defaults =
|
|
10325
|
-
this.
|
|
10326
|
-
this.globalConfig = defaults.merge(config ? this.loadFromObject(config) : this.defaultConfig());
|
|
10028
|
+
constructor(resolvers, config) {
|
|
10029
|
+
const defaults = Config.empty();
|
|
10030
|
+
this.resolvers = resolvers;
|
|
10031
|
+
this.globalConfig = defaults.merge(this.resolvers, config ? this.loadFromObject(config) : this.defaultConfig());
|
|
10032
|
+
}
|
|
10033
|
+
/**
|
|
10034
|
+
* @internal For testing only
|
|
10035
|
+
*/
|
|
10036
|
+
_getGlobalConfig() {
|
|
10037
|
+
return this.globalConfig.get();
|
|
10327
10038
|
}
|
|
10328
10039
|
empty() {
|
|
10329
|
-
return
|
|
10040
|
+
return Config.empty();
|
|
10330
10041
|
}
|
|
10331
10042
|
loadFromObject(options, filename) {
|
|
10332
|
-
return
|
|
10043
|
+
return Config.fromObject(this.resolvers, options, filename);
|
|
10333
10044
|
}
|
|
10334
10045
|
loadFromFile(filename) {
|
|
10335
|
-
return
|
|
10046
|
+
return Config.fromFile(this.resolvers, filename);
|
|
10336
10047
|
}
|
|
10337
10048
|
}
|
|
10338
10049
|
|
|
@@ -11320,7 +11031,7 @@ class Engine {
|
|
|
11320
11031
|
/**
|
|
11321
11032
|
* Get rule documentation.
|
|
11322
11033
|
*/
|
|
11323
|
-
getRuleDocumentation(ruleId, context) {
|
|
11034
|
+
getRuleDocumentation({ ruleId, context, }) {
|
|
11324
11035
|
const rules = this.config.getRules();
|
|
11325
11036
|
const ruleData = rules.get(ruleId);
|
|
11326
11037
|
if (ruleData) {
|
|
@@ -11557,6 +11268,10 @@ class Engine {
|
|
|
11557
11268
|
}
|
|
11558
11269
|
}
|
|
11559
11270
|
|
|
11271
|
+
const defaultResolvers$1 = [];
|
|
11272
|
+
function hasResolver$1(value) {
|
|
11273
|
+
return Array.isArray(value[0]);
|
|
11274
|
+
}
|
|
11560
11275
|
/**
|
|
11561
11276
|
* The static configuration loader does not do any per-handle lookup. Only the
|
|
11562
11277
|
* global or per-call configuration is used.
|
|
@@ -11567,13 +11282,23 @@ class Engine {
|
|
|
11567
11282
|
* @public
|
|
11568
11283
|
*/
|
|
11569
11284
|
class StaticConfigLoader extends ConfigLoader {
|
|
11285
|
+
constructor(...args) {
|
|
11286
|
+
if (hasResolver$1(args)) {
|
|
11287
|
+
const [resolvers, config] = args;
|
|
11288
|
+
super(resolvers, config);
|
|
11289
|
+
}
|
|
11290
|
+
else {
|
|
11291
|
+
const [config] = args;
|
|
11292
|
+
super(defaultResolvers$1, config);
|
|
11293
|
+
}
|
|
11294
|
+
}
|
|
11570
11295
|
getConfigFor(_handle, configOverride) {
|
|
11571
11296
|
const override = this.loadFromObject(configOverride || {});
|
|
11572
11297
|
if (override.isRootFound()) {
|
|
11573
11298
|
override.init();
|
|
11574
11299
|
return override.resolve();
|
|
11575
11300
|
}
|
|
11576
|
-
const merged = this.globalConfig.merge(override);
|
|
11301
|
+
const merged = this.globalConfig.merge(this.resolvers, override);
|
|
11577
11302
|
merged.init();
|
|
11578
11303
|
return merged.resolve();
|
|
11579
11304
|
}
|
|
@@ -11626,6 +11351,33 @@ class HtmlValidate {
|
|
|
11626
11351
|
};
|
|
11627
11352
|
return this.validateSource(source, options);
|
|
11628
11353
|
}
|
|
11354
|
+
validateStringSync(str, arg1, arg2, arg3) {
|
|
11355
|
+
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11356
|
+
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
11357
|
+
const hooks = isSourceHooks(arg1) ? arg1 : isSourceHooks(arg2) ? arg2 : arg3;
|
|
11358
|
+
const source = {
|
|
11359
|
+
data: str,
|
|
11360
|
+
filename,
|
|
11361
|
+
line: 1,
|
|
11362
|
+
column: 1,
|
|
11363
|
+
offset: 0,
|
|
11364
|
+
hooks,
|
|
11365
|
+
};
|
|
11366
|
+
return this.validateSourceSync(source, options);
|
|
11367
|
+
}
|
|
11368
|
+
/**
|
|
11369
|
+
* Parse and validate HTML from [[Source]].
|
|
11370
|
+
*
|
|
11371
|
+
* @public
|
|
11372
|
+
* @param input - Source to parse.
|
|
11373
|
+
* @returns Report output.
|
|
11374
|
+
*/
|
|
11375
|
+
async validateSource(input, configOverride) {
|
|
11376
|
+
const config = await this.getConfigFor(input.filename, configOverride);
|
|
11377
|
+
const source = config.transformSource(input);
|
|
11378
|
+
const engine = new Engine(config, Parser);
|
|
11379
|
+
return engine.lint(source);
|
|
11380
|
+
}
|
|
11629
11381
|
/**
|
|
11630
11382
|
* Parse and validate HTML from [[Source]].
|
|
11631
11383
|
*
|
|
@@ -11633,8 +11385,8 @@ class HtmlValidate {
|
|
|
11633
11385
|
* @param input - Source to parse.
|
|
11634
11386
|
* @returns Report output.
|
|
11635
11387
|
*/
|
|
11636
|
-
|
|
11637
|
-
const config = this.
|
|
11388
|
+
validateSourceSync(input, configOverride) {
|
|
11389
|
+
const config = this.getConfigForSync(input.filename, configOverride);
|
|
11638
11390
|
const source = config.transformSource(input);
|
|
11639
11391
|
const engine = new Engine(config, Parser);
|
|
11640
11392
|
return engine.lint(source);
|
|
@@ -11646,8 +11398,21 @@ class HtmlValidate {
|
|
|
11646
11398
|
* @param filename - Filename to read and parse.
|
|
11647
11399
|
* @returns Report output.
|
|
11648
11400
|
*/
|
|
11649
|
-
validateFile(filename) {
|
|
11650
|
-
const config = this.getConfigFor(filename);
|
|
11401
|
+
async validateFile(filename) {
|
|
11402
|
+
const config = await this.getConfigFor(filename);
|
|
11403
|
+
const source = config.transformFilename(filename);
|
|
11404
|
+
const engine = new Engine(config, Parser);
|
|
11405
|
+
return Promise.resolve(engine.lint(source));
|
|
11406
|
+
}
|
|
11407
|
+
/**
|
|
11408
|
+
* Parse and validate HTML from file.
|
|
11409
|
+
*
|
|
11410
|
+
* @public
|
|
11411
|
+
* @param filename - Filename to read and parse.
|
|
11412
|
+
* @returns Report output.
|
|
11413
|
+
*/
|
|
11414
|
+
validateFileSync(filename) {
|
|
11415
|
+
const config = this.getConfigForSync(filename);
|
|
11651
11416
|
const source = config.transformFilename(filename);
|
|
11652
11417
|
const engine = new Engine(config, Parser);
|
|
11653
11418
|
return engine.lint(source);
|
|
@@ -11659,8 +11424,19 @@ class HtmlValidate {
|
|
|
11659
11424
|
* @param filenames - Filenames to read and parse.
|
|
11660
11425
|
* @returns Report output.
|
|
11661
11426
|
*/
|
|
11662
|
-
validateMultipleFiles(filenames) {
|
|
11663
|
-
|
|
11427
|
+
async validateMultipleFiles(filenames) {
|
|
11428
|
+
const report = Reporter.merge(filenames.map((filename) => this.validateFileSync(filename)));
|
|
11429
|
+
return Promise.resolve(report);
|
|
11430
|
+
}
|
|
11431
|
+
/**
|
|
11432
|
+
* Parse and validate HTML from multiple files. Result is merged together to a
|
|
11433
|
+
* single report.
|
|
11434
|
+
*
|
|
11435
|
+
* @param filenames - Filenames to read and parse.
|
|
11436
|
+
* @returns Report output.
|
|
11437
|
+
*/
|
|
11438
|
+
validateMultipleFilesSync(filenames) {
|
|
11439
|
+
return Reporter.merge(filenames.map((filename) => this.validateFileSync(filename)));
|
|
11664
11440
|
}
|
|
11665
11441
|
/**
|
|
11666
11442
|
* Returns true if the given filename can be validated.
|
|
@@ -11671,14 +11447,33 @@ class HtmlValidate {
|
|
|
11671
11447
|
* This is mostly useful for tooling to determine whenever to validate the
|
|
11672
11448
|
* file or not. CLI tools will run on all the given files anyway.
|
|
11673
11449
|
*/
|
|
11674
|
-
canValidate(filename) {
|
|
11450
|
+
async canValidate(filename) {
|
|
11675
11451
|
/* .html is always supported */
|
|
11676
11452
|
const extension = path__default.default.extname(filename).toLowerCase();
|
|
11677
11453
|
if (extension === ".html") {
|
|
11678
11454
|
return true;
|
|
11679
11455
|
}
|
|
11680
11456
|
/* test if there is a matching transformer */
|
|
11681
|
-
const config = this.getConfigFor(filename);
|
|
11457
|
+
const config = await this.getConfigFor(filename);
|
|
11458
|
+
return config.canTransform(filename);
|
|
11459
|
+
}
|
|
11460
|
+
/**
|
|
11461
|
+
* Returns true if the given filename can be validated.
|
|
11462
|
+
*
|
|
11463
|
+
* A file is considered to be validatable if the extension is `.html` or if a
|
|
11464
|
+
* transformer matches the filename.
|
|
11465
|
+
*
|
|
11466
|
+
* This is mostly useful for tooling to determine whenever to validate the
|
|
11467
|
+
* file or not. CLI tools will run on all the given files anyway.
|
|
11468
|
+
*/
|
|
11469
|
+
canValidateSync(filename) {
|
|
11470
|
+
/* .html is always supported */
|
|
11471
|
+
const extension = path__default.default.extname(filename).toLowerCase();
|
|
11472
|
+
if (extension === ".html") {
|
|
11473
|
+
return true;
|
|
11474
|
+
}
|
|
11475
|
+
/* test if there is a matching transformer */
|
|
11476
|
+
const config = this.getConfigForSync(filename);
|
|
11682
11477
|
return config.canTransform(filename);
|
|
11683
11478
|
}
|
|
11684
11479
|
/**
|
|
@@ -11691,7 +11486,7 @@ class HtmlValidate {
|
|
|
11691
11486
|
* @param filename - Filename to tokenize.
|
|
11692
11487
|
*/
|
|
11693
11488
|
dumpTokens(filename) {
|
|
11694
|
-
const config = this.
|
|
11489
|
+
const config = this.getConfigForSync(filename);
|
|
11695
11490
|
const source = config.transformFilename(filename);
|
|
11696
11491
|
const engine = new Engine(config, Parser);
|
|
11697
11492
|
return engine.dumpTokens(source);
|
|
@@ -11706,7 +11501,7 @@ class HtmlValidate {
|
|
|
11706
11501
|
* @param filename - Filename to dump events from.
|
|
11707
11502
|
*/
|
|
11708
11503
|
dumpEvents(filename) {
|
|
11709
|
-
const config = this.
|
|
11504
|
+
const config = this.getConfigForSync(filename);
|
|
11710
11505
|
const source = config.transformFilename(filename);
|
|
11711
11506
|
const engine = new Engine(config, Parser);
|
|
11712
11507
|
return engine.dumpEvents(source);
|
|
@@ -11721,7 +11516,7 @@ class HtmlValidate {
|
|
|
11721
11516
|
* @param filename - Filename to dump DOM tree from.
|
|
11722
11517
|
*/
|
|
11723
11518
|
dumpTree(filename) {
|
|
11724
|
-
const config = this.
|
|
11519
|
+
const config = this.getConfigForSync(filename);
|
|
11725
11520
|
const source = config.transformFilename(filename);
|
|
11726
11521
|
const engine = new Engine(config, Parser);
|
|
11727
11522
|
return engine.dumpTree(source);
|
|
@@ -11736,7 +11531,7 @@ class HtmlValidate {
|
|
|
11736
11531
|
* @param filename - Filename to dump source from.
|
|
11737
11532
|
*/
|
|
11738
11533
|
dumpSource(filename) {
|
|
11739
|
-
const config = this.
|
|
11534
|
+
const config = this.getConfigForSync(filename);
|
|
11740
11535
|
const sources = config.transformFilename(filename);
|
|
11741
11536
|
return sources.reduce((result, source) => {
|
|
11742
11537
|
result.push(`Source ${source.filename}@${source.line}:${source.column} (offset: ${source.offset})`);
|
|
@@ -11772,37 +11567,95 @@ class HtmlValidate {
|
|
|
11772
11567
|
* handled by html-validate but the path will be used when resolving
|
|
11773
11568
|
* configuration. As a rule-of-thumb, set it to the elements json file.
|
|
11774
11569
|
*/
|
|
11775
|
-
getElementsSchema(filename) {
|
|
11776
|
-
const config = this.getConfigFor(filename !== null && filename !== void 0 ? filename : "inline");
|
|
11570
|
+
async getElementsSchema(filename) {
|
|
11571
|
+
const config = await this.getConfigFor(filename !== null && filename !== void 0 ? filename : "inline");
|
|
11777
11572
|
const metaTable = config.getMetaTable();
|
|
11778
11573
|
return metaTable.getJSONSchema();
|
|
11779
11574
|
}
|
|
11575
|
+
/**
|
|
11576
|
+
* Get effective metadata element schema.
|
|
11577
|
+
*
|
|
11578
|
+
* If a filename is given the configured plugins can extend the
|
|
11579
|
+
* schema. Filename must not be an existing file or a filetype normally
|
|
11580
|
+
* handled by html-validate but the path will be used when resolving
|
|
11581
|
+
* configuration. As a rule-of-thumb, set it to the elements json file.
|
|
11582
|
+
*/
|
|
11583
|
+
getElementsSchemaSync(filename) {
|
|
11584
|
+
const config = this.getConfigForSync(filename !== null && filename !== void 0 ? filename : "inline");
|
|
11585
|
+
const metaTable = config.getMetaTable();
|
|
11586
|
+
return metaTable.getJSONSchema();
|
|
11587
|
+
}
|
|
11588
|
+
async getContextualDocumentation(message, filenameOrConfig = "inline") {
|
|
11589
|
+
const config = typeof filenameOrConfig === "string"
|
|
11590
|
+
? await this.getConfigFor(filenameOrConfig)
|
|
11591
|
+
: await filenameOrConfig;
|
|
11592
|
+
const engine = new Engine(config, Parser);
|
|
11593
|
+
return engine.getRuleDocumentation(message);
|
|
11594
|
+
}
|
|
11595
|
+
getContextualDocumentationSync(message, filenameOrConfig = "inline") {
|
|
11596
|
+
const config = typeof filenameOrConfig === "string"
|
|
11597
|
+
? this.getConfigForSync(filenameOrConfig)
|
|
11598
|
+
: filenameOrConfig;
|
|
11599
|
+
const engine = new Engine(config, Parser);
|
|
11600
|
+
return engine.getRuleDocumentation(message);
|
|
11601
|
+
}
|
|
11780
11602
|
/**
|
|
11781
11603
|
* Get contextual documentation for the given rule.
|
|
11782
11604
|
*
|
|
11783
11605
|
* Typical usage:
|
|
11784
11606
|
*
|
|
11785
11607
|
* ```js
|
|
11786
|
-
* const report = htmlvalidate.validateFile("my-file.html");
|
|
11608
|
+
* const report = await htmlvalidate.validateFile("my-file.html");
|
|
11787
11609
|
* for (const result of report.results){
|
|
11788
|
-
* const config = htmlvalidate.getConfigFor(result.filePath);
|
|
11610
|
+
* const config = await htmlvalidate.getConfigFor(result.filePath);
|
|
11789
11611
|
* for (const message of result.messages){
|
|
11790
|
-
* const documentation = htmlvalidate.getRuleDocumentation(message.ruleId, config, message.context);
|
|
11612
|
+
* const documentation = await htmlvalidate.getRuleDocumentation(message.ruleId, config, message.context);
|
|
11791
11613
|
* // do something with documentation
|
|
11792
11614
|
* }
|
|
11793
11615
|
* }
|
|
11794
11616
|
* ```
|
|
11795
11617
|
*
|
|
11618
|
+
* @public
|
|
11619
|
+
* @deprecated Deprecated since 8.0.0, use [[getContextualDocumentation]] instead.
|
|
11796
11620
|
* @param ruleId - Rule to get documentation for.
|
|
11797
11621
|
* @param config - If set it provides more accurate description by using the
|
|
11798
11622
|
* correct configuration for the file.
|
|
11799
11623
|
* @param context - If set to `Message.context` some rules can provide
|
|
11800
11624
|
* contextual details and suggestions.
|
|
11801
11625
|
*/
|
|
11802
|
-
getRuleDocumentation(ruleId, config = null, context = null) {
|
|
11626
|
+
async getRuleDocumentation(ruleId, config = null, context = null) {
|
|
11803
11627
|
const c = config || this.getConfigFor("inline");
|
|
11628
|
+
const engine = new Engine(await c, Parser);
|
|
11629
|
+
return engine.getRuleDocumentation({ ruleId, context });
|
|
11630
|
+
}
|
|
11631
|
+
/**
|
|
11632
|
+
* Get contextual documentation for the given rule.
|
|
11633
|
+
*
|
|
11634
|
+
* Typical usage:
|
|
11635
|
+
*
|
|
11636
|
+
* ```js
|
|
11637
|
+
* const report = htmlvalidate.validateFileSync("my-file.html");
|
|
11638
|
+
* for (const result of report.results){
|
|
11639
|
+
* const config = htmlvalidate.getConfigForSync(result.filePath);
|
|
11640
|
+
* for (const message of result.messages){
|
|
11641
|
+
* const documentation = htmlvalidate.getRuleDocumentationSync(message.ruleId, config, message.context);
|
|
11642
|
+
* // do something with documentation
|
|
11643
|
+
* }
|
|
11644
|
+
* }
|
|
11645
|
+
* ```
|
|
11646
|
+
*
|
|
11647
|
+
* @public
|
|
11648
|
+
* @deprecated Deprecated since 8.0.0, use [[getContextualDocumentationSync]] instead.
|
|
11649
|
+
* @param ruleId - Rule to get documentation for.
|
|
11650
|
+
* @param config - If set it provides more accurate description by using the
|
|
11651
|
+
* correct configuration for the file.
|
|
11652
|
+
* @param context - If set to `Message.context` some rules can provide
|
|
11653
|
+
* contextual details and suggestions.
|
|
11654
|
+
*/
|
|
11655
|
+
getRuleDocumentationSync(ruleId, config = null, context = null) {
|
|
11656
|
+
const c = config || this.getConfigForSync("inline");
|
|
11804
11657
|
const engine = new Engine(c, Parser);
|
|
11805
|
-
return engine.getRuleDocumentation(ruleId, context);
|
|
11658
|
+
return engine.getRuleDocumentation({ ruleId, context });
|
|
11806
11659
|
}
|
|
11807
11660
|
/**
|
|
11808
11661
|
* Create a parser configured for given filename.
|
|
@@ -11810,8 +11663,8 @@ class HtmlValidate {
|
|
|
11810
11663
|
* @internal
|
|
11811
11664
|
* @param source - Source to use.
|
|
11812
11665
|
*/
|
|
11813
|
-
getParserFor(source) {
|
|
11814
|
-
const config = this.getConfigFor(source.filename);
|
|
11666
|
+
async getParserFor(source) {
|
|
11667
|
+
const config = await this.getConfigFor(source.filename);
|
|
11815
11668
|
return new Parser(config);
|
|
11816
11669
|
}
|
|
11817
11670
|
/**
|
|
@@ -11825,11 +11678,19 @@ class HtmlValidate {
|
|
|
11825
11678
|
*/
|
|
11826
11679
|
getConfigFor(filename, configOverride) {
|
|
11827
11680
|
const config = this.configLoader.getConfigFor(filename, configOverride);
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11831
|
-
|
|
11832
|
-
|
|
11681
|
+
return Promise.resolve(config);
|
|
11682
|
+
}
|
|
11683
|
+
/**
|
|
11684
|
+
* Get configuration for given filename.
|
|
11685
|
+
*
|
|
11686
|
+
* See [[FileSystemConfigLoader]] for details.
|
|
11687
|
+
*
|
|
11688
|
+
* @public
|
|
11689
|
+
* @param filename - Filename to get configuration for.
|
|
11690
|
+
* @param configOverride - Configuration to apply last.
|
|
11691
|
+
*/
|
|
11692
|
+
getConfigForSync(filename, configOverride) {
|
|
11693
|
+
return this.configLoader.getConfigFor(filename, configOverride);
|
|
11833
11694
|
}
|
|
11834
11695
|
/**
|
|
11835
11696
|
* Flush configuration cache. Clears full cache unless a filename is given.
|
|
@@ -11848,7 +11709,7 @@ class HtmlValidate {
|
|
|
11848
11709
|
/** @public */
|
|
11849
11710
|
const name = "html-validate";
|
|
11850
11711
|
/** @public */
|
|
11851
|
-
const version = "
|
|
11712
|
+
const version = "8.0.0";
|
|
11852
11713
|
/** @public */
|
|
11853
11714
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11854
11715
|
|
|
@@ -11874,6 +11735,7 @@ const defaults$1 = {
|
|
|
11874
11735
|
* option is used a warning is displayed on the console.
|
|
11875
11736
|
*
|
|
11876
11737
|
* @public
|
|
11738
|
+
* @since v5.0.0
|
|
11877
11739
|
* @param name - Name of plugin
|
|
11878
11740
|
* @param declared - What library versions the plugin support (e.g. declared peerDependencies)
|
|
11879
11741
|
* @returns - `true` if version is compatible
|
|
@@ -11894,6 +11756,27 @@ function compatibilityCheck(name, declared, options) {
|
|
|
11894
11756
|
return false;
|
|
11895
11757
|
}
|
|
11896
11758
|
|
|
11759
|
+
/**
|
|
11760
|
+
* Similar to `require(..)` but removes the cached copy first.
|
|
11761
|
+
*/
|
|
11762
|
+
function requireUncached(require, moduleId) {
|
|
11763
|
+
const filename = require.resolve(moduleId);
|
|
11764
|
+
/* remove references from the parent module to prevent memory leak */
|
|
11765
|
+
const m = require.cache[filename];
|
|
11766
|
+
if (m && m.parent) {
|
|
11767
|
+
const { parent } = m;
|
|
11768
|
+
for (let i = parent.children.length - 1; i >= 0; i--) {
|
|
11769
|
+
if (parent.children[i].id === filename) {
|
|
11770
|
+
parent.children.splice(i, 1);
|
|
11771
|
+
}
|
|
11772
|
+
}
|
|
11773
|
+
}
|
|
11774
|
+
/* remove old module from cache */
|
|
11775
|
+
delete require.cache[filename];
|
|
11776
|
+
/* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
|
|
11777
|
+
return require(filename);
|
|
11778
|
+
}
|
|
11779
|
+
|
|
11897
11780
|
const ruleIds = new Set(Object.keys(rules));
|
|
11898
11781
|
/**
|
|
11899
11782
|
* Returns true if given ruleId is an existing builtin rule. It does not handle
|
|
@@ -11910,13 +11793,148 @@ function ruleExists(ruleId) {
|
|
|
11910
11793
|
return ruleIds.has(ruleId);
|
|
11911
11794
|
}
|
|
11912
11795
|
|
|
11796
|
+
const legacyRequire = require;
|
|
11797
|
+
|
|
11798
|
+
let cachedRootDir = null;
|
|
11799
|
+
/**
|
|
11800
|
+
* @internal
|
|
11801
|
+
*/
|
|
11802
|
+
function determineRootDirImpl(intial, fs) {
|
|
11803
|
+
/* try to locate package.json */
|
|
11804
|
+
let current = intial;
|
|
11805
|
+
// eslint-disable-next-line no-constant-condition -- break outs when filesystem is traversed
|
|
11806
|
+
while (true) {
|
|
11807
|
+
const search = path__default$1.default.join(current, "package.json");
|
|
11808
|
+
if (fs.existsSync(search)) {
|
|
11809
|
+
return current;
|
|
11810
|
+
}
|
|
11811
|
+
/* get the parent directory */
|
|
11812
|
+
const child = current;
|
|
11813
|
+
current = path__default$1.default.dirname(current);
|
|
11814
|
+
/* stop if this is the root directory */
|
|
11815
|
+
if (current === child) {
|
|
11816
|
+
break;
|
|
11817
|
+
}
|
|
11818
|
+
}
|
|
11819
|
+
/* default to working directory if no package.json is found */
|
|
11820
|
+
return intial;
|
|
11821
|
+
}
|
|
11913
11822
|
/**
|
|
11823
|
+
* Try to determine root directory based on the location of the closest
|
|
11824
|
+
* `package.json`. Fallbacks on `process.cwd()` if no package.json was found.
|
|
11825
|
+
*
|
|
11914
11826
|
* @internal
|
|
11915
11827
|
*/
|
|
11916
|
-
|
|
11828
|
+
/* istanbul ignore next: cached version of determineRootDirImpl, no need to test */
|
|
11829
|
+
function determineRootDir() {
|
|
11830
|
+
if (cachedRootDir === null) {
|
|
11831
|
+
cachedRootDir = determineRootDirImpl(process.cwd(), fs__default$1.default);
|
|
11832
|
+
}
|
|
11833
|
+
return cachedRootDir;
|
|
11834
|
+
}
|
|
11835
|
+
|
|
11836
|
+
/**
|
|
11837
|
+
* @internal
|
|
11838
|
+
*/
|
|
11839
|
+
function expandRelativePath(value, { cwd }) {
|
|
11840
|
+
if (typeof value === "string" && value[0] === ".") {
|
|
11841
|
+
return path__default$1.default.normalize(path__default$1.default.join(cwd, value));
|
|
11842
|
+
}
|
|
11843
|
+
else {
|
|
11844
|
+
return value;
|
|
11845
|
+
}
|
|
11846
|
+
}
|
|
11847
|
+
|
|
11848
|
+
function isRequireError(error) {
|
|
11849
|
+
return Boolean(error && typeof error === "object" && "code" in error);
|
|
11850
|
+
}
|
|
11851
|
+
function isTransformer(value) {
|
|
11852
|
+
return typeof value === "function";
|
|
11853
|
+
}
|
|
11854
|
+
/**
|
|
11855
|
+
* Create a new resolver for NodeJS packages using `require(..)`.
|
|
11856
|
+
*
|
|
11857
|
+
* If the module name contains `<rootDir>` (e.g. `<rootDir/foo`) it will be
|
|
11858
|
+
* expanded relative to the root directory either explicitly set by the
|
|
11859
|
+
* `rootDir` parameter or determined automatically by the closest `package.json`
|
|
11860
|
+
* file (starting at the current working directory).
|
|
11861
|
+
*
|
|
11862
|
+
* @public
|
|
11863
|
+
* @since 8.0.0
|
|
11864
|
+
*/
|
|
11865
|
+
function nodejsResolver(options = {}) {
|
|
11866
|
+
var _a;
|
|
11867
|
+
const rootDir = (_a = options.rootDir) !== null && _a !== void 0 ? _a : determineRootDir();
|
|
11868
|
+
function internalRequire(id, { cache }) {
|
|
11869
|
+
const moduleName = id.replace("<rootDir>", rootDir);
|
|
11870
|
+
try {
|
|
11871
|
+
/* istanbul ignore else: the tests only runs the cached versions to get
|
|
11872
|
+
* unmodified access to `require`, the implementation of `requireUncached`
|
|
11873
|
+
* is assumed to be tested elsewhere */
|
|
11874
|
+
if (cache) {
|
|
11875
|
+
return legacyRequire(moduleName);
|
|
11876
|
+
}
|
|
11877
|
+
else {
|
|
11878
|
+
return requireUncached(legacyRequire, moduleName);
|
|
11879
|
+
}
|
|
11880
|
+
}
|
|
11881
|
+
catch (err) {
|
|
11882
|
+
if (isRequireError(err) && err.code === "MODULE_NOT_FOUND") {
|
|
11883
|
+
return null;
|
|
11884
|
+
}
|
|
11885
|
+
throw err;
|
|
11886
|
+
}
|
|
11887
|
+
}
|
|
11888
|
+
return {
|
|
11889
|
+
name: "nodejs-resolver",
|
|
11890
|
+
resolveElements(id, options) {
|
|
11891
|
+
return internalRequire(id, options);
|
|
11892
|
+
},
|
|
11893
|
+
resolveConfig(id, options) {
|
|
11894
|
+
var _a, _b, _c;
|
|
11895
|
+
const configData = internalRequire(id, options);
|
|
11896
|
+
if (!configData) {
|
|
11897
|
+
return null;
|
|
11898
|
+
}
|
|
11899
|
+
/* expand any relative paths */
|
|
11900
|
+
const cwd = path__default$1.default.dirname(id);
|
|
11901
|
+
const expand = (value) => expandRelativePath(value, { cwd });
|
|
11902
|
+
configData.elements = (_a = configData.elements) === null || _a === void 0 ? void 0 : _a.map(expand);
|
|
11903
|
+
configData.extends = (_b = configData.extends) === null || _b === void 0 ? void 0 : _b.map(expand);
|
|
11904
|
+
configData.plugins = (_c = configData.plugins) === null || _c === void 0 ? void 0 : _c.map(expand);
|
|
11905
|
+
return configData;
|
|
11906
|
+
},
|
|
11907
|
+
resolvePlugin(id, options) {
|
|
11908
|
+
return internalRequire(id, options);
|
|
11909
|
+
},
|
|
11910
|
+
resolveTransformer(id, options) {
|
|
11911
|
+
const mod = internalRequire(id, options);
|
|
11912
|
+
if (!mod) {
|
|
11913
|
+
return null;
|
|
11914
|
+
}
|
|
11915
|
+
if (isTransformer(mod)) {
|
|
11916
|
+
return mod;
|
|
11917
|
+
}
|
|
11918
|
+
/* this is not a proper transformer, is it a plugin exposing a transformer? */
|
|
11919
|
+
if (mod.transformer) {
|
|
11920
|
+
throw new ConfigError(`Module "${id}" is not a valid transformer. This looks like a plugin, did you forget to load the plugin first?`);
|
|
11921
|
+
}
|
|
11922
|
+
throw new ConfigError(`Module "${id}" is not a valid transformer.`);
|
|
11923
|
+
},
|
|
11924
|
+
};
|
|
11925
|
+
}
|
|
11926
|
+
|
|
11927
|
+
/**
|
|
11928
|
+
* @internal
|
|
11929
|
+
*/
|
|
11930
|
+
function findConfigurationFiles(fs, directory) {
|
|
11917
11931
|
return ["json", "cjs", "js"]
|
|
11918
|
-
.map((extension) => path__default.default.join(directory, `.htmlvalidate.${extension}`))
|
|
11919
|
-
.filter((filePath) =>
|
|
11932
|
+
.map((extension) => path__default$1.default.join(directory, `.htmlvalidate.${extension}`))
|
|
11933
|
+
.filter((filePath) => fs.existsSync(filePath));
|
|
11934
|
+
}
|
|
11935
|
+
const defaultResolvers = [nodejsResolver()];
|
|
11936
|
+
function hasResolver(value) {
|
|
11937
|
+
return Array.isArray(value[0]);
|
|
11920
11938
|
}
|
|
11921
11939
|
/**
|
|
11922
11940
|
* Loads configuration by traversing filesystem.
|
|
@@ -11946,12 +11964,20 @@ function findConfigurationFiles(directory) {
|
|
|
11946
11964
|
* @public
|
|
11947
11965
|
*/
|
|
11948
11966
|
class FileSystemConfigLoader extends ConfigLoader {
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11967
|
+
constructor(...args) {
|
|
11968
|
+
var _a, _b;
|
|
11969
|
+
if (hasResolver(args)) {
|
|
11970
|
+
/* istanbul ignore next */
|
|
11971
|
+
const [resolvers, config, options = {}] = args;
|
|
11972
|
+
super(resolvers, config);
|
|
11973
|
+
this.fs = /* istanbul ignore next */ (_a = options.fs) !== null && _a !== void 0 ? _a : fs__default$1.default;
|
|
11974
|
+
}
|
|
11975
|
+
else {
|
|
11976
|
+
/* istanbul ignore next */
|
|
11977
|
+
const [config, options = {}] = args;
|
|
11978
|
+
super(defaultResolvers, config);
|
|
11979
|
+
this.fs = /* istanbul ignore next */ (_b = options.fs) !== null && _b !== void 0 ? _b : fs__default$1.default;
|
|
11980
|
+
}
|
|
11955
11981
|
this.cache = new Map();
|
|
11956
11982
|
}
|
|
11957
11983
|
/**
|
|
@@ -11971,12 +11997,14 @@ class FileSystemConfigLoader extends ConfigLoader {
|
|
|
11971
11997
|
/* special case when the global configuration is marked as root, should not
|
|
11972
11998
|
* try to load and more configuration files */
|
|
11973
11999
|
if (this.globalConfig.isRootFound()) {
|
|
11974
|
-
const merged = this.globalConfig.merge(override);
|
|
12000
|
+
const merged = this.globalConfig.merge(this.resolvers, override);
|
|
11975
12001
|
merged.init();
|
|
11976
12002
|
return merged.resolve();
|
|
11977
12003
|
}
|
|
11978
12004
|
const config = this.fromFilename(filename);
|
|
11979
|
-
const merged = config
|
|
12005
|
+
const merged = config
|
|
12006
|
+
? config.merge(this.resolvers, override)
|
|
12007
|
+
: this.globalConfig.merge(this.resolvers, override);
|
|
11980
12008
|
merged.init();
|
|
11981
12009
|
return merged.resolve();
|
|
11982
12010
|
}
|
|
@@ -12008,15 +12036,15 @@ class FileSystemConfigLoader extends ConfigLoader {
|
|
|
12008
12036
|
return cache;
|
|
12009
12037
|
}
|
|
12010
12038
|
let found = false;
|
|
12011
|
-
let current = path__default.default.resolve(path__default.default.dirname(filename));
|
|
12039
|
+
let current = path__default$1.default.resolve(path__default$1.default.dirname(filename));
|
|
12012
12040
|
let config = this.empty();
|
|
12013
12041
|
// eslint-disable-next-line no-constant-condition -- it will break out when filesystem is traversed
|
|
12014
12042
|
while (true) {
|
|
12015
12043
|
/* search configuration files in current directory */
|
|
12016
|
-
for (const configFile of findConfigurationFiles(current)) {
|
|
12044
|
+
for (const configFile of findConfigurationFiles(this.fs, current)) {
|
|
12017
12045
|
const local = this.loadFromFile(configFile);
|
|
12018
12046
|
found = true;
|
|
12019
|
-
config = local.merge(config);
|
|
12047
|
+
config = local.merge(this.resolvers, config);
|
|
12020
12048
|
}
|
|
12021
12049
|
/* stop if a configuration with "root" is set to true */
|
|
12022
12050
|
if (config.isRootFound()) {
|
|
@@ -12024,7 +12052,7 @@ class FileSystemConfigLoader extends ConfigLoader {
|
|
|
12024
12052
|
}
|
|
12025
12053
|
/* get the parent directory */
|
|
12026
12054
|
const child = current;
|
|
12027
|
-
current = path__default.default.dirname(current);
|
|
12055
|
+
current = path__default$1.default.dirname(current);
|
|
12028
12056
|
/* stop if this is the root directory */
|
|
12029
12057
|
if (current === child) {
|
|
12030
12058
|
break;
|
|
@@ -12038,8 +12066,14 @@ class FileSystemConfigLoader extends ConfigLoader {
|
|
|
12038
12066
|
this.cache.set(filename, config);
|
|
12039
12067
|
return config;
|
|
12040
12068
|
}
|
|
12069
|
+
/**
|
|
12070
|
+
* @internal For testing only
|
|
12071
|
+
*/
|
|
12072
|
+
_getInternalCache() {
|
|
12073
|
+
return this.cache;
|
|
12074
|
+
}
|
|
12041
12075
|
defaultConfig() {
|
|
12042
|
-
return
|
|
12076
|
+
return Config.defaultConfig();
|
|
12043
12077
|
}
|
|
12044
12078
|
}
|
|
12045
12079
|
|
|
@@ -12316,7 +12350,6 @@ exports.ResolvedConfig = ResolvedConfig;
|
|
|
12316
12350
|
exports.Rule = Rule;
|
|
12317
12351
|
exports.SchemaValidationError = SchemaValidationError;
|
|
12318
12352
|
exports.StaticConfigLoader = StaticConfigLoader;
|
|
12319
|
-
exports.TemplateExtractor = TemplateExtractor;
|
|
12320
12353
|
exports.TextNode = TextNode;
|
|
12321
12354
|
exports.UserError = UserError;
|
|
12322
12355
|
exports.Validator = Validator;
|
|
@@ -12324,7 +12357,6 @@ exports.WrappedError = WrappedError;
|
|
|
12324
12357
|
exports.bugs = bugs;
|
|
12325
12358
|
exports.codeframe = codeframe;
|
|
12326
12359
|
exports.compatibilityCheck = compatibilityCheck;
|
|
12327
|
-
exports.configDataFromFile = configDataFromFile;
|
|
12328
12360
|
exports.definePlugin = definePlugin;
|
|
12329
12361
|
exports.ensureError = ensureError;
|
|
12330
12362
|
exports.generateIdSelector = generateIdSelector;
|
|
@@ -12333,7 +12365,9 @@ exports.isElementNode = isElementNode;
|
|
|
12333
12365
|
exports.isTextNode = isTextNode;
|
|
12334
12366
|
exports.legacyRequire = legacyRequire;
|
|
12335
12367
|
exports.name = name;
|
|
12368
|
+
exports.nodejsResolver = nodejsResolver;
|
|
12336
12369
|
exports.ruleExists = ruleExists;
|
|
12337
12370
|
exports.sliceLocation = sliceLocation;
|
|
12371
|
+
exports.staticResolver = staticResolver;
|
|
12338
12372
|
exports.version = version;
|
|
12339
12373
|
//# sourceMappingURL=core.js.map
|