html-validate 10.7.0 → 10.9.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 +271 -23
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +6 -2
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/esm/browser.js +1 -1
- package/dist/esm/cli.js +2 -2
- package/dist/esm/core-browser.js +1 -1
- package/dist/esm/core-nodejs.js +1 -1
- package/dist/esm/core.js +272 -24
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/elements.js +6 -2
- package/dist/esm/elements.js.map +1 -1
- package/dist/esm/html-validate.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +1 -1
package/dist/cjs/core.js
CHANGED
|
@@ -4008,7 +4008,7 @@ class Rule {
|
|
|
4008
4008
|
}
|
|
4009
4009
|
}
|
|
4010
4010
|
|
|
4011
|
-
const defaults$
|
|
4011
|
+
const defaults$B = {
|
|
4012
4012
|
allowExternal: true,
|
|
4013
4013
|
allowRelative: true,
|
|
4014
4014
|
allowAbsolute: true,
|
|
@@ -4052,7 +4052,7 @@ class AllowedLinks extends Rule {
|
|
|
4052
4052
|
allowRelative;
|
|
4053
4053
|
allowAbsolute;
|
|
4054
4054
|
constructor(options) {
|
|
4055
|
-
super({ ...defaults$
|
|
4055
|
+
super({ ...defaults$B, ...options });
|
|
4056
4056
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
4057
4057
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
4058
4058
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -4220,7 +4220,7 @@ class AllowedLinks extends Rule {
|
|
|
4220
4220
|
}
|
|
4221
4221
|
}
|
|
4222
4222
|
|
|
4223
|
-
const defaults$
|
|
4223
|
+
const defaults$A = {
|
|
4224
4224
|
accessible: true
|
|
4225
4225
|
};
|
|
4226
4226
|
function findByTarget(target, siblings) {
|
|
@@ -4250,7 +4250,7 @@ function getDescription$1(context) {
|
|
|
4250
4250
|
}
|
|
4251
4251
|
class AreaAlt extends Rule {
|
|
4252
4252
|
constructor(options) {
|
|
4253
|
-
super({ ...defaults$
|
|
4253
|
+
super({ ...defaults$A, ...options });
|
|
4254
4254
|
}
|
|
4255
4255
|
static schema() {
|
|
4256
4256
|
return {
|
|
@@ -4329,7 +4329,7 @@ class AriaHiddenBody extends Rule {
|
|
|
4329
4329
|
}
|
|
4330
4330
|
}
|
|
4331
4331
|
|
|
4332
|
-
const defaults$
|
|
4332
|
+
const defaults$z = {
|
|
4333
4333
|
allowAnyNamable: false,
|
|
4334
4334
|
elements: {
|
|
4335
4335
|
include: null,
|
|
@@ -4377,7 +4377,7 @@ function isValidUsage(target, meta) {
|
|
|
4377
4377
|
}
|
|
4378
4378
|
class AriaLabelMisuse extends Rule {
|
|
4379
4379
|
constructor(options) {
|
|
4380
|
-
super({ ...defaults$
|
|
4380
|
+
super({ ...defaults$z, ...options });
|
|
4381
4381
|
}
|
|
4382
4382
|
static schema() {
|
|
4383
4383
|
return {
|
|
@@ -4546,14 +4546,14 @@ class CaseStyle {
|
|
|
4546
4546
|
}
|
|
4547
4547
|
}
|
|
4548
4548
|
|
|
4549
|
-
const defaults$
|
|
4549
|
+
const defaults$y = {
|
|
4550
4550
|
style: "lowercase",
|
|
4551
4551
|
ignoreForeign: true
|
|
4552
4552
|
};
|
|
4553
4553
|
class AttrCase extends Rule {
|
|
4554
4554
|
style;
|
|
4555
4555
|
constructor(options) {
|
|
4556
|
-
super({ ...defaults$
|
|
4556
|
+
super({ ...defaults$y, ...options });
|
|
4557
4557
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
4558
4558
|
}
|
|
4559
4559
|
static schema() {
|
|
@@ -4958,7 +4958,7 @@ class AttrDelimiter extends Rule {
|
|
|
4958
4958
|
}
|
|
4959
4959
|
|
|
4960
4960
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4961
|
-
const defaults$
|
|
4961
|
+
const defaults$x = {
|
|
4962
4962
|
pattern: DEFAULT_PATTERN,
|
|
4963
4963
|
ignoreForeign: true
|
|
4964
4964
|
};
|
|
@@ -4991,7 +4991,7 @@ function generateDescription(name, pattern) {
|
|
|
4991
4991
|
class AttrPattern extends Rule {
|
|
4992
4992
|
pattern;
|
|
4993
4993
|
constructor(options) {
|
|
4994
|
-
super({ ...defaults$
|
|
4994
|
+
super({ ...defaults$x, ...options });
|
|
4995
4995
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4996
4996
|
}
|
|
4997
4997
|
static schema() {
|
|
@@ -5038,7 +5038,7 @@ class AttrPattern extends Rule {
|
|
|
5038
5038
|
}
|
|
5039
5039
|
}
|
|
5040
5040
|
|
|
5041
|
-
const defaults$
|
|
5041
|
+
const defaults$w = {
|
|
5042
5042
|
style: "auto",
|
|
5043
5043
|
unquoted: false
|
|
5044
5044
|
};
|
|
@@ -5104,7 +5104,7 @@ class AttrQuotes extends Rule {
|
|
|
5104
5104
|
};
|
|
5105
5105
|
}
|
|
5106
5106
|
constructor(options) {
|
|
5107
|
-
super({ ...defaults$
|
|
5107
|
+
super({ ...defaults$w, ...options });
|
|
5108
5108
|
this.style = parseStyle$3(this.options.style);
|
|
5109
5109
|
}
|
|
5110
5110
|
setup() {
|
|
@@ -5260,13 +5260,13 @@ class AttributeAllowedValues extends Rule {
|
|
|
5260
5260
|
}
|
|
5261
5261
|
}
|
|
5262
5262
|
|
|
5263
|
-
const defaults$
|
|
5263
|
+
const defaults$v = {
|
|
5264
5264
|
style: "omit"
|
|
5265
5265
|
};
|
|
5266
5266
|
class AttributeBooleanStyle extends Rule {
|
|
5267
5267
|
hasInvalidStyle;
|
|
5268
5268
|
constructor(options) {
|
|
5269
|
-
super({ ...defaults$
|
|
5269
|
+
super({ ...defaults$v, ...options });
|
|
5270
5270
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
5271
5271
|
}
|
|
5272
5272
|
static schema() {
|
|
@@ -5336,13 +5336,13 @@ function reportMessage$1(attr, style) {
|
|
|
5336
5336
|
return "";
|
|
5337
5337
|
}
|
|
5338
5338
|
|
|
5339
|
-
const defaults$
|
|
5339
|
+
const defaults$u = {
|
|
5340
5340
|
style: "omit"
|
|
5341
5341
|
};
|
|
5342
5342
|
class AttributeEmptyStyle extends Rule {
|
|
5343
5343
|
hasInvalidStyle;
|
|
5344
5344
|
constructor(options) {
|
|
5345
|
-
super({ ...defaults$
|
|
5345
|
+
super({ ...defaults$u, ...options });
|
|
5346
5346
|
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
5347
5347
|
}
|
|
5348
5348
|
static schema() {
|
|
@@ -5459,6 +5459,122 @@ class AttributeMisuse extends Rule {
|
|
|
5459
5459
|
}
|
|
5460
5460
|
}
|
|
5461
5461
|
|
|
5462
|
+
const defaults$t = {
|
|
5463
|
+
preferred: void 0
|
|
5464
|
+
};
|
|
5465
|
+
function isPasswordInput(event) {
|
|
5466
|
+
const { target } = event;
|
|
5467
|
+
if (!target.is("input")) {
|
|
5468
|
+
return false;
|
|
5469
|
+
}
|
|
5470
|
+
const type = target.getAttribute("type");
|
|
5471
|
+
return type?.value?.toString().toLowerCase() === "password";
|
|
5472
|
+
}
|
|
5473
|
+
function isGroupingToken(token) {
|
|
5474
|
+
return token.startsWith("section-") || token === "shipping" || token === "billing";
|
|
5475
|
+
}
|
|
5476
|
+
class AutocompletePassword extends Rule {
|
|
5477
|
+
preferred;
|
|
5478
|
+
constructor(options) {
|
|
5479
|
+
super({ ...defaults$t, ...options });
|
|
5480
|
+
this.preferred = options.preferred?.toLowerCase();
|
|
5481
|
+
}
|
|
5482
|
+
static schema() {
|
|
5483
|
+
return {
|
|
5484
|
+
preferred: {
|
|
5485
|
+
type: "string"
|
|
5486
|
+
}
|
|
5487
|
+
};
|
|
5488
|
+
}
|
|
5489
|
+
documentation(context) {
|
|
5490
|
+
const url = "https://html-validate.org/rules/autocomplete-password.html";
|
|
5491
|
+
switch (context.kind) {
|
|
5492
|
+
case "preferred-mismatch":
|
|
5493
|
+
return {
|
|
5494
|
+
description: [
|
|
5495
|
+
`\`<input type="password">\` should use \`autocomplete="${context.preferred}"\`.`,
|
|
5496
|
+
"",
|
|
5497
|
+
`The configured preferred autocomplete value is \`"${context.preferred}"\` but the element uses \`"${context.value}"\`.`
|
|
5498
|
+
].join("\n"),
|
|
5499
|
+
url
|
|
5500
|
+
};
|
|
5501
|
+
case "off":
|
|
5502
|
+
case "missing":
|
|
5503
|
+
default: {
|
|
5504
|
+
const error = context.kind === "off" ? '`<input type="password">` should not use `autocomplete="off"`.' : '`<input type="password">` must have the `autocomplete` attribute.';
|
|
5505
|
+
return {
|
|
5506
|
+
description: [
|
|
5507
|
+
error,
|
|
5508
|
+
"",
|
|
5509
|
+
"Browsers and password managers often ignore the absence of autocomplete and autofill password fields anyway, which can lead to unexpected behavior where users unknowingly submit autofilled passwords for unrelated fields.",
|
|
5510
|
+
"",
|
|
5511
|
+
"Use one of the following values:",
|
|
5512
|
+
"",
|
|
5513
|
+
'- `autocomplete="new-password"` for password creation forms',
|
|
5514
|
+
'- `autocomplete="current-password"` for login forms'
|
|
5515
|
+
].join("\n"),
|
|
5516
|
+
url
|
|
5517
|
+
};
|
|
5518
|
+
}
|
|
5519
|
+
}
|
|
5520
|
+
}
|
|
5521
|
+
setup() {
|
|
5522
|
+
this.on("tag:ready", isPasswordInput, (event) => {
|
|
5523
|
+
const { preferred } = this;
|
|
5524
|
+
const { target } = event;
|
|
5525
|
+
const autocomplete = target.getAttribute("autocomplete");
|
|
5526
|
+
if (!autocomplete) {
|
|
5527
|
+
const context = { kind: "missing" };
|
|
5528
|
+
this.report({
|
|
5529
|
+
node: target,
|
|
5530
|
+
message: '<input type="password"> is missing required "autocomplete" attribute',
|
|
5531
|
+
location: target.location,
|
|
5532
|
+
context
|
|
5533
|
+
});
|
|
5534
|
+
return;
|
|
5535
|
+
}
|
|
5536
|
+
if (autocomplete.isDynamic || !autocomplete.value) {
|
|
5537
|
+
return;
|
|
5538
|
+
}
|
|
5539
|
+
const raw = autocomplete.value.toString().toLowerCase();
|
|
5540
|
+
const tokens = new DOMTokenList(raw, autocomplete.valueLocation);
|
|
5541
|
+
const index = tokens.findIndex((token) => !isGroupingToken(token));
|
|
5542
|
+
const value = tokens.item(index);
|
|
5543
|
+
const location = tokens.location(index);
|
|
5544
|
+
if (!value) {
|
|
5545
|
+
return;
|
|
5546
|
+
}
|
|
5547
|
+
if (value === "off") {
|
|
5548
|
+
const context = { kind: "off" };
|
|
5549
|
+
this.report({
|
|
5550
|
+
node: target,
|
|
5551
|
+
message: '<input type="password"> should not use autocomplete="off"',
|
|
5552
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- location must be present if value is */
|
|
5553
|
+
location,
|
|
5554
|
+
context
|
|
5555
|
+
});
|
|
5556
|
+
return;
|
|
5557
|
+
}
|
|
5558
|
+
if (preferred) {
|
|
5559
|
+
if (value !== preferred) {
|
|
5560
|
+
const context = {
|
|
5561
|
+
kind: "preferred-mismatch",
|
|
5562
|
+
value,
|
|
5563
|
+
preferred
|
|
5564
|
+
};
|
|
5565
|
+
this.report({
|
|
5566
|
+
node: target,
|
|
5567
|
+
message: `<input type="password"> should use autocomplete="${preferred}"`,
|
|
5568
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- location must be present if value is */
|
|
5569
|
+
location,
|
|
5570
|
+
context
|
|
5571
|
+
});
|
|
5572
|
+
}
|
|
5573
|
+
}
|
|
5574
|
+
});
|
|
5575
|
+
}
|
|
5576
|
+
}
|
|
5577
|
+
|
|
5462
5578
|
const patternNamesValues = [
|
|
5463
5579
|
"kebabcase",
|
|
5464
5580
|
"camelcase",
|
|
@@ -5590,7 +5706,7 @@ class BasePatternRule extends Rule {
|
|
|
5590
5706
|
}
|
|
5591
5707
|
}
|
|
5592
5708
|
|
|
5593
|
-
const defaults$
|
|
5709
|
+
const defaults$s = {
|
|
5594
5710
|
pattern: "kebabcase"
|
|
5595
5711
|
};
|
|
5596
5712
|
class ClassPattern extends BasePatternRule {
|
|
@@ -5598,7 +5714,7 @@ class ClassPattern extends BasePatternRule {
|
|
|
5598
5714
|
super({
|
|
5599
5715
|
ruleId: "class-pattern",
|
|
5600
5716
|
attr: "class",
|
|
5601
|
-
options: { ...defaults$
|
|
5717
|
+
options: { ...defaults$s, ...options },
|
|
5602
5718
|
allowedPatterns: patternNames
|
|
5603
5719
|
// allow all patterns
|
|
5604
5720
|
});
|
|
@@ -5748,13 +5864,13 @@ class CloseOrder extends Rule {
|
|
|
5748
5864
|
}
|
|
5749
5865
|
}
|
|
5750
5866
|
|
|
5751
|
-
const defaults$
|
|
5867
|
+
const defaults$r = {
|
|
5752
5868
|
include: null,
|
|
5753
5869
|
exclude: null
|
|
5754
5870
|
};
|
|
5755
5871
|
class Deprecated extends Rule {
|
|
5756
5872
|
constructor(options) {
|
|
5757
|
-
super({ ...defaults$
|
|
5873
|
+
super({ ...defaults$r, ...options });
|
|
5758
5874
|
}
|
|
5759
5875
|
static schema() {
|
|
5760
5876
|
return {
|
|
@@ -5862,6 +5978,137 @@ function prettySource(source) {
|
|
|
5862
5978
|
}
|
|
5863
5979
|
}
|
|
5864
5980
|
|
|
5981
|
+
function quote(value, char = '"') {
|
|
5982
|
+
return `${char}${value}${char}`;
|
|
5983
|
+
}
|
|
5984
|
+
|
|
5985
|
+
const defaults$q = {
|
|
5986
|
+
classes: []
|
|
5987
|
+
};
|
|
5988
|
+
function isRelevant$6(event) {
|
|
5989
|
+
return event.key.toLowerCase() === "class";
|
|
5990
|
+
}
|
|
5991
|
+
function normalizeEntry(entry) {
|
|
5992
|
+
const { class: className, message, replacement = [], url } = entry;
|
|
5993
|
+
return {
|
|
5994
|
+
class: className,
|
|
5995
|
+
message,
|
|
5996
|
+
replacement: Array.isArray(replacement) ? replacement : [replacement],
|
|
5997
|
+
url
|
|
5998
|
+
};
|
|
5999
|
+
}
|
|
6000
|
+
function formatDeprecatedMessage(className, entry) {
|
|
6001
|
+
let message = `class "${className}" is deprecated`;
|
|
6002
|
+
if (entry.replacement.length > 0) {
|
|
6003
|
+
const joined = utils_naturalJoin.naturalJoin(
|
|
6004
|
+
entry.replacement.map((r) => quote(r)),
|
|
6005
|
+
"or"
|
|
6006
|
+
);
|
|
6007
|
+
message += ` and replaced with ${joined}`;
|
|
6008
|
+
}
|
|
6009
|
+
if (entry.message) {
|
|
6010
|
+
message += `: ${entry.message}`;
|
|
6011
|
+
}
|
|
6012
|
+
return message;
|
|
6013
|
+
}
|
|
6014
|
+
function formatDocumentationDescription(context) {
|
|
6015
|
+
const text = [];
|
|
6016
|
+
const className = context.class;
|
|
6017
|
+
let description = `The class \`${className}\` is deprecated and should not be used`;
|
|
6018
|
+
if (context.message) {
|
|
6019
|
+
description += `: ${context.message}.`;
|
|
6020
|
+
} else {
|
|
6021
|
+
description += ".";
|
|
6022
|
+
}
|
|
6023
|
+
text.push(description);
|
|
6024
|
+
if (context.replacement.length === 1) {
|
|
6025
|
+
text.push(`Use the replacement class ${quote(context.replacement[0], "`")} instead.`);
|
|
6026
|
+
} else if (context.replacement.length > 1) {
|
|
6027
|
+
const listItems = context.replacement.map((r) => `- ${quote(r, "`")}`);
|
|
6028
|
+
text.push(`Use one of the following replacement classes instead:
|
|
6029
|
+
${listItems.join("\n")}`);
|
|
6030
|
+
}
|
|
6031
|
+
if (context.url) {
|
|
6032
|
+
text.push(`For details see: ${context.url}`);
|
|
6033
|
+
}
|
|
6034
|
+
return text.join("\n\n");
|
|
6035
|
+
}
|
|
6036
|
+
class DeprecatedClass extends Rule {
|
|
6037
|
+
deprecatedMap;
|
|
6038
|
+
constructor(options) {
|
|
6039
|
+
super({ ...defaults$q, ...options });
|
|
6040
|
+
const { classes } = this.options;
|
|
6041
|
+
this.deprecatedMap = new Map(classes.map((entry) => [entry.class, normalizeEntry(entry)]));
|
|
6042
|
+
}
|
|
6043
|
+
static schema() {
|
|
6044
|
+
return {
|
|
6045
|
+
classes: {
|
|
6046
|
+
type: "array",
|
|
6047
|
+
items: {
|
|
6048
|
+
type: "object",
|
|
6049
|
+
properties: {
|
|
6050
|
+
class: {
|
|
6051
|
+
type: "string"
|
|
6052
|
+
},
|
|
6053
|
+
message: {
|
|
6054
|
+
type: "string"
|
|
6055
|
+
},
|
|
6056
|
+
replacement: {
|
|
6057
|
+
anyOf: [
|
|
6058
|
+
{
|
|
6059
|
+
type: "string"
|
|
6060
|
+
},
|
|
6061
|
+
{
|
|
6062
|
+
type: "array",
|
|
6063
|
+
items: {
|
|
6064
|
+
type: "string"
|
|
6065
|
+
}
|
|
6066
|
+
}
|
|
6067
|
+
]
|
|
6068
|
+
},
|
|
6069
|
+
url: {
|
|
6070
|
+
type: "string"
|
|
6071
|
+
}
|
|
6072
|
+
},
|
|
6073
|
+
required: ["class"],
|
|
6074
|
+
additionalProperties: false
|
|
6075
|
+
}
|
|
6076
|
+
}
|
|
6077
|
+
};
|
|
6078
|
+
}
|
|
6079
|
+
documentation(context) {
|
|
6080
|
+
return {
|
|
6081
|
+
description: formatDocumentationDescription(context),
|
|
6082
|
+
url: "https://html-validate.org/rules/deprecated-class.html"
|
|
6083
|
+
};
|
|
6084
|
+
}
|
|
6085
|
+
setup() {
|
|
6086
|
+
this.on("attr", isRelevant$6, (event) => {
|
|
6087
|
+
const { value, valueLocation, target } = event;
|
|
6088
|
+
const classes = new DOMTokenList(value, valueLocation);
|
|
6089
|
+
for (const { item, location } of classes.iterator()) {
|
|
6090
|
+
const deprecatedEntry = this.deprecatedMap.get(item);
|
|
6091
|
+
if (!deprecatedEntry) {
|
|
6092
|
+
continue;
|
|
6093
|
+
}
|
|
6094
|
+
const message = formatDeprecatedMessage(item, deprecatedEntry);
|
|
6095
|
+
const context = {
|
|
6096
|
+
class: item,
|
|
6097
|
+
message: deprecatedEntry.message ?? null,
|
|
6098
|
+
replacement: deprecatedEntry.replacement,
|
|
6099
|
+
url: deprecatedEntry.url ?? null
|
|
6100
|
+
};
|
|
6101
|
+
this.report({
|
|
6102
|
+
node: target,
|
|
6103
|
+
message,
|
|
6104
|
+
location,
|
|
6105
|
+
context
|
|
6106
|
+
});
|
|
6107
|
+
}
|
|
6108
|
+
});
|
|
6109
|
+
}
|
|
6110
|
+
}
|
|
6111
|
+
|
|
5865
6112
|
class DeprecatedRule extends Rule {
|
|
5866
6113
|
documentation(context) {
|
|
5867
6114
|
const preamble = context ? `The rule "${context}"` : "This rule";
|
|
@@ -9755,9 +10002,7 @@ const fieldNameGroup = {
|
|
|
9755
10002
|
nickname: "text",
|
|
9756
10003
|
username: "username",
|
|
9757
10004
|
"new-password": "password",
|
|
9758
|
-
// eslint-disable-line sonarjs/no-hardcoded-passwords -- false positive, it is not used as a password
|
|
9759
10005
|
"current-password": "password",
|
|
9760
|
-
// eslint-disable-line sonarjs/no-hardcoded-passwords -- false positive, it is not used as a password
|
|
9761
10006
|
"one-time-code": "password",
|
|
9762
10007
|
"organization-title": "text",
|
|
9763
10008
|
organization: "text",
|
|
@@ -10799,10 +11044,12 @@ const bundledRules = {
|
|
|
10799
11044
|
"attribute-boolean-style": AttributeBooleanStyle,
|
|
10800
11045
|
"attribute-empty-style": AttributeEmptyStyle,
|
|
10801
11046
|
"attribute-misuse": AttributeMisuse,
|
|
11047
|
+
"autocomplete-password": AutocompletePassword,
|
|
10802
11048
|
"class-pattern": ClassPattern,
|
|
10803
11049
|
"close-attr": CloseAttr,
|
|
10804
11050
|
"close-order": CloseOrder,
|
|
10805
11051
|
deprecated: Deprecated,
|
|
11052
|
+
"deprecated-class": DeprecatedClass,
|
|
10806
11053
|
"deprecated-rule": DeprecatedRule,
|
|
10807
11054
|
"doctype-html": NoStyleTag$1,
|
|
10808
11055
|
"doctype-style": DoctypeStyle,
|
|
@@ -11164,6 +11411,7 @@ const config$1 = {
|
|
|
11164
11411
|
"attribute-boolean-style": "error",
|
|
11165
11412
|
"attribute-empty-style": "error",
|
|
11166
11413
|
"attribute-misuse": "error",
|
|
11414
|
+
"autocomplete-password": "error",
|
|
11167
11415
|
"close-attr": "error",
|
|
11168
11416
|
"close-order": "error",
|
|
11169
11417
|
deprecated: "error",
|
|
@@ -12178,7 +12426,7 @@ class EventHandler {
|
|
|
12178
12426
|
}
|
|
12179
12427
|
|
|
12180
12428
|
const name = "html-validate";
|
|
12181
|
-
const version = "10.
|
|
12429
|
+
const version = "10.9.0";
|
|
12182
12430
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12183
12431
|
|
|
12184
12432
|
function freeze(src) {
|