html-validate 7.16.0 → 7.17.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/core.js +86 -73
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/es/core.js +86 -73
- package/dist/es/core.js.map +1 -1
- package/dist/schema/config.json +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +3 -10
- package/dist/types/index.d.ts +3 -10
- package/package.json +9 -9
package/dist/es/core.js
CHANGED
|
@@ -1832,28 +1832,6 @@ function cyrb53(str) {
|
|
|
1832
1832
|
}
|
|
1833
1833
|
const computeHash = cyrb53;
|
|
1834
1834
|
|
|
1835
|
-
const legacyRequire = createRequire(import.meta.url);
|
|
1836
|
-
|
|
1837
|
-
/**
|
|
1838
|
-
* Similar to `require(..)` but removes the cached copy first.
|
|
1839
|
-
*/
|
|
1840
|
-
function requireUncached(moduleId) {
|
|
1841
|
-
const filename = legacyRequire.resolve(moduleId);
|
|
1842
|
-
/* remove references from the parent module to prevent memory leak */
|
|
1843
|
-
const m = legacyRequire.cache[filename];
|
|
1844
|
-
if (m && m.parent) {
|
|
1845
|
-
const { parent } = m;
|
|
1846
|
-
for (let i = parent.children.length - 1; i >= 0; i--) {
|
|
1847
|
-
if (parent.children[i].id === filename) {
|
|
1848
|
-
parent.children.splice(i, 1);
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
/* remove old module from cache */
|
|
1853
|
-
delete legacyRequire.cache[filename];
|
|
1854
|
-
return legacyRequire(filename);
|
|
1855
|
-
}
|
|
1856
|
-
|
|
1857
1835
|
const $schema$1 = "http://json-schema.org/draft-06/schema#";
|
|
1858
1836
|
const $id$1 = "https://html-validate.org/schemas/elements.json";
|
|
1859
1837
|
const type$1 = "object";
|
|
@@ -2503,29 +2481,18 @@ class MetaTable {
|
|
|
2503
2481
|
*/
|
|
2504
2482
|
loadFromObject(obj, filename = null) {
|
|
2505
2483
|
var _a;
|
|
2506
|
-
const validate = this.getSchemaValidator();
|
|
2507
|
-
if (!validate(obj)) {
|
|
2508
|
-
throw new SchemaValidationError(filename, `Element metadata is not valid`, obj, this.schema,
|
|
2509
|
-
/* istanbul ignore next: AJV sets .errors when validate returns false */
|
|
2510
|
-
(_a = validate.errors) !== null && _a !== void 0 ? _a : []);
|
|
2511
|
-
}
|
|
2512
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
2513
|
-
if (key === "$schema")
|
|
2514
|
-
continue;
|
|
2515
|
-
this.addEntry(key, migrateElement(value));
|
|
2516
|
-
}
|
|
2517
|
-
}
|
|
2518
|
-
/**
|
|
2519
|
-
* Load metadata table from filename
|
|
2520
|
-
*
|
|
2521
|
-
* @public
|
|
2522
|
-
* @param filename - Filename to load
|
|
2523
|
-
*/
|
|
2524
|
-
loadFromFile(filename) {
|
|
2525
2484
|
try {
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2485
|
+
const validate = this.getSchemaValidator();
|
|
2486
|
+
if (!validate(obj)) {
|
|
2487
|
+
throw new SchemaValidationError(filename, `Element metadata is not valid`, obj, this.schema,
|
|
2488
|
+
/* istanbul ignore next: AJV sets .errors when validate returns false */
|
|
2489
|
+
(_a = validate.errors) !== null && _a !== void 0 ? _a : []);
|
|
2490
|
+
}
|
|
2491
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
2492
|
+
if (key === "$schema")
|
|
2493
|
+
continue;
|
|
2494
|
+
this.addEntry(key, migrateElement(value));
|
|
2495
|
+
}
|
|
2529
2496
|
}
|
|
2530
2497
|
catch (err) {
|
|
2531
2498
|
if (err instanceof InheritError) {
|
|
@@ -2535,6 +2502,9 @@ class MetaTable {
|
|
|
2535
2502
|
if (err instanceof SchemaValidationError) {
|
|
2536
2503
|
throw err;
|
|
2537
2504
|
}
|
|
2505
|
+
if (!filename) {
|
|
2506
|
+
throw err;
|
|
2507
|
+
}
|
|
2538
2508
|
throw new UserError(`Failed to load element metadata from "${filename}"`, ensureError(err));
|
|
2539
2509
|
}
|
|
2540
2510
|
}
|
|
@@ -3076,7 +3046,14 @@ const properties = {
|
|
|
3076
3046
|
plugins: {
|
|
3077
3047
|
type: "array",
|
|
3078
3048
|
items: {
|
|
3079
|
-
|
|
3049
|
+
anyOf: [
|
|
3050
|
+
{
|
|
3051
|
+
type: "string"
|
|
3052
|
+
},
|
|
3053
|
+
{
|
|
3054
|
+
type: "object"
|
|
3055
|
+
}
|
|
3056
|
+
]
|
|
3080
3057
|
},
|
|
3081
3058
|
title: "Plugins to load",
|
|
3082
3059
|
description: "Array of plugins load. Use <rootDir> to refer to the folder with the package.json file.",
|
|
@@ -3383,6 +3360,29 @@ var TRANSFORMER_API;
|
|
|
3383
3360
|
TRANSFORMER_API[TRANSFORMER_API["VERSION"] = 1] = "VERSION";
|
|
3384
3361
|
})(TRANSFORMER_API || (TRANSFORMER_API = {}));
|
|
3385
3362
|
|
|
3363
|
+
/**
|
|
3364
|
+
* Similar to `require(..)` but removes the cached copy first.
|
|
3365
|
+
*/
|
|
3366
|
+
function requireUncached(require, moduleId) {
|
|
3367
|
+
const filename = require.resolve(moduleId);
|
|
3368
|
+
/* remove references from the parent module to prevent memory leak */
|
|
3369
|
+
const m = require.cache[filename];
|
|
3370
|
+
if (m && m.parent) {
|
|
3371
|
+
const { parent } = m;
|
|
3372
|
+
for (let i = parent.children.length - 1; i >= 0; i--) {
|
|
3373
|
+
if (parent.children[i].id === filename) {
|
|
3374
|
+
parent.children.splice(i, 1);
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
/* remove old module from cache */
|
|
3379
|
+
delete require.cache[filename];
|
|
3380
|
+
/* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
|
|
3381
|
+
return require(filename);
|
|
3382
|
+
}
|
|
3383
|
+
|
|
3384
|
+
const legacyRequire = createRequire(import.meta.url);
|
|
3385
|
+
|
|
3386
3386
|
/**
|
|
3387
3387
|
* @public
|
|
3388
3388
|
*/
|
|
@@ -4087,6 +4087,29 @@ const whitelisted = [
|
|
|
4087
4087
|
"summary",
|
|
4088
4088
|
"figure",
|
|
4089
4089
|
];
|
|
4090
|
+
function isValidUsage(target, meta) {
|
|
4091
|
+
/* elements with explicit aria-label attribute are valid */
|
|
4092
|
+
if (meta.attributes["aria-label"]) {
|
|
4093
|
+
return true;
|
|
4094
|
+
}
|
|
4095
|
+
/* landmark and other whitelisted elements are valid */
|
|
4096
|
+
if (whitelisted.includes(target.tagName)) {
|
|
4097
|
+
return true;
|
|
4098
|
+
}
|
|
4099
|
+
/* elements with role are valid, @todo check if the role is widget or landmark */
|
|
4100
|
+
if (target.hasAttribute("role")) {
|
|
4101
|
+
return true;
|
|
4102
|
+
}
|
|
4103
|
+
/* elements with tabindex (implicit interactive) are valid */
|
|
4104
|
+
if (target.hasAttribute("tabindex")) {
|
|
4105
|
+
return true;
|
|
4106
|
+
}
|
|
4107
|
+
/* interactive and labelable elements are valid */
|
|
4108
|
+
if (meta.interactive || meta.labelable) {
|
|
4109
|
+
return true;
|
|
4110
|
+
}
|
|
4111
|
+
return false;
|
|
4112
|
+
}
|
|
4090
4113
|
class AriaLabelMisuse extends Rule {
|
|
4091
4114
|
documentation() {
|
|
4092
4115
|
const valid = [
|
|
@@ -4125,20 +4148,8 @@ class AriaLabelMisuse extends Rule {
|
|
|
4125
4148
|
if (!meta) {
|
|
4126
4149
|
return;
|
|
4127
4150
|
}
|
|
4128
|
-
/* ignore
|
|
4129
|
-
if (
|
|
4130
|
-
return;
|
|
4131
|
-
}
|
|
4132
|
-
/* ignore elements with role, @todo check if the role is widget or landmark */
|
|
4133
|
-
if (target.hasAttribute("role")) {
|
|
4134
|
-
return;
|
|
4135
|
-
}
|
|
4136
|
-
/* ignore elements with tabindex (implicit interactive) */
|
|
4137
|
-
if (target.hasAttribute("tabindex")) {
|
|
4138
|
-
return;
|
|
4139
|
-
}
|
|
4140
|
-
/* ignore interactive and labelable elements */
|
|
4141
|
-
if (meta.interactive || meta.labelable) {
|
|
4151
|
+
/* ignore elements which is valid usage */
|
|
4152
|
+
if (isValidUsage(target, meta)) {
|
|
4142
4153
|
return;
|
|
4143
4154
|
}
|
|
4144
4155
|
this.report(target, `"aria-label" cannot be used on this element`, attr.keyLocation);
|
|
@@ -9759,7 +9770,7 @@ function configDataFromFile(filename) {
|
|
|
9759
9770
|
try {
|
|
9760
9771
|
/* load using require as it can process both js and json */
|
|
9761
9772
|
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, should be refactored into something more typesafe */
|
|
9762
|
-
json = requireUncached(filename);
|
|
9773
|
+
json = requireUncached(legacyRequire, filename);
|
|
9763
9774
|
}
|
|
9764
9775
|
catch (err) {
|
|
9765
9776
|
throw new ConfigError(`Failed to read configuration from "${filename}"`, ensureError(err));
|
|
@@ -9930,7 +9941,6 @@ class Config {
|
|
|
9930
9941
|
/**
|
|
9931
9942
|
* Get element metadata.
|
|
9932
9943
|
*/
|
|
9933
|
-
/* eslint-disable-next-line complexity, sonarjs/cognitive-complexity -- technical debt, should be refactored */
|
|
9934
9944
|
getMetaTable() {
|
|
9935
9945
|
/* use cached table if it exists */
|
|
9936
9946
|
if (this.metaTable) {
|
|
@@ -9957,20 +9967,16 @@ class Config {
|
|
|
9957
9967
|
metaTable.loadFromObject(bundled);
|
|
9958
9968
|
continue;
|
|
9959
9969
|
}
|
|
9960
|
-
/* try as regular file */
|
|
9961
|
-
const filename = entry.replace("<rootDir>", this.rootDir);
|
|
9962
|
-
if (fs.existsSync(filename)) {
|
|
9963
|
-
metaTable.loadFromFile(filename);
|
|
9964
|
-
continue;
|
|
9965
|
-
}
|
|
9966
9970
|
/* assume it is loadable with require() */
|
|
9971
|
+
const id = entry.replace("<rootDir>", this.rootDir);
|
|
9967
9972
|
try {
|
|
9968
|
-
|
|
9973
|
+
const data = legacyRequire(id);
|
|
9974
|
+
metaTable.loadFromObject(data, id);
|
|
9969
9975
|
}
|
|
9970
9976
|
catch (err) {
|
|
9971
9977
|
/* istanbul ignore next: only used as a fallback */
|
|
9972
9978
|
const message = err instanceof Error ? err.message : String(err);
|
|
9973
|
-
throw new ConfigError(`Failed to load elements from "${
|
|
9979
|
+
throw new ConfigError(`Failed to load elements from "${id}": ${message}`, ensureError(err));
|
|
9974
9980
|
}
|
|
9975
9981
|
}
|
|
9976
9982
|
metaTable.init();
|
|
@@ -10040,7 +10046,13 @@ class Config {
|
|
|
10040
10046
|
return this.plugins;
|
|
10041
10047
|
}
|
|
10042
10048
|
loadPlugins(plugins) {
|
|
10043
|
-
return plugins.map((moduleName) => {
|
|
10049
|
+
return plugins.map((moduleName, index) => {
|
|
10050
|
+
if (typeof moduleName !== "string") {
|
|
10051
|
+
const plugin = moduleName;
|
|
10052
|
+
plugin.name = plugin.name || `:unnamedPlugin@${index + 1}`;
|
|
10053
|
+
plugin.originalName = `:unnamedPlugin@${index + 1}`;
|
|
10054
|
+
return plugin;
|
|
10055
|
+
}
|
|
10044
10056
|
try {
|
|
10045
10057
|
const plugin = legacyRequire(moduleName.replace("<rootDir>", this.rootDir));
|
|
10046
10058
|
plugin.name = plugin.name || moduleName;
|
|
@@ -10127,6 +10139,7 @@ class Config {
|
|
|
10127
10139
|
var _a;
|
|
10128
10140
|
try {
|
|
10129
10141
|
const fn = this.getTransformFunction(name);
|
|
10142
|
+
/* istanbul ignore next */
|
|
10130
10143
|
const version = (_a = fn.api) !== null && _a !== void 0 ? _a : 0;
|
|
10131
10144
|
/* check if transformer version is supported */
|
|
10132
10145
|
if (version !== TRANSFORMER_API.VERSION) {
|
|
@@ -11518,13 +11531,13 @@ class Engine {
|
|
|
11518
11531
|
* The static configuration loader does not do any per-handle lookup. Only the
|
|
11519
11532
|
* global or per-call configuration is used.
|
|
11520
11533
|
*
|
|
11521
|
-
* In practice this means no configuration is
|
|
11534
|
+
* In practice this means no configuration is fetched by traversing the
|
|
11522
11535
|
* filesystem.
|
|
11523
11536
|
*
|
|
11524
11537
|
* @public
|
|
11525
11538
|
*/
|
|
11526
11539
|
class StaticConfigLoader extends ConfigLoader {
|
|
11527
|
-
getConfigFor(
|
|
11540
|
+
getConfigFor(_handle, configOverride) {
|
|
11528
11541
|
const override = this.loadFromObject(configOverride || {});
|
|
11529
11542
|
if (override.isRootFound()) {
|
|
11530
11543
|
override.init();
|
|
@@ -11801,7 +11814,7 @@ class HtmlValidate {
|
|
|
11801
11814
|
/** @public */
|
|
11802
11815
|
const name = "html-validate";
|
|
11803
11816
|
/** @public */
|
|
11804
|
-
const version = "7.
|
|
11817
|
+
const version = "7.17.0";
|
|
11805
11818
|
/** @public */
|
|
11806
11819
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11807
11820
|
|