html-validate 9.2.2 → 9.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/browser.js +1 -2
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/cli.js +7 -3
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js +417 -0
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js +423 -3
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +286 -694
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +30 -0
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/jest-worker.js +6 -6
- package/dist/cjs/jest-worker.js.map +1 -1
- package/dist/cjs/jest.js +1 -1
- package/dist/cjs/vitest.js +2 -2
- package/dist/es/browser.js +2 -3
- package/dist/es/browser.js.map +1 -1
- package/dist/es/cli.js +8 -4
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core-browser.js +418 -2
- package/dist/es/core-browser.js.map +1 -1
- package/dist/es/core-nodejs.js +422 -3
- package/dist/es/core-nodejs.js.map +1 -1
- package/dist/es/core.js +280 -693
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +30 -0
- package/dist/es/elements.js.map +1 -1
- package/dist/es/html-validate.js +2 -2
- package/dist/es/index.js +3 -3
- package/dist/es/jest-worker.js +6 -6
- package/dist/es/jest.js +1 -1
- package/dist/es/matchers-jestonly.js +1 -1
- package/dist/es/matchers.js +1 -1
- package/dist/es/vitest.js +2 -2
- package/dist/types/browser.d.ts +25 -4
- package/dist/types/index.d.ts +25 -4
- package/package.json +1 -1
package/dist/cjs/core.js
CHANGED
|
@@ -4,7 +4,6 @@ var Ajv = require('ajv');
|
|
|
4
4
|
var elements = require('./elements.js');
|
|
5
5
|
var betterAjvErrors = require('@sidvind/better-ajv-errors');
|
|
6
6
|
var utils_naturalJoin = require('./utils/natural-join.js');
|
|
7
|
-
var fs = require('node:fs');
|
|
8
7
|
var kleur = require('kleur');
|
|
9
8
|
var stylish$1 = require('@html-validate/stylish');
|
|
10
9
|
var semver = require('semver');
|
|
@@ -13,7 +12,6 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
13
12
|
|
|
14
13
|
var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
15
14
|
var betterAjvErrors__default = /*#__PURE__*/_interopDefault(betterAjvErrors);
|
|
16
|
-
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
17
15
|
var kleur__default = /*#__PURE__*/_interopDefault(kleur);
|
|
18
16
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
19
17
|
|
|
@@ -6608,7 +6606,7 @@ const defaults$j = {
|
|
|
6608
6606
|
minInitialRank: "h1",
|
|
6609
6607
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
|
|
6610
6608
|
};
|
|
6611
|
-
function isRelevant$
|
|
6609
|
+
function isRelevant$5(event) {
|
|
6612
6610
|
const node = event.target;
|
|
6613
6611
|
return Boolean(node.meta?.heading);
|
|
6614
6612
|
}
|
|
@@ -6677,7 +6675,7 @@ class HeadingLevel extends Rule {
|
|
|
6677
6675
|
};
|
|
6678
6676
|
}
|
|
6679
6677
|
setup() {
|
|
6680
|
-
this.on("tag:start", isRelevant$
|
|
6678
|
+
this.on("tag:start", isRelevant$5, (event) => {
|
|
6681
6679
|
this.onTagStart(event);
|
|
6682
6680
|
});
|
|
6683
6681
|
this.on("tag:ready", (event) => {
|
|
@@ -7333,7 +7331,7 @@ class MapDupName extends Rule {
|
|
|
7333
7331
|
}
|
|
7334
7332
|
}
|
|
7335
7333
|
|
|
7336
|
-
function isRelevant$
|
|
7334
|
+
function isRelevant$4(event) {
|
|
7337
7335
|
return event.target.is("map");
|
|
7338
7336
|
}
|
|
7339
7337
|
function hasStaticValue(attr) {
|
|
@@ -7347,7 +7345,7 @@ class MapIdName extends Rule {
|
|
|
7347
7345
|
};
|
|
7348
7346
|
}
|
|
7349
7347
|
setup() {
|
|
7350
|
-
this.on("tag:ready", isRelevant$
|
|
7348
|
+
this.on("tag:ready", isRelevant$4, (event) => {
|
|
7351
7349
|
const { target } = event;
|
|
7352
7350
|
const id = target.getAttribute("id");
|
|
7353
7351
|
const name = target.getAttribute("name");
|
|
@@ -7471,7 +7469,7 @@ const abstractRoles = [
|
|
|
7471
7469
|
"widget",
|
|
7472
7470
|
"window"
|
|
7473
7471
|
];
|
|
7474
|
-
function isRelevant$
|
|
7472
|
+
function isRelevant$3(event) {
|
|
7475
7473
|
return event.key === "role";
|
|
7476
7474
|
}
|
|
7477
7475
|
class NoAbstractRole extends Rule {
|
|
@@ -7490,7 +7488,7 @@ class NoAbstractRole extends Rule {
|
|
|
7490
7488
|
};
|
|
7491
7489
|
}
|
|
7492
7490
|
setup() {
|
|
7493
|
-
this.on("attr", isRelevant$
|
|
7491
|
+
this.on("attr", isRelevant$3, (event) => {
|
|
7494
7492
|
const roles = event.value;
|
|
7495
7493
|
if (!roles || roles instanceof DynamicValue) {
|
|
7496
7494
|
return;
|
|
@@ -7691,17 +7689,25 @@ class NoDupID extends Rule {
|
|
|
7691
7689
|
setup() {
|
|
7692
7690
|
this.on("dom:ready", (event) => {
|
|
7693
7691
|
const { document } = event;
|
|
7692
|
+
const rootExisting = getExisting(document.root, document.root);
|
|
7693
|
+
const useRootExisting = !document.querySelector("template");
|
|
7694
7694
|
const elements = document.querySelectorAll("[id]");
|
|
7695
|
-
const
|
|
7696
|
-
for (const el of relevant) {
|
|
7695
|
+
for (const el of elements) {
|
|
7697
7696
|
const attr = el.getAttribute("id");
|
|
7698
|
-
if (!attr
|
|
7697
|
+
if (!attr) {
|
|
7698
|
+
continue;
|
|
7699
|
+
}
|
|
7700
|
+
if (!attr.value) {
|
|
7701
|
+
continue;
|
|
7702
|
+
}
|
|
7703
|
+
if (attr.isDynamic) {
|
|
7699
7704
|
continue;
|
|
7700
7705
|
}
|
|
7701
7706
|
const id = attr.value.toString();
|
|
7702
|
-
const existing = getExisting(el, document.root);
|
|
7707
|
+
const existing = useRootExisting ? rootExisting : getExisting(el, document.root);
|
|
7703
7708
|
if (existing.has(id)) {
|
|
7704
7709
|
this.report(el, `Duplicate ID "${id}"`, attr.valueLocation);
|
|
7710
|
+
continue;
|
|
7705
7711
|
}
|
|
7706
7712
|
existing.add(id);
|
|
7707
7713
|
}
|
|
@@ -7718,19 +7724,6 @@ function getExisting(element, root) {
|
|
|
7718
7724
|
return group.cacheSet(CACHE_KEY, existing2);
|
|
7719
7725
|
}
|
|
7720
7726
|
}
|
|
7721
|
-
function isRelevant$3(element) {
|
|
7722
|
-
const attr = element.getAttribute("id");
|
|
7723
|
-
if (!attr) {
|
|
7724
|
-
return false;
|
|
7725
|
-
}
|
|
7726
|
-
if (!attr.value) {
|
|
7727
|
-
return false;
|
|
7728
|
-
}
|
|
7729
|
-
if (attr.isDynamic) {
|
|
7730
|
-
return false;
|
|
7731
|
-
}
|
|
7732
|
-
return true;
|
|
7733
|
-
}
|
|
7734
7727
|
|
|
7735
7728
|
function isRelevant$2(event) {
|
|
7736
7729
|
return event.target.is("button");
|
|
@@ -9971,14 +9964,15 @@ class ValidID extends Rule {
|
|
|
9971
9964
|
}
|
|
9972
9965
|
documentation(context) {
|
|
9973
9966
|
const { relaxed } = this.options;
|
|
9974
|
-
const
|
|
9967
|
+
const { kind, id } = context;
|
|
9968
|
+
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(/^(.)/, (m) => m.toUpperCase());
|
|
9975
9969
|
const relaxedDescription = relaxed ? [] : [
|
|
9976
9970
|
" - ID must begin with a letter",
|
|
9977
9971
|
" - ID must only contain letters, digits, `-` and `_`"
|
|
9978
9972
|
];
|
|
9979
9973
|
return {
|
|
9980
9974
|
description: [
|
|
9981
|
-
`${message}.`,
|
|
9975
|
+
`${interpolate(message, { id })}.`,
|
|
9982
9976
|
"",
|
|
9983
9977
|
"Under the current configuration the following rules are applied:",
|
|
9984
9978
|
"",
|
|
@@ -9996,13 +9990,13 @@ class ValidID extends Rule {
|
|
|
9996
9990
|
return;
|
|
9997
9991
|
}
|
|
9998
9992
|
if (value === "") {
|
|
9999
|
-
const context = 1 /* EMPTY
|
|
10000
|
-
this.report(event.target, this.messages[context], event.location, context);
|
|
9993
|
+
const context = { kind: 1 /* EMPTY */, id: value };
|
|
9994
|
+
this.report(event.target, this.messages[context.kind], event.location, context);
|
|
10001
9995
|
return;
|
|
10002
9996
|
}
|
|
10003
9997
|
if (value.match(/\s/)) {
|
|
10004
|
-
const context = 2 /* WHITESPACE
|
|
10005
|
-
this.report(event.target, this.messages[context], event.valueLocation, context);
|
|
9998
|
+
const context = { kind: 2 /* WHITESPACE */, id: value };
|
|
9999
|
+
this.report(event.target, this.messages[context.kind], event.valueLocation, context);
|
|
10006
10000
|
return;
|
|
10007
10001
|
}
|
|
10008
10002
|
const { relaxed } = this.options;
|
|
@@ -10010,22 +10004,22 @@ class ValidID extends Rule {
|
|
|
10010
10004
|
return;
|
|
10011
10005
|
}
|
|
10012
10006
|
if (value.match(/^[^\p{L}]/u)) {
|
|
10013
|
-
const context = 3 /* LEADING_CHARACTER
|
|
10014
|
-
this.report(event.target, this.messages[context], event.valueLocation, context);
|
|
10007
|
+
const context = { kind: 3 /* LEADING_CHARACTER */, id: value };
|
|
10008
|
+
this.report(event.target, this.messages[context.kind], event.valueLocation, context);
|
|
10015
10009
|
return;
|
|
10016
10010
|
}
|
|
10017
10011
|
if (value.match(/[^\p{L}\p{N}_-]/u)) {
|
|
10018
|
-
const context = 4 /* DISALLOWED_CHARACTER
|
|
10019
|
-
this.report(event.target, this.messages[context], event.valueLocation, context);
|
|
10012
|
+
const context = { kind: 4 /* DISALLOWED_CHARACTER */, id: value };
|
|
10013
|
+
this.report(event.target, this.messages[context.kind], event.valueLocation, context);
|
|
10020
10014
|
}
|
|
10021
10015
|
});
|
|
10022
10016
|
}
|
|
10023
10017
|
get messages() {
|
|
10024
10018
|
return {
|
|
10025
|
-
[1 /* EMPTY */]:
|
|
10026
|
-
[2 /* WHITESPACE */]:
|
|
10027
|
-
[3 /* LEADING_CHARACTER */]:
|
|
10028
|
-
[4 /* DISALLOWED_CHARACTER */]:
|
|
10019
|
+
[1 /* EMPTY */]: `element id "{{ id }}" must not be empty`,
|
|
10020
|
+
[2 /* WHITESPACE */]: `element id "{{ id }}" must not contain whitespace`,
|
|
10021
|
+
[3 /* LEADING_CHARACTER */]: `element id "{{ id }}" must begin with a letter`,
|
|
10022
|
+
[4 /* DISALLOWED_CHARACTER */]: `element id "{{ id }}" must only contain letters, digits, dash and underscore characters`
|
|
10029
10023
|
};
|
|
10030
10024
|
}
|
|
10031
10025
|
isRelevant(event) {
|
|
@@ -10090,29 +10084,41 @@ class VoidStyle extends Rule {
|
|
|
10090
10084
|
};
|
|
10091
10085
|
}
|
|
10092
10086
|
setup() {
|
|
10087
|
+
const { style } = this;
|
|
10088
|
+
const validateStyle = {
|
|
10089
|
+
[1 /* AlwaysOmit */]: this.validateOmitted.bind(this),
|
|
10090
|
+
[2 /* AlwaysSelfclose */]: this.validateSelfClosed.bind(this)
|
|
10091
|
+
}[style];
|
|
10093
10092
|
this.on("tag:end", (event) => {
|
|
10094
10093
|
const active = event.previous;
|
|
10095
10094
|
if (active.meta) {
|
|
10096
|
-
|
|
10095
|
+
validateStyle(active);
|
|
10097
10096
|
}
|
|
10098
10097
|
});
|
|
10099
10098
|
}
|
|
10100
|
-
|
|
10099
|
+
validateOmitted(node) {
|
|
10101
10100
|
if (!node.voidElement) {
|
|
10102
10101
|
return;
|
|
10103
10102
|
}
|
|
10104
|
-
if (
|
|
10105
|
-
|
|
10106
|
-
node,
|
|
10107
|
-
`Expected omitted end tag <${node.tagName}> instead of self-closing element <${node.tagName}/>`
|
|
10108
|
-
);
|
|
10103
|
+
if (node.closed !== NodeClosed.VoidSelfClosed) {
|
|
10104
|
+
return;
|
|
10109
10105
|
}
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10106
|
+
this.reportError(
|
|
10107
|
+
node,
|
|
10108
|
+
`Expected omitted end tag <${node.tagName}> instead of self-closing element <${node.tagName}/>`
|
|
10109
|
+
);
|
|
10110
|
+
}
|
|
10111
|
+
validateSelfClosed(node) {
|
|
10112
|
+
if (!node.voidElement) {
|
|
10113
|
+
return;
|
|
10114
|
+
}
|
|
10115
|
+
if (node.closed !== NodeClosed.VoidOmitted) {
|
|
10116
|
+
return;
|
|
10115
10117
|
}
|
|
10118
|
+
this.reportError(
|
|
10119
|
+
node,
|
|
10120
|
+
`Expected self-closing element <${node.tagName}/> instead of omitted end-tag <${node.tagName}>`
|
|
10121
|
+
);
|
|
10116
10122
|
}
|
|
10117
10123
|
reportError(node, message) {
|
|
10118
10124
|
const context = {
|
|
@@ -10121,12 +10127,6 @@ class VoidStyle extends Rule {
|
|
|
10121
10127
|
};
|
|
10122
10128
|
super.report(node, message, null, context);
|
|
10123
10129
|
}
|
|
10124
|
-
shouldBeOmitted(node) {
|
|
10125
|
-
return this.style === 1 /* AlwaysOmit */ && node.closed === NodeClosed.VoidSelfClosed;
|
|
10126
|
-
}
|
|
10127
|
-
shouldBeSelfClosed(node) {
|
|
10128
|
-
return this.style === 2 /* AlwaysSelfclose */ && node.closed === NodeClosed.VoidOmitted;
|
|
10129
|
-
}
|
|
10130
10130
|
}
|
|
10131
10131
|
function parseStyle(name) {
|
|
10132
10132
|
switch (name) {
|
|
@@ -11521,6 +11521,75 @@ function defineConfig(config) {
|
|
|
11521
11521
|
return config;
|
|
11522
11522
|
}
|
|
11523
11523
|
|
|
11524
|
+
const defaultResolvers = [];
|
|
11525
|
+
function hasResolver(value) {
|
|
11526
|
+
return Array.isArray(value[0]);
|
|
11527
|
+
}
|
|
11528
|
+
class StaticConfigLoader extends ConfigLoader {
|
|
11529
|
+
constructor(...args) {
|
|
11530
|
+
if (hasResolver(args)) {
|
|
11531
|
+
const [resolvers, config] = args;
|
|
11532
|
+
super(resolvers, config);
|
|
11533
|
+
} else {
|
|
11534
|
+
const [config] = args;
|
|
11535
|
+
super(defaultResolvers, config);
|
|
11536
|
+
}
|
|
11537
|
+
}
|
|
11538
|
+
/**
|
|
11539
|
+
* Set a new configuration for this loader.
|
|
11540
|
+
*
|
|
11541
|
+
* @public
|
|
11542
|
+
* @since 8.20.0
|
|
11543
|
+
* @param config - New configuration to use.
|
|
11544
|
+
*/
|
|
11545
|
+
setConfig(config) {
|
|
11546
|
+
this.setConfigData(config);
|
|
11547
|
+
}
|
|
11548
|
+
getConfigFor(_handle, configOverride) {
|
|
11549
|
+
const override = this.loadFromObject(configOverride ?? {});
|
|
11550
|
+
if (isThenable(override)) {
|
|
11551
|
+
return override.then((override2) => this._resolveConfig(override2));
|
|
11552
|
+
} else {
|
|
11553
|
+
return this._resolveConfig(override);
|
|
11554
|
+
}
|
|
11555
|
+
}
|
|
11556
|
+
flushCache() {
|
|
11557
|
+
}
|
|
11558
|
+
defaultConfig() {
|
|
11559
|
+
return this.loadFromObject({
|
|
11560
|
+
extends: ["html-validate:recommended"],
|
|
11561
|
+
elements: ["html5"]
|
|
11562
|
+
});
|
|
11563
|
+
}
|
|
11564
|
+
_resolveConfig(override) {
|
|
11565
|
+
if (override.isRootFound()) {
|
|
11566
|
+
return override.resolve();
|
|
11567
|
+
}
|
|
11568
|
+
const globalConfig = this.getGlobalConfig();
|
|
11569
|
+
if (isThenable(globalConfig)) {
|
|
11570
|
+
return globalConfig.then((globalConfig2) => {
|
|
11571
|
+
const merged = globalConfig2.merge(this.resolvers, override);
|
|
11572
|
+
if (isThenable(merged)) {
|
|
11573
|
+
return merged.then((merged2) => {
|
|
11574
|
+
return merged2.resolve();
|
|
11575
|
+
});
|
|
11576
|
+
} else {
|
|
11577
|
+
return merged.resolve();
|
|
11578
|
+
}
|
|
11579
|
+
});
|
|
11580
|
+
} else {
|
|
11581
|
+
const merged = globalConfig.merge(this.resolvers, override);
|
|
11582
|
+
if (isThenable(merged)) {
|
|
11583
|
+
return merged.then((merged2) => {
|
|
11584
|
+
return merged2.resolve();
|
|
11585
|
+
});
|
|
11586
|
+
} else {
|
|
11587
|
+
return merged.resolve();
|
|
11588
|
+
}
|
|
11589
|
+
}
|
|
11590
|
+
}
|
|
11591
|
+
}
|
|
11592
|
+
|
|
11524
11593
|
class EventHandler {
|
|
11525
11594
|
listeners;
|
|
11526
11595
|
constructor() {
|
|
@@ -11582,6 +11651,153 @@ class EventHandler {
|
|
|
11582
11651
|
}
|
|
11583
11652
|
}
|
|
11584
11653
|
|
|
11654
|
+
const name = "html-validate";
|
|
11655
|
+
const version = "9.4.0";
|
|
11656
|
+
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11657
|
+
|
|
11658
|
+
function freeze(src) {
|
|
11659
|
+
return {
|
|
11660
|
+
...src,
|
|
11661
|
+
selector: src.selector()
|
|
11662
|
+
};
|
|
11663
|
+
}
|
|
11664
|
+
function isThenableArray(value) {
|
|
11665
|
+
if (value.length === 0) {
|
|
11666
|
+
return false;
|
|
11667
|
+
}
|
|
11668
|
+
return isThenable(value[0]);
|
|
11669
|
+
}
|
|
11670
|
+
class Reporter {
|
|
11671
|
+
result;
|
|
11672
|
+
constructor() {
|
|
11673
|
+
this.result = {};
|
|
11674
|
+
}
|
|
11675
|
+
static merge(reports) {
|
|
11676
|
+
if (isThenable(reports)) {
|
|
11677
|
+
return reports.then((reports2) => this.merge(reports2));
|
|
11678
|
+
}
|
|
11679
|
+
if (isThenableArray(reports)) {
|
|
11680
|
+
return Promise.all(reports).then((reports2) => this.merge(reports2));
|
|
11681
|
+
}
|
|
11682
|
+
const valid = reports.every((report) => report.valid);
|
|
11683
|
+
const merged = {};
|
|
11684
|
+
reports.forEach((report) => {
|
|
11685
|
+
report.results.forEach((result) => {
|
|
11686
|
+
const key = result.filePath;
|
|
11687
|
+
if (key in merged) {
|
|
11688
|
+
merged[key].messages = [...merged[key].messages, ...result.messages];
|
|
11689
|
+
} else {
|
|
11690
|
+
merged[key] = { ...result };
|
|
11691
|
+
}
|
|
11692
|
+
});
|
|
11693
|
+
});
|
|
11694
|
+
const results = Object.values(merged).map((result) => {
|
|
11695
|
+
result.errorCount = countErrors(result.messages);
|
|
11696
|
+
result.warningCount = countWarnings(result.messages);
|
|
11697
|
+
return result;
|
|
11698
|
+
});
|
|
11699
|
+
return {
|
|
11700
|
+
valid,
|
|
11701
|
+
results,
|
|
11702
|
+
errorCount: sumErrors(results),
|
|
11703
|
+
warningCount: sumWarnings(results)
|
|
11704
|
+
};
|
|
11705
|
+
}
|
|
11706
|
+
add(rule, message, severity, node, location, context) {
|
|
11707
|
+
if (!(location.filename in this.result)) {
|
|
11708
|
+
this.result[location.filename] = [];
|
|
11709
|
+
}
|
|
11710
|
+
const ruleUrl = rule.documentation(context)?.url;
|
|
11711
|
+
const entry = {
|
|
11712
|
+
ruleId: rule.name,
|
|
11713
|
+
severity,
|
|
11714
|
+
message,
|
|
11715
|
+
offset: location.offset,
|
|
11716
|
+
line: location.line,
|
|
11717
|
+
column: location.column,
|
|
11718
|
+
size: location.size || 0,
|
|
11719
|
+
selector() {
|
|
11720
|
+
return node ? node.generateSelector() : null;
|
|
11721
|
+
}
|
|
11722
|
+
};
|
|
11723
|
+
if (ruleUrl) {
|
|
11724
|
+
entry.ruleUrl = ruleUrl;
|
|
11725
|
+
}
|
|
11726
|
+
if (context) {
|
|
11727
|
+
entry.context = context;
|
|
11728
|
+
}
|
|
11729
|
+
this.result[location.filename].push(entry);
|
|
11730
|
+
}
|
|
11731
|
+
addManual(filename, message) {
|
|
11732
|
+
if (!(filename in this.result)) {
|
|
11733
|
+
this.result[filename] = [];
|
|
11734
|
+
}
|
|
11735
|
+
this.result[filename].push(message);
|
|
11736
|
+
}
|
|
11737
|
+
save(sources) {
|
|
11738
|
+
const report = {
|
|
11739
|
+
valid: this.isValid(),
|
|
11740
|
+
results: Object.keys(this.result).map((filePath) => {
|
|
11741
|
+
const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
|
|
11742
|
+
const source = (sources ?? []).find((source2) => filePath === source2.filename);
|
|
11743
|
+
return {
|
|
11744
|
+
filePath,
|
|
11745
|
+
messages,
|
|
11746
|
+
errorCount: countErrors(messages),
|
|
11747
|
+
warningCount: countWarnings(messages),
|
|
11748
|
+
source: source ? source.originalData ?? source.data : null
|
|
11749
|
+
};
|
|
11750
|
+
}),
|
|
11751
|
+
errorCount: 0,
|
|
11752
|
+
warningCount: 0
|
|
11753
|
+
};
|
|
11754
|
+
report.errorCount = sumErrors(report.results);
|
|
11755
|
+
report.warningCount = sumWarnings(report.results);
|
|
11756
|
+
return report;
|
|
11757
|
+
}
|
|
11758
|
+
isValid() {
|
|
11759
|
+
const numErrors = Object.values(this.result).reduce((sum, messages) => {
|
|
11760
|
+
return sum + countErrors(messages);
|
|
11761
|
+
}, 0);
|
|
11762
|
+
return numErrors === 0;
|
|
11763
|
+
}
|
|
11764
|
+
}
|
|
11765
|
+
function countErrors(messages) {
|
|
11766
|
+
return messages.filter((m) => m.severity === Number(Severity.ERROR)).length;
|
|
11767
|
+
}
|
|
11768
|
+
function countWarnings(messages) {
|
|
11769
|
+
return messages.filter((m) => m.severity === Number(Severity.WARN)).length;
|
|
11770
|
+
}
|
|
11771
|
+
function sumErrors(results) {
|
|
11772
|
+
return results.reduce((sum, result) => {
|
|
11773
|
+
return sum + result.errorCount;
|
|
11774
|
+
}, 0);
|
|
11775
|
+
}
|
|
11776
|
+
function sumWarnings(results) {
|
|
11777
|
+
return results.reduce((sum, result) => {
|
|
11778
|
+
return sum + result.warningCount;
|
|
11779
|
+
}, 0);
|
|
11780
|
+
}
|
|
11781
|
+
function messageSort(a, b) {
|
|
11782
|
+
if (a.line < b.line) {
|
|
11783
|
+
return -1;
|
|
11784
|
+
}
|
|
11785
|
+
if (a.line > b.line) {
|
|
11786
|
+
return 1;
|
|
11787
|
+
}
|
|
11788
|
+
if (a.column < b.column) {
|
|
11789
|
+
return -1;
|
|
11790
|
+
}
|
|
11791
|
+
if (a.column > b.column) {
|
|
11792
|
+
return 1;
|
|
11793
|
+
}
|
|
11794
|
+
return 0;
|
|
11795
|
+
}
|
|
11796
|
+
|
|
11797
|
+
function definePlugin(plugin) {
|
|
11798
|
+
return plugin;
|
|
11799
|
+
}
|
|
11800
|
+
|
|
11585
11801
|
const regexp = /<!(?:--)?\[(.*?)\](?:--)?>/g;
|
|
11586
11802
|
function* parseConditionalComment(comment, commentLocation) {
|
|
11587
11803
|
let match;
|
|
@@ -12181,145 +12397,6 @@ class Parser {
|
|
|
12181
12397
|
}
|
|
12182
12398
|
}
|
|
12183
12399
|
|
|
12184
|
-
function freeze(src) {
|
|
12185
|
-
return {
|
|
12186
|
-
...src,
|
|
12187
|
-
selector: src.selector()
|
|
12188
|
-
};
|
|
12189
|
-
}
|
|
12190
|
-
function isThenableArray(value) {
|
|
12191
|
-
if (value.length === 0) {
|
|
12192
|
-
return false;
|
|
12193
|
-
}
|
|
12194
|
-
return isThenable(value[0]);
|
|
12195
|
-
}
|
|
12196
|
-
class Reporter {
|
|
12197
|
-
result;
|
|
12198
|
-
constructor() {
|
|
12199
|
-
this.result = {};
|
|
12200
|
-
}
|
|
12201
|
-
static merge(reports) {
|
|
12202
|
-
if (isThenable(reports)) {
|
|
12203
|
-
return reports.then((reports2) => this.merge(reports2));
|
|
12204
|
-
}
|
|
12205
|
-
if (isThenableArray(reports)) {
|
|
12206
|
-
return Promise.all(reports).then((reports2) => this.merge(reports2));
|
|
12207
|
-
}
|
|
12208
|
-
const valid = reports.every((report) => report.valid);
|
|
12209
|
-
const merged = {};
|
|
12210
|
-
reports.forEach((report) => {
|
|
12211
|
-
report.results.forEach((result) => {
|
|
12212
|
-
const key = result.filePath;
|
|
12213
|
-
if (key in merged) {
|
|
12214
|
-
merged[key].messages = [...merged[key].messages, ...result.messages];
|
|
12215
|
-
} else {
|
|
12216
|
-
merged[key] = { ...result };
|
|
12217
|
-
}
|
|
12218
|
-
});
|
|
12219
|
-
});
|
|
12220
|
-
const results = Object.values(merged).map((result) => {
|
|
12221
|
-
result.errorCount = countErrors(result.messages);
|
|
12222
|
-
result.warningCount = countWarnings(result.messages);
|
|
12223
|
-
return result;
|
|
12224
|
-
});
|
|
12225
|
-
return {
|
|
12226
|
-
valid,
|
|
12227
|
-
results,
|
|
12228
|
-
errorCount: sumErrors(results),
|
|
12229
|
-
warningCount: sumWarnings(results)
|
|
12230
|
-
};
|
|
12231
|
-
}
|
|
12232
|
-
add(rule, message, severity, node, location, context) {
|
|
12233
|
-
if (!(location.filename in this.result)) {
|
|
12234
|
-
this.result[location.filename] = [];
|
|
12235
|
-
}
|
|
12236
|
-
const ruleUrl = rule.documentation(context)?.url;
|
|
12237
|
-
const entry = {
|
|
12238
|
-
ruleId: rule.name,
|
|
12239
|
-
severity,
|
|
12240
|
-
message,
|
|
12241
|
-
offset: location.offset,
|
|
12242
|
-
line: location.line,
|
|
12243
|
-
column: location.column,
|
|
12244
|
-
size: location.size || 0,
|
|
12245
|
-
selector() {
|
|
12246
|
-
return node ? node.generateSelector() : null;
|
|
12247
|
-
}
|
|
12248
|
-
};
|
|
12249
|
-
if (ruleUrl) {
|
|
12250
|
-
entry.ruleUrl = ruleUrl;
|
|
12251
|
-
}
|
|
12252
|
-
if (context) {
|
|
12253
|
-
entry.context = context;
|
|
12254
|
-
}
|
|
12255
|
-
this.result[location.filename].push(entry);
|
|
12256
|
-
}
|
|
12257
|
-
addManual(filename, message) {
|
|
12258
|
-
if (!(filename in this.result)) {
|
|
12259
|
-
this.result[filename] = [];
|
|
12260
|
-
}
|
|
12261
|
-
this.result[filename].push(message);
|
|
12262
|
-
}
|
|
12263
|
-
save(sources) {
|
|
12264
|
-
const report = {
|
|
12265
|
-
valid: this.isValid(),
|
|
12266
|
-
results: Object.keys(this.result).map((filePath) => {
|
|
12267
|
-
const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
|
|
12268
|
-
const source = (sources ?? []).find((source2) => filePath === source2.filename);
|
|
12269
|
-
return {
|
|
12270
|
-
filePath,
|
|
12271
|
-
messages,
|
|
12272
|
-
errorCount: countErrors(messages),
|
|
12273
|
-
warningCount: countWarnings(messages),
|
|
12274
|
-
source: source ? source.originalData ?? source.data : null
|
|
12275
|
-
};
|
|
12276
|
-
}),
|
|
12277
|
-
errorCount: 0,
|
|
12278
|
-
warningCount: 0
|
|
12279
|
-
};
|
|
12280
|
-
report.errorCount = sumErrors(report.results);
|
|
12281
|
-
report.warningCount = sumWarnings(report.results);
|
|
12282
|
-
return report;
|
|
12283
|
-
}
|
|
12284
|
-
isValid() {
|
|
12285
|
-
const numErrors = Object.values(this.result).reduce((sum, messages) => {
|
|
12286
|
-
return sum + countErrors(messages);
|
|
12287
|
-
}, 0);
|
|
12288
|
-
return numErrors === 0;
|
|
12289
|
-
}
|
|
12290
|
-
}
|
|
12291
|
-
function countErrors(messages) {
|
|
12292
|
-
return messages.filter((m) => m.severity === Number(Severity.ERROR)).length;
|
|
12293
|
-
}
|
|
12294
|
-
function countWarnings(messages) {
|
|
12295
|
-
return messages.filter((m) => m.severity === Number(Severity.WARN)).length;
|
|
12296
|
-
}
|
|
12297
|
-
function sumErrors(results) {
|
|
12298
|
-
return results.reduce((sum, result) => {
|
|
12299
|
-
return sum + result.errorCount;
|
|
12300
|
-
}, 0);
|
|
12301
|
-
}
|
|
12302
|
-
function sumWarnings(results) {
|
|
12303
|
-
return results.reduce((sum, result) => {
|
|
12304
|
-
return sum + result.warningCount;
|
|
12305
|
-
}, 0);
|
|
12306
|
-
}
|
|
12307
|
-
function messageSort(a, b) {
|
|
12308
|
-
if (a.line < b.line) {
|
|
12309
|
-
return -1;
|
|
12310
|
-
}
|
|
12311
|
-
if (a.line > b.line) {
|
|
12312
|
-
return 1;
|
|
12313
|
-
}
|
|
12314
|
-
if (a.column < b.column) {
|
|
12315
|
-
return -1;
|
|
12316
|
-
}
|
|
12317
|
-
if (a.column > b.column) {
|
|
12318
|
-
return 1;
|
|
12319
|
-
}
|
|
12320
|
-
return 0;
|
|
12321
|
-
}
|
|
12322
|
-
|
|
12323
12400
|
let blockerCounter = 1;
|
|
12324
12401
|
function createBlocker() {
|
|
12325
12402
|
const id = blockerCounter++;
|
|
@@ -12655,75 +12732,6 @@ class Engine {
|
|
|
12655
12732
|
}
|
|
12656
12733
|
}
|
|
12657
12734
|
|
|
12658
|
-
const defaultResolvers = [];
|
|
12659
|
-
function hasResolver(value) {
|
|
12660
|
-
return Array.isArray(value[0]);
|
|
12661
|
-
}
|
|
12662
|
-
class StaticConfigLoader extends ConfigLoader {
|
|
12663
|
-
constructor(...args) {
|
|
12664
|
-
if (hasResolver(args)) {
|
|
12665
|
-
const [resolvers, config] = args;
|
|
12666
|
-
super(resolvers, config);
|
|
12667
|
-
} else {
|
|
12668
|
-
const [config] = args;
|
|
12669
|
-
super(defaultResolvers, config);
|
|
12670
|
-
}
|
|
12671
|
-
}
|
|
12672
|
-
/**
|
|
12673
|
-
* Set a new configuration for this loader.
|
|
12674
|
-
*
|
|
12675
|
-
* @public
|
|
12676
|
-
* @since 8.20.0
|
|
12677
|
-
* @param config - New configuration to use.
|
|
12678
|
-
*/
|
|
12679
|
-
setConfig(config) {
|
|
12680
|
-
this.setConfigData(config);
|
|
12681
|
-
}
|
|
12682
|
-
getConfigFor(_handle, configOverride) {
|
|
12683
|
-
const override = this.loadFromObject(configOverride ?? {});
|
|
12684
|
-
if (isThenable(override)) {
|
|
12685
|
-
return override.then((override2) => this._resolveConfig(override2));
|
|
12686
|
-
} else {
|
|
12687
|
-
return this._resolveConfig(override);
|
|
12688
|
-
}
|
|
12689
|
-
}
|
|
12690
|
-
flushCache() {
|
|
12691
|
-
}
|
|
12692
|
-
defaultConfig() {
|
|
12693
|
-
return this.loadFromObject({
|
|
12694
|
-
extends: ["html-validate:recommended"],
|
|
12695
|
-
elements: ["html5"]
|
|
12696
|
-
});
|
|
12697
|
-
}
|
|
12698
|
-
_resolveConfig(override) {
|
|
12699
|
-
if (override.isRootFound()) {
|
|
12700
|
-
return override.resolve();
|
|
12701
|
-
}
|
|
12702
|
-
const globalConfig = this.getGlobalConfig();
|
|
12703
|
-
if (isThenable(globalConfig)) {
|
|
12704
|
-
return globalConfig.then((globalConfig2) => {
|
|
12705
|
-
const merged = globalConfig2.merge(this.resolvers, override);
|
|
12706
|
-
if (isThenable(merged)) {
|
|
12707
|
-
return merged.then((merged2) => {
|
|
12708
|
-
return merged2.resolve();
|
|
12709
|
-
});
|
|
12710
|
-
} else {
|
|
12711
|
-
return merged.resolve();
|
|
12712
|
-
}
|
|
12713
|
-
});
|
|
12714
|
-
} else {
|
|
12715
|
-
const merged = globalConfig.merge(this.resolvers, override);
|
|
12716
|
-
if (isThenable(merged)) {
|
|
12717
|
-
return merged.then((merged2) => {
|
|
12718
|
-
return merged2.resolve();
|
|
12719
|
-
});
|
|
12720
|
-
} else {
|
|
12721
|
-
return merged.resolve();
|
|
12722
|
-
}
|
|
12723
|
-
}
|
|
12724
|
-
}
|
|
12725
|
-
}
|
|
12726
|
-
|
|
12727
12735
|
function getNamedTransformerFromPlugin(name, plugins, pluginName, key) {
|
|
12728
12736
|
const plugin = plugins.find((cur) => cur.name === pluginName);
|
|
12729
12737
|
if (!plugin) {
|
|
@@ -12903,10 +12911,11 @@ function transformSourceSync(resolvers, config, source, filename) {
|
|
|
12903
12911
|
}
|
|
12904
12912
|
}
|
|
12905
12913
|
|
|
12906
|
-
function transformFilename(resolvers, config, filename) {
|
|
12914
|
+
function transformFilename(resolvers, config, filename, fs) {
|
|
12907
12915
|
const stdin = 0;
|
|
12908
12916
|
const src = filename !== "/dev/stdin" ? filename : stdin;
|
|
12909
|
-
const
|
|
12917
|
+
const output = fs.readFileSync(src, { encoding: "utf8" });
|
|
12918
|
+
const data = typeof output === "string" ? output : output.toString("utf8");
|
|
12910
12919
|
const source = {
|
|
12911
12920
|
data,
|
|
12912
12921
|
filename,
|
|
@@ -12917,10 +12926,11 @@ function transformFilename(resolvers, config, filename) {
|
|
|
12917
12926
|
};
|
|
12918
12927
|
return transformSource(resolvers, config, source, filename);
|
|
12919
12928
|
}
|
|
12920
|
-
function transformFilenameSync(resolvers, config, filename) {
|
|
12929
|
+
function transformFilenameSync(resolvers, config, filename, fs) {
|
|
12921
12930
|
const stdin = 0;
|
|
12922
12931
|
const src = filename !== "/dev/stdin" ? filename : stdin;
|
|
12923
|
-
const
|
|
12932
|
+
const output = fs.readFileSync(src, { encoding: "utf8" });
|
|
12933
|
+
const data = typeof output === "string" ? output : output.toString("utf8");
|
|
12924
12934
|
const source = {
|
|
12925
12935
|
data,
|
|
12926
12936
|
filename,
|
|
@@ -12932,430 +12942,6 @@ function transformFilenameSync(resolvers, config, filename) {
|
|
|
12932
12942
|
return transformSourceSync(resolvers, config, source, filename);
|
|
12933
12943
|
}
|
|
12934
12944
|
|
|
12935
|
-
function isSourceHooks(value) {
|
|
12936
|
-
if (!value || typeof value === "string") {
|
|
12937
|
-
return false;
|
|
12938
|
-
}
|
|
12939
|
-
return Boolean(value.processAttribute || value.processElement);
|
|
12940
|
-
}
|
|
12941
|
-
function isConfigData(value) {
|
|
12942
|
-
if (!value || typeof value === "string") {
|
|
12943
|
-
return false;
|
|
12944
|
-
}
|
|
12945
|
-
return !(value.processAttribute || value.processElement);
|
|
12946
|
-
}
|
|
12947
|
-
class HtmlValidate {
|
|
12948
|
-
configLoader;
|
|
12949
|
-
constructor(arg) {
|
|
12950
|
-
const [loader, config] = arg instanceof ConfigLoader ? [arg, void 0] : [void 0, arg];
|
|
12951
|
-
this.configLoader = loader ?? new StaticConfigLoader(config);
|
|
12952
|
-
}
|
|
12953
|
-
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
12954
|
-
validateString(str, arg1, arg2, arg3) {
|
|
12955
|
-
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
12956
|
-
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : void 0;
|
|
12957
|
-
const hooks = isSourceHooks(arg1) ? arg1 : isSourceHooks(arg2) ? arg2 : arg3;
|
|
12958
|
-
const source = {
|
|
12959
|
-
data: str,
|
|
12960
|
-
filename,
|
|
12961
|
-
line: 1,
|
|
12962
|
-
column: 1,
|
|
12963
|
-
offset: 0,
|
|
12964
|
-
hooks
|
|
12965
|
-
};
|
|
12966
|
-
return this.validateSource(source, options);
|
|
12967
|
-
}
|
|
12968
|
-
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
12969
|
-
validateStringSync(str, arg1, arg2, arg3) {
|
|
12970
|
-
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
12971
|
-
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : void 0;
|
|
12972
|
-
const hooks = isSourceHooks(arg1) ? arg1 : isSourceHooks(arg2) ? arg2 : arg3;
|
|
12973
|
-
const source = {
|
|
12974
|
-
data: str,
|
|
12975
|
-
filename,
|
|
12976
|
-
line: 1,
|
|
12977
|
-
column: 1,
|
|
12978
|
-
offset: 0,
|
|
12979
|
-
hooks
|
|
12980
|
-
};
|
|
12981
|
-
return this.validateSourceSync(source, options);
|
|
12982
|
-
}
|
|
12983
|
-
/**
|
|
12984
|
-
* Parse and validate HTML from [[Source]].
|
|
12985
|
-
*
|
|
12986
|
-
* @public
|
|
12987
|
-
* @param input - Source to parse.
|
|
12988
|
-
* @returns Report output.
|
|
12989
|
-
*/
|
|
12990
|
-
async validateSource(input, configOverride) {
|
|
12991
|
-
const source = normalizeSource(input);
|
|
12992
|
-
const config = await this.getConfigFor(source.filename, configOverride);
|
|
12993
|
-
const resolvers = this.configLoader.getResolvers();
|
|
12994
|
-
const transformedSource = await transformSource(resolvers, config, source);
|
|
12995
|
-
const engine = new Engine(config, Parser);
|
|
12996
|
-
return engine.lint(transformedSource);
|
|
12997
|
-
}
|
|
12998
|
-
/**
|
|
12999
|
-
* Parse and validate HTML from [[Source]].
|
|
13000
|
-
*
|
|
13001
|
-
* @public
|
|
13002
|
-
* @param input - Source to parse.
|
|
13003
|
-
* @returns Report output.
|
|
13004
|
-
*/
|
|
13005
|
-
validateSourceSync(input, configOverride) {
|
|
13006
|
-
const source = normalizeSource(input);
|
|
13007
|
-
const config = this.getConfigForSync(source.filename, configOverride);
|
|
13008
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13009
|
-
const transformedSource = transformSourceSync(resolvers, config, source);
|
|
13010
|
-
const engine = new Engine(config, Parser);
|
|
13011
|
-
return engine.lint(transformedSource);
|
|
13012
|
-
}
|
|
13013
|
-
/**
|
|
13014
|
-
* Parse and validate HTML from file.
|
|
13015
|
-
*
|
|
13016
|
-
* @public
|
|
13017
|
-
* @param filename - Filename to read and parse.
|
|
13018
|
-
* @returns Report output.
|
|
13019
|
-
*/
|
|
13020
|
-
async validateFile(filename) {
|
|
13021
|
-
const config = await this.getConfigFor(filename);
|
|
13022
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13023
|
-
const source = await transformFilename(resolvers, config, filename);
|
|
13024
|
-
const engine = new Engine(config, Parser);
|
|
13025
|
-
return Promise.resolve(engine.lint(source));
|
|
13026
|
-
}
|
|
13027
|
-
/**
|
|
13028
|
-
* Parse and validate HTML from file.
|
|
13029
|
-
*
|
|
13030
|
-
* @public
|
|
13031
|
-
* @param filename - Filename to read and parse.
|
|
13032
|
-
* @returns Report output.
|
|
13033
|
-
*/
|
|
13034
|
-
validateFileSync(filename) {
|
|
13035
|
-
const config = this.getConfigForSync(filename);
|
|
13036
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13037
|
-
const source = transformFilenameSync(resolvers, config, filename);
|
|
13038
|
-
const engine = new Engine(config, Parser);
|
|
13039
|
-
return engine.lint(source);
|
|
13040
|
-
}
|
|
13041
|
-
/**
|
|
13042
|
-
* Parse and validate HTML from multiple files. Result is merged together to a
|
|
13043
|
-
* single report.
|
|
13044
|
-
*
|
|
13045
|
-
* @param filenames - Filenames to read and parse.
|
|
13046
|
-
* @returns Report output.
|
|
13047
|
-
*/
|
|
13048
|
-
async validateMultipleFiles(filenames) {
|
|
13049
|
-
return Reporter.merge(filenames.map((filename) => this.validateFile(filename)));
|
|
13050
|
-
}
|
|
13051
|
-
/**
|
|
13052
|
-
* Parse and validate HTML from multiple files. Result is merged together to a
|
|
13053
|
-
* single report.
|
|
13054
|
-
*
|
|
13055
|
-
* @param filenames - Filenames to read and parse.
|
|
13056
|
-
* @returns Report output.
|
|
13057
|
-
*/
|
|
13058
|
-
validateMultipleFilesSync(filenames) {
|
|
13059
|
-
return Reporter.merge(filenames.map((filename) => this.validateFileSync(filename)));
|
|
13060
|
-
}
|
|
13061
|
-
/**
|
|
13062
|
-
* Returns true if the given filename can be validated.
|
|
13063
|
-
*
|
|
13064
|
-
* A file is considered to be validatable if the extension is `.html` or if a
|
|
13065
|
-
* transformer matches the filename.
|
|
13066
|
-
*
|
|
13067
|
-
* This is mostly useful for tooling to determine whenever to validate the
|
|
13068
|
-
* file or not. CLI tools will run on all the given files anyway.
|
|
13069
|
-
*/
|
|
13070
|
-
async canValidate(filename) {
|
|
13071
|
-
if (filename.toLowerCase().endsWith(".html")) {
|
|
13072
|
-
return true;
|
|
13073
|
-
}
|
|
13074
|
-
const config = await this.getConfigFor(filename);
|
|
13075
|
-
return config.canTransform(filename);
|
|
13076
|
-
}
|
|
13077
|
-
/**
|
|
13078
|
-
* Returns true if the given filename can be validated.
|
|
13079
|
-
*
|
|
13080
|
-
* A file is considered to be validatable if the extension is `.html` or if a
|
|
13081
|
-
* transformer matches the filename.
|
|
13082
|
-
*
|
|
13083
|
-
* This is mostly useful for tooling to determine whenever to validate the
|
|
13084
|
-
* file or not. CLI tools will run on all the given files anyway.
|
|
13085
|
-
*/
|
|
13086
|
-
canValidateSync(filename) {
|
|
13087
|
-
if (filename.toLowerCase().endsWith(".html")) {
|
|
13088
|
-
return true;
|
|
13089
|
-
}
|
|
13090
|
-
const config = this.getConfigForSync(filename);
|
|
13091
|
-
return config.canTransform(filename);
|
|
13092
|
-
}
|
|
13093
|
-
/**
|
|
13094
|
-
* Tokenize filename and output all tokens.
|
|
13095
|
-
*
|
|
13096
|
-
* Using CLI this is enabled with `--dump-tokens`. Mostly useful for
|
|
13097
|
-
* debugging.
|
|
13098
|
-
*
|
|
13099
|
-
* @internal
|
|
13100
|
-
* @param filename - Filename to tokenize.
|
|
13101
|
-
*/
|
|
13102
|
-
async dumpTokens(filename) {
|
|
13103
|
-
const config = await this.getConfigFor(filename);
|
|
13104
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13105
|
-
const source = await transformFilename(resolvers, config, filename);
|
|
13106
|
-
const engine = new Engine(config, Parser);
|
|
13107
|
-
return engine.dumpTokens(source);
|
|
13108
|
-
}
|
|
13109
|
-
/**
|
|
13110
|
-
* Parse filename and output all events.
|
|
13111
|
-
*
|
|
13112
|
-
* Using CLI this is enabled with `--dump-events`. Mostly useful for
|
|
13113
|
-
* debugging.
|
|
13114
|
-
*
|
|
13115
|
-
* @internal
|
|
13116
|
-
* @param filename - Filename to dump events from.
|
|
13117
|
-
*/
|
|
13118
|
-
async dumpEvents(filename) {
|
|
13119
|
-
const config = await this.getConfigFor(filename);
|
|
13120
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13121
|
-
const source = await transformFilename(resolvers, config, filename);
|
|
13122
|
-
const engine = new Engine(config, Parser);
|
|
13123
|
-
return engine.dumpEvents(source);
|
|
13124
|
-
}
|
|
13125
|
-
/**
|
|
13126
|
-
* Parse filename and output DOM tree.
|
|
13127
|
-
*
|
|
13128
|
-
* Using CLI this is enabled with `--dump-tree`. Mostly useful for
|
|
13129
|
-
* debugging.
|
|
13130
|
-
*
|
|
13131
|
-
* @internal
|
|
13132
|
-
* @param filename - Filename to dump DOM tree from.
|
|
13133
|
-
*/
|
|
13134
|
-
async dumpTree(filename) {
|
|
13135
|
-
const config = await this.getConfigFor(filename);
|
|
13136
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13137
|
-
const source = await transformFilename(resolvers, config, filename);
|
|
13138
|
-
const engine = new Engine(config, Parser);
|
|
13139
|
-
return engine.dumpTree(source);
|
|
13140
|
-
}
|
|
13141
|
-
/**
|
|
13142
|
-
* Transform filename and output source data.
|
|
13143
|
-
*
|
|
13144
|
-
* Using CLI this is enabled with `--dump-source`. Mostly useful for
|
|
13145
|
-
* debugging.
|
|
13146
|
-
*
|
|
13147
|
-
* @internal
|
|
13148
|
-
* @param filename - Filename to dump source from.
|
|
13149
|
-
*/
|
|
13150
|
-
async dumpSource(filename) {
|
|
13151
|
-
const config = await this.getConfigFor(filename);
|
|
13152
|
-
const resolvers = this.configLoader.getResolvers();
|
|
13153
|
-
const sources = await transformFilename(resolvers, config, filename);
|
|
13154
|
-
return sources.reduce((result, source) => {
|
|
13155
|
-
const line = String(source.line);
|
|
13156
|
-
const column = String(source.column);
|
|
13157
|
-
const offset = String(source.offset);
|
|
13158
|
-
result.push(`Source ${source.filename}@${line}:${column} (offset: ${offset})`);
|
|
13159
|
-
if (source.transformedBy) {
|
|
13160
|
-
result.push("Transformed by:");
|
|
13161
|
-
result = result.concat(source.transformedBy.reverse().map((name) => ` - ${name}`));
|
|
13162
|
-
}
|
|
13163
|
-
if (source.hooks && Object.keys(source.hooks).length > 0) {
|
|
13164
|
-
result.push("Hooks");
|
|
13165
|
-
for (const [key, present] of Object.entries(source.hooks)) {
|
|
13166
|
-
if (present) {
|
|
13167
|
-
result.push(` - ${key}`);
|
|
13168
|
-
}
|
|
13169
|
-
}
|
|
13170
|
-
}
|
|
13171
|
-
result.push("---");
|
|
13172
|
-
result = result.concat(source.data.split("\n"));
|
|
13173
|
-
result.push("---");
|
|
13174
|
-
return result;
|
|
13175
|
-
}, []);
|
|
13176
|
-
}
|
|
13177
|
-
/**
|
|
13178
|
-
* Get effective configuration schema.
|
|
13179
|
-
*/
|
|
13180
|
-
getConfigurationSchema() {
|
|
13181
|
-
return Promise.resolve(configurationSchema);
|
|
13182
|
-
}
|
|
13183
|
-
/**
|
|
13184
|
-
* Get effective metadata element schema.
|
|
13185
|
-
*
|
|
13186
|
-
* If a filename is given the configured plugins can extend the
|
|
13187
|
-
* schema. Filename must not be an existing file or a filetype normally
|
|
13188
|
-
* handled by html-validate but the path will be used when resolving
|
|
13189
|
-
* configuration. As a rule-of-thumb, set it to the elements json file.
|
|
13190
|
-
*/
|
|
13191
|
-
async getElementsSchema(filename) {
|
|
13192
|
-
const config = await this.getConfigFor(filename ?? "inline");
|
|
13193
|
-
const metaTable = config.getMetaTable();
|
|
13194
|
-
return metaTable.getJSONSchema();
|
|
13195
|
-
}
|
|
13196
|
-
/**
|
|
13197
|
-
* Get effective metadata element schema.
|
|
13198
|
-
*
|
|
13199
|
-
* If a filename is given the configured plugins can extend the
|
|
13200
|
-
* schema. Filename must not be an existing file or a filetype normally
|
|
13201
|
-
* handled by html-validate but the path will be used when resolving
|
|
13202
|
-
* configuration. As a rule-of-thumb, set it to the elements json file.
|
|
13203
|
-
*/
|
|
13204
|
-
getElementsSchemaSync(filename) {
|
|
13205
|
-
const config = this.getConfigForSync(filename ?? "inline");
|
|
13206
|
-
const metaTable = config.getMetaTable();
|
|
13207
|
-
return metaTable.getJSONSchema();
|
|
13208
|
-
}
|
|
13209
|
-
async getContextualDocumentation(message, filenameOrConfig = "inline") {
|
|
13210
|
-
const config = typeof filenameOrConfig === "string" ? await this.getConfigFor(filenameOrConfig) : await filenameOrConfig;
|
|
13211
|
-
const engine = new Engine(config, Parser);
|
|
13212
|
-
return engine.getRuleDocumentation(message);
|
|
13213
|
-
}
|
|
13214
|
-
getContextualDocumentationSync(message, filenameOrConfig = "inline") {
|
|
13215
|
-
const config = typeof filenameOrConfig === "string" ? this.getConfigForSync(filenameOrConfig) : filenameOrConfig;
|
|
13216
|
-
const engine = new Engine(config, Parser);
|
|
13217
|
-
return engine.getRuleDocumentation(message);
|
|
13218
|
-
}
|
|
13219
|
-
/**
|
|
13220
|
-
* Get contextual documentation for the given rule.
|
|
13221
|
-
*
|
|
13222
|
-
* Typical usage:
|
|
13223
|
-
*
|
|
13224
|
-
* ```js
|
|
13225
|
-
* const report = await htmlvalidate.validateFile("my-file.html");
|
|
13226
|
-
* for (const result of report.results){
|
|
13227
|
-
* const config = await htmlvalidate.getConfigFor(result.filePath);
|
|
13228
|
-
* for (const message of result.messages){
|
|
13229
|
-
* const documentation = await htmlvalidate.getRuleDocumentation(message.ruleId, config, message.context);
|
|
13230
|
-
* // do something with documentation
|
|
13231
|
-
* }
|
|
13232
|
-
* }
|
|
13233
|
-
* ```
|
|
13234
|
-
*
|
|
13235
|
-
* @public
|
|
13236
|
-
* @deprecated Deprecated since 8.0.0, use [[getContextualDocumentation]] instead.
|
|
13237
|
-
* @param ruleId - Rule to get documentation for.
|
|
13238
|
-
* @param config - If set it provides more accurate description by using the
|
|
13239
|
-
* correct configuration for the file.
|
|
13240
|
-
* @param context - If set to `Message.context` some rules can provide
|
|
13241
|
-
* contextual details and suggestions.
|
|
13242
|
-
*/
|
|
13243
|
-
async getRuleDocumentation(ruleId, config = null, context = null) {
|
|
13244
|
-
const c = config ?? this.getConfigFor("inline");
|
|
13245
|
-
const engine = new Engine(await c, Parser);
|
|
13246
|
-
return engine.getRuleDocumentation({ ruleId, context });
|
|
13247
|
-
}
|
|
13248
|
-
/**
|
|
13249
|
-
* Get contextual documentation for the given rule.
|
|
13250
|
-
*
|
|
13251
|
-
* Typical usage:
|
|
13252
|
-
*
|
|
13253
|
-
* ```js
|
|
13254
|
-
* const report = htmlvalidate.validateFileSync("my-file.html");
|
|
13255
|
-
* for (const result of report.results){
|
|
13256
|
-
* const config = htmlvalidate.getConfigForSync(result.filePath);
|
|
13257
|
-
* for (const message of result.messages){
|
|
13258
|
-
* const documentation = htmlvalidate.getRuleDocumentationSync(message.ruleId, config, message.context);
|
|
13259
|
-
* // do something with documentation
|
|
13260
|
-
* }
|
|
13261
|
-
* }
|
|
13262
|
-
* ```
|
|
13263
|
-
*
|
|
13264
|
-
* @public
|
|
13265
|
-
* @deprecated Deprecated since 8.0.0, use [[getContextualDocumentationSync]] instead.
|
|
13266
|
-
* @param ruleId - Rule to get documentation for.
|
|
13267
|
-
* @param config - If set it provides more accurate description by using the
|
|
13268
|
-
* correct configuration for the file.
|
|
13269
|
-
* @param context - If set to `Message.context` some rules can provide
|
|
13270
|
-
* contextual details and suggestions.
|
|
13271
|
-
*/
|
|
13272
|
-
getRuleDocumentationSync(ruleId, config = null, context = null) {
|
|
13273
|
-
const c = config ?? this.getConfigForSync("inline");
|
|
13274
|
-
const engine = new Engine(c, Parser);
|
|
13275
|
-
return engine.getRuleDocumentation({ ruleId, context });
|
|
13276
|
-
}
|
|
13277
|
-
/**
|
|
13278
|
-
* Create a parser configured for given filename.
|
|
13279
|
-
*
|
|
13280
|
-
* @internal
|
|
13281
|
-
* @param source - Source to use.
|
|
13282
|
-
*/
|
|
13283
|
-
async getParserFor(source) {
|
|
13284
|
-
const config = await this.getConfigFor(source.filename);
|
|
13285
|
-
return new Parser(config);
|
|
13286
|
-
}
|
|
13287
|
-
/**
|
|
13288
|
-
* Get configuration for given filename.
|
|
13289
|
-
*
|
|
13290
|
-
* See [[FileSystemConfigLoader]] for details.
|
|
13291
|
-
*
|
|
13292
|
-
* @public
|
|
13293
|
-
* @param filename - Filename to get configuration for.
|
|
13294
|
-
* @param configOverride - Configuration to apply last.
|
|
13295
|
-
*/
|
|
13296
|
-
getConfigFor(filename, configOverride) {
|
|
13297
|
-
const config = this.configLoader.getConfigFor(filename, configOverride);
|
|
13298
|
-
return Promise.resolve(config);
|
|
13299
|
-
}
|
|
13300
|
-
/**
|
|
13301
|
-
* Get configuration for given filename.
|
|
13302
|
-
*
|
|
13303
|
-
* See [[FileSystemConfigLoader]] for details.
|
|
13304
|
-
*
|
|
13305
|
-
* @public
|
|
13306
|
-
* @param filename - Filename to get configuration for.
|
|
13307
|
-
* @param configOverride - Configuration to apply last.
|
|
13308
|
-
*/
|
|
13309
|
-
getConfigForSync(filename, configOverride) {
|
|
13310
|
-
const config = this.configLoader.getConfigFor(filename, configOverride);
|
|
13311
|
-
if (isThenable(config)) {
|
|
13312
|
-
throw new UserError("Cannot use asynchronous config loader with synchronous api");
|
|
13313
|
-
}
|
|
13314
|
-
return config;
|
|
13315
|
-
}
|
|
13316
|
-
/**
|
|
13317
|
-
* Get current configuration loader.
|
|
13318
|
-
*
|
|
13319
|
-
* @public
|
|
13320
|
-
* @since %version%
|
|
13321
|
-
* @returns Current configuration loader.
|
|
13322
|
-
*/
|
|
13323
|
-
/* istanbul ignore next -- not testing setters/getters */
|
|
13324
|
-
getConfigLoader() {
|
|
13325
|
-
return this.configLoader;
|
|
13326
|
-
}
|
|
13327
|
-
/**
|
|
13328
|
-
* Set configuration loader.
|
|
13329
|
-
*
|
|
13330
|
-
* @public
|
|
13331
|
-
* @since %version%
|
|
13332
|
-
* @param loader - New configuration loader to use.
|
|
13333
|
-
*/
|
|
13334
|
-
/* istanbul ignore next -- not testing setters/getters */
|
|
13335
|
-
setConfigLoader(loader) {
|
|
13336
|
-
this.configLoader = loader;
|
|
13337
|
-
}
|
|
13338
|
-
/**
|
|
13339
|
-
* Flush configuration cache. Clears full cache unless a filename is given.
|
|
13340
|
-
*
|
|
13341
|
-
* See [[FileSystemConfigLoader]] for details.
|
|
13342
|
-
*
|
|
13343
|
-
* @public
|
|
13344
|
-
* @param filename - If set, only flush cache for given filename.
|
|
13345
|
-
*/
|
|
13346
|
-
flushConfigCache(filename) {
|
|
13347
|
-
this.configLoader.flushCache(filename);
|
|
13348
|
-
}
|
|
13349
|
-
}
|
|
13350
|
-
|
|
13351
|
-
const name = "html-validate";
|
|
13352
|
-
const version = "9.2.2";
|
|
13353
|
-
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
13354
|
-
|
|
13355
|
-
function definePlugin(plugin) {
|
|
13356
|
-
return plugin;
|
|
13357
|
-
}
|
|
13358
|
-
|
|
13359
12945
|
const entities = {
|
|
13360
12946
|
">": ">",
|
|
13361
12947
|
"<": "<",
|
|
@@ -14471,9 +14057,9 @@ exports.DOMNode = DOMNode;
|
|
|
14471
14057
|
exports.DOMTokenList = DOMTokenList;
|
|
14472
14058
|
exports.DOMTree = DOMTree;
|
|
14473
14059
|
exports.DynamicValue = DynamicValue;
|
|
14060
|
+
exports.Engine = Engine;
|
|
14474
14061
|
exports.EventHandler = EventHandler;
|
|
14475
14062
|
exports.HtmlElement = HtmlElement;
|
|
14476
|
-
exports.HtmlValidate = HtmlValidate;
|
|
14477
14063
|
exports.MetaCopyableProperty = MetaCopyableProperty;
|
|
14478
14064
|
exports.MetaTable = MetaTable;
|
|
14479
14065
|
exports.NestedError = NestedError;
|
|
@@ -14497,6 +14083,7 @@ exports.bugs = bugs;
|
|
|
14497
14083
|
exports.classifyNodeText = classifyNodeText;
|
|
14498
14084
|
exports.codeframe = codeframe;
|
|
14499
14085
|
exports.compatibilityCheckImpl = compatibilityCheckImpl;
|
|
14086
|
+
exports.configurationSchema = configurationSchema;
|
|
14500
14087
|
exports.deepmerge = deepmerge;
|
|
14501
14088
|
exports.defineConfig = defineConfig;
|
|
14502
14089
|
exports.definePlugin = definePlugin;
|
|
@@ -14508,10 +14095,15 @@ exports.isThenable = isThenable;
|
|
|
14508
14095
|
exports.isUserError = isUserError;
|
|
14509
14096
|
exports.keywordPatternMatcher = keywordPatternMatcher;
|
|
14510
14097
|
exports.name = name;
|
|
14098
|
+
exports.normalizeSource = normalizeSource;
|
|
14511
14099
|
exports.presets = presets;
|
|
14512
14100
|
exports.ruleExists = ruleExists;
|
|
14513
14101
|
exports.sliceLocation = sliceLocation;
|
|
14514
14102
|
exports.staticResolver = staticResolver;
|
|
14103
|
+
exports.transformFilename = transformFilename;
|
|
14104
|
+
exports.transformFilenameSync = transformFilenameSync;
|
|
14105
|
+
exports.transformSource = transformSource;
|
|
14106
|
+
exports.transformSourceSync = transformSourceSync;
|
|
14515
14107
|
exports.version = version;
|
|
14516
14108
|
exports.walk = walk;
|
|
14517
14109
|
exports.workerPath = workerPath;
|