html-validate 7.12.2 → 7.13.1
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.d.ts +1 -1
- package/dist/cjs/browser.js +1 -0
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/cli.js +3 -6
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core.d.ts +213 -20
- package/dist/cjs/core.js +234 -25
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/html-validate.js +5 -5
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/browser.d.ts +1 -1
- package/dist/es/browser.js +1 -1
- package/dist/es/cli.js +2 -5
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core.d.ts +213 -20
- package/dist/es/core.js +234 -26
- package/dist/es/core.js.map +1 -1
- package/dist/es/html-validate.js +5 -5
- package/dist/es/index.d.ts +1 -1
- package/dist/es/index.js +1 -1
- package/package.json +9 -8
package/dist/cjs/core.js
CHANGED
|
@@ -543,6 +543,7 @@ class DOMNode {
|
|
|
543
543
|
this.nodeName = nodeName !== null && nodeName !== void 0 ? nodeName : DOCUMENT_NODE_NAME;
|
|
544
544
|
this.location = location;
|
|
545
545
|
this.disabledRules = new Set();
|
|
546
|
+
this.blockedRules = new Map();
|
|
546
547
|
this.childNodes = [];
|
|
547
548
|
this.unique = counter++;
|
|
548
549
|
this.cache = null;
|
|
@@ -618,14 +619,42 @@ class DOMNode {
|
|
|
618
619
|
get lastChild() {
|
|
619
620
|
return this.childNodes[this.childNodes.length - 1] || null;
|
|
620
621
|
}
|
|
622
|
+
/**
|
|
623
|
+
* Block a rule for this node.
|
|
624
|
+
*
|
|
625
|
+
* @internal
|
|
626
|
+
*/
|
|
627
|
+
blockRule(ruleId, blocker) {
|
|
628
|
+
const current = this.blockedRules.get(ruleId);
|
|
629
|
+
if (current) {
|
|
630
|
+
current.push(blocker);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
this.blockedRules.set(ruleId, [blocker]);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Blocks multiple rules.
|
|
638
|
+
*
|
|
639
|
+
* @internal
|
|
640
|
+
*/
|
|
641
|
+
blockRules(rules, blocker) {
|
|
642
|
+
for (const rule of rules) {
|
|
643
|
+
this.blockRule(rule, blocker);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
621
646
|
/**
|
|
622
647
|
* Disable a rule for this node.
|
|
648
|
+
*
|
|
649
|
+
* @internal
|
|
623
650
|
*/
|
|
624
651
|
disableRule(ruleId) {
|
|
625
652
|
this.disabledRules.add(ruleId);
|
|
626
653
|
}
|
|
627
654
|
/**
|
|
628
655
|
* Disables multiple rules.
|
|
656
|
+
*
|
|
657
|
+
* @internal
|
|
629
658
|
*/
|
|
630
659
|
disableRules(rules) {
|
|
631
660
|
for (const rule of rules) {
|
|
@@ -648,10 +677,21 @@ class DOMNode {
|
|
|
648
677
|
}
|
|
649
678
|
/**
|
|
650
679
|
* Test if a rule is enabled for this node.
|
|
680
|
+
*
|
|
681
|
+
* @internal
|
|
651
682
|
*/
|
|
652
683
|
ruleEnabled(ruleId) {
|
|
653
684
|
return !this.disabledRules.has(ruleId);
|
|
654
685
|
}
|
|
686
|
+
/**
|
|
687
|
+
* Test if a rule is blocked for this node.
|
|
688
|
+
*
|
|
689
|
+
* @internal
|
|
690
|
+
*/
|
|
691
|
+
ruleBlockers(ruleId) {
|
|
692
|
+
var _a;
|
|
693
|
+
return (_a = this.blockedRules.get(ruleId)) !== null && _a !== void 0 ? _a : [];
|
|
694
|
+
}
|
|
655
695
|
generateSelector() {
|
|
656
696
|
return null;
|
|
657
697
|
}
|
|
@@ -2707,6 +2747,8 @@ function matchAttributeFacade(node, match) {
|
|
|
2707
2747
|
const allowedKeys = ["exclude"];
|
|
2708
2748
|
/**
|
|
2709
2749
|
* Helper class to validate elements against metadata rules.
|
|
2750
|
+
*
|
|
2751
|
+
* @public
|
|
2710
2752
|
*/
|
|
2711
2753
|
class Validator {
|
|
2712
2754
|
/**
|
|
@@ -3462,6 +3504,7 @@ class Rule {
|
|
|
3462
3504
|
this.event = null;
|
|
3463
3505
|
this.options = options;
|
|
3464
3506
|
this.enabled = true;
|
|
3507
|
+
this.blockers = [];
|
|
3465
3508
|
this.severity = 0;
|
|
3466
3509
|
this.name = "";
|
|
3467
3510
|
}
|
|
@@ -3471,6 +3514,26 @@ class Rule {
|
|
|
3471
3514
|
setServerity(severity) {
|
|
3472
3515
|
this.severity = severity;
|
|
3473
3516
|
}
|
|
3517
|
+
/**
|
|
3518
|
+
* Block this rule from generating errors. Pass in an id generated by {@link
|
|
3519
|
+
* createBlocker}. Can be unblocked by {@link unblock}.
|
|
3520
|
+
*
|
|
3521
|
+
* A blocked rule is similar to disabling it but it will still receive parser
|
|
3522
|
+
* events. A list of all blockers is passed to the `rule:error` event.
|
|
3523
|
+
*
|
|
3524
|
+
* @internal
|
|
3525
|
+
*/
|
|
3526
|
+
block(id) {
|
|
3527
|
+
this.blockers.push(id);
|
|
3528
|
+
}
|
|
3529
|
+
/**
|
|
3530
|
+
* Unblock a rule previously blocked by {@link block}.
|
|
3531
|
+
*
|
|
3532
|
+
* @internal
|
|
3533
|
+
*/
|
|
3534
|
+
unblock(id) {
|
|
3535
|
+
this.blockers = this.blockers.filter((it) => it !== id);
|
|
3536
|
+
}
|
|
3474
3537
|
setEnabled(enabled) {
|
|
3475
3538
|
this.enabled = enabled;
|
|
3476
3539
|
}
|
|
@@ -3487,9 +3550,36 @@ class Rule {
|
|
|
3487
3550
|
*
|
|
3488
3551
|
* To be considered enabled the enabled flag must be true and the severity at
|
|
3489
3552
|
* least warning.
|
|
3553
|
+
*
|
|
3554
|
+
* @internal
|
|
3490
3555
|
*/
|
|
3491
|
-
isEnabled() {
|
|
3492
|
-
return this.enabled && this.severity >= exports.Severity.WARN;
|
|
3556
|
+
isEnabled(node) {
|
|
3557
|
+
return this.enabled && this.severity >= exports.Severity.WARN && (!node || node.ruleEnabled(this.name));
|
|
3558
|
+
}
|
|
3559
|
+
/**
|
|
3560
|
+
* Test if rule is enabled.
|
|
3561
|
+
*
|
|
3562
|
+
* To be considered enabled the enabled flag must be true and the severity at
|
|
3563
|
+
* least warning.
|
|
3564
|
+
*
|
|
3565
|
+
* @internal
|
|
3566
|
+
*/
|
|
3567
|
+
isBlocked(node) {
|
|
3568
|
+
if (this.blockers.length > 0) {
|
|
3569
|
+
return true;
|
|
3570
|
+
}
|
|
3571
|
+
if (node && node.ruleBlockers(this.name).length > 0) {
|
|
3572
|
+
return true;
|
|
3573
|
+
}
|
|
3574
|
+
return false;
|
|
3575
|
+
}
|
|
3576
|
+
/**
|
|
3577
|
+
* Get a list of all blockers currently active this rule.
|
|
3578
|
+
*
|
|
3579
|
+
* @internal
|
|
3580
|
+
*/
|
|
3581
|
+
getBlockers(node) {
|
|
3582
|
+
return [...this.blockers, ...(node ? node.ruleBlockers(this.name) : [])];
|
|
3493
3583
|
}
|
|
3494
3584
|
/**
|
|
3495
3585
|
* Check if keyword is being ignored by the current rule configuration.
|
|
@@ -3553,8 +3643,16 @@ class Rule {
|
|
|
3553
3643
|
}
|
|
3554
3644
|
report(...args) {
|
|
3555
3645
|
const { node, message, location, context } = unpackErrorDescriptor(args);
|
|
3556
|
-
|
|
3557
|
-
|
|
3646
|
+
const enabled = this.isEnabled(node);
|
|
3647
|
+
const blocked = this.isBlocked(node);
|
|
3648
|
+
const where = this.findLocation({ node, location, event: this.event });
|
|
3649
|
+
this.parser.trigger("rule:error", {
|
|
3650
|
+
location: where,
|
|
3651
|
+
ruleId: this.name,
|
|
3652
|
+
enabled,
|
|
3653
|
+
blockers: this.getBlockers(node),
|
|
3654
|
+
});
|
|
3655
|
+
if (enabled && !blocked) {
|
|
3558
3656
|
const interpolated = interpolate(message, context !== null && context !== void 0 ? context : {});
|
|
3559
3657
|
this.reporter.add(this, interpolated, this.severity, node, where, context);
|
|
3560
3658
|
}
|
|
@@ -4168,7 +4266,7 @@ const MATCH_SCRIPT_DATA = /^[^]*?(?=<\/script)/;
|
|
|
4168
4266
|
const MATCH_SCRIPT_END = /^<(\/)(script)/;
|
|
4169
4267
|
const MATCH_STYLE_DATA = /^[^]*?(?=<\/style)/;
|
|
4170
4268
|
const MATCH_STYLE_END = /^<(\/)(style)/;
|
|
4171
|
-
const MATCH_DIRECTIVE =
|
|
4269
|
+
const MATCH_DIRECTIVE = /^(<!--\s*\[html-validate-)([a-z0-9-]+)(\s*)(.*?)(]?\s*-->)/;
|
|
4172
4270
|
const MATCH_COMMENT = /^<!--([^]*?)-->/;
|
|
4173
4271
|
const MATCH_CONDITIONAL = /^<!\[([^\]]*?)\]>/;
|
|
4174
4272
|
class InvalidTokenError extends Error {
|
|
@@ -7668,6 +7766,39 @@ class NoUnknownElements extends Rule {
|
|
|
7668
7766
|
}
|
|
7669
7767
|
}
|
|
7670
7768
|
|
|
7769
|
+
class NoUnusedDisable extends Rule {
|
|
7770
|
+
documentation(context) {
|
|
7771
|
+
return {
|
|
7772
|
+
description: context
|
|
7773
|
+
? `\`${context.ruleId}\` rule is disabled but no error was reported.`
|
|
7774
|
+
: "Rule is disabled but no error was reported.",
|
|
7775
|
+
url: "https://html-validate.org/rules/no-unused-disable.html",
|
|
7776
|
+
};
|
|
7777
|
+
}
|
|
7778
|
+
setup() {
|
|
7779
|
+
/* this is a special rule, the `Engine` class directly emits errors on this
|
|
7780
|
+
* rule, it exists only to be able to configure whenever the rule is enabled
|
|
7781
|
+
* or not and to get the regular documentation and contextual help. */
|
|
7782
|
+
}
|
|
7783
|
+
reportUnused(unused, options, location) {
|
|
7784
|
+
const tokens = new DOMTokenList(options.replace(/,/g, " "), location);
|
|
7785
|
+
for (const ruleId of unused) {
|
|
7786
|
+
const index = tokens.indexOf(ruleId);
|
|
7787
|
+
/* istanbul ignore next: the token should be present or it wouldn't be
|
|
7788
|
+
* reported as unused, this is just a sanity check and fallback */
|
|
7789
|
+
const tokenLocation = index >= 0 ? tokens.location(index) : location;
|
|
7790
|
+
this.report({
|
|
7791
|
+
node: null,
|
|
7792
|
+
message: '"{{ ruleId }}" rule is disabled but no error was reported',
|
|
7793
|
+
location: tokenLocation,
|
|
7794
|
+
context: {
|
|
7795
|
+
ruleId: ruleId,
|
|
7796
|
+
},
|
|
7797
|
+
});
|
|
7798
|
+
}
|
|
7799
|
+
}
|
|
7800
|
+
}
|
|
7801
|
+
|
|
7671
7802
|
class NoUtf8Bom extends Rule {
|
|
7672
7803
|
documentation() {
|
|
7673
7804
|
return {
|
|
@@ -9291,6 +9422,7 @@ const bundledRules = {
|
|
|
9291
9422
|
"no-style-tag": NoStyleTag,
|
|
9292
9423
|
"no-trailing-whitespace": NoTrailingWhitespace,
|
|
9293
9424
|
"no-unknown-elements": NoUnknownElements,
|
|
9425
|
+
"no-unused-disable": NoUnusedDisable,
|
|
9294
9426
|
"no-utf8-bom": NoUtf8Bom,
|
|
9295
9427
|
"prefer-button": PreferButton,
|
|
9296
9428
|
"prefer-native-element": PreferNativeElement,
|
|
@@ -9401,6 +9533,7 @@ const config$1 = {
|
|
|
9401
9533
|
"no-self-closing": "error",
|
|
9402
9534
|
"no-trailing-whitespace": "error",
|
|
9403
9535
|
"no-utf8-bom": "error",
|
|
9536
|
+
"no-unused-disable": "error",
|
|
9404
9537
|
"prefer-button": "error",
|
|
9405
9538
|
"prefer-native-element": "error",
|
|
9406
9539
|
"prefer-tbody": "error",
|
|
@@ -9451,6 +9584,7 @@ const config = {
|
|
|
9451
9584
|
"no-dup-id": "error",
|
|
9452
9585
|
"no-multiple-main": "error",
|
|
9453
9586
|
"no-raw-characters": ["error", { relaxed: true }],
|
|
9587
|
+
"no-unused-disable": "error",
|
|
9454
9588
|
"script-element": "error",
|
|
9455
9589
|
"unrecognized-char-ref": "error",
|
|
9456
9590
|
"valid-id": ["error", { relaxed: true }],
|
|
@@ -10250,6 +10384,10 @@ class Parser {
|
|
|
10250
10384
|
offset: 0,
|
|
10251
10385
|
};
|
|
10252
10386
|
}
|
|
10387
|
+
/* trigger starting event */
|
|
10388
|
+
this.trigger("parse:begin", {
|
|
10389
|
+
location: null,
|
|
10390
|
+
});
|
|
10253
10391
|
/* reset DOM in case there are multiple calls in the same session */
|
|
10254
10392
|
this.dom = new DOMTree({
|
|
10255
10393
|
filename: (_a = source.filename) !== null && _a !== void 0 ? _a : "",
|
|
@@ -10284,6 +10422,10 @@ class Parser {
|
|
|
10284
10422
|
* instead */
|
|
10285
10423
|
location: null,
|
|
10286
10424
|
});
|
|
10425
|
+
/* trigger ending event */
|
|
10426
|
+
this.trigger("parse:end", {
|
|
10427
|
+
location: null,
|
|
10428
|
+
});
|
|
10287
10429
|
return this.dom.root;
|
|
10288
10430
|
}
|
|
10289
10431
|
/**
|
|
@@ -10594,11 +10736,11 @@ class Parser {
|
|
|
10594
10736
|
};
|
|
10595
10737
|
}
|
|
10596
10738
|
consumeDirective(token) {
|
|
10597
|
-
const [text, , action, directive,
|
|
10598
|
-
if (
|
|
10739
|
+
const [text, preamble, action, separator1, directive, postamble] = token.data;
|
|
10740
|
+
if (!postamble.startsWith("]")) {
|
|
10599
10741
|
throw new ParserError(token.location, `Missing end bracket "]" on directive "${text}"`);
|
|
10600
10742
|
}
|
|
10601
|
-
const match = directive.match(/^(.*?)(
|
|
10743
|
+
const match = directive.match(/^(.*?)(?:(\s*(?:--|:)\s*)(.*))?$/);
|
|
10602
10744
|
/* istanbul ignore next: should not be possible, would be emitted as comment token */
|
|
10603
10745
|
if (!match) {
|
|
10604
10746
|
throw new Error(`Failed to parse directive "${text}"`);
|
|
@@ -10606,12 +10748,32 @@ class Parser {
|
|
|
10606
10748
|
if (!isValidDirective(action)) {
|
|
10607
10749
|
throw new ParserError(token.location, `Unknown directive "${action}"`);
|
|
10608
10750
|
}
|
|
10609
|
-
const [, data, comment] = match;
|
|
10751
|
+
const [, data, separator2, comment] = match;
|
|
10752
|
+
const prefix = "html-validate-";
|
|
10753
|
+
/* <!-- [html-validate-action options -- comment] -->
|
|
10754
|
+
* ^ ^ ^--------------- comment offset
|
|
10755
|
+
* | \-------------------------- options offset
|
|
10756
|
+
* \--------------------------------- action offset
|
|
10757
|
+
*/
|
|
10758
|
+
const actionOffset = preamble.length;
|
|
10759
|
+
const optionsOffset = actionOffset + action.length + separator1.length;
|
|
10760
|
+
const commentOffset = optionsOffset + data.length + (separator2 || "").length;
|
|
10761
|
+
const location = sliceLocation(token.location, preamble.length - prefix.length - 1, -postamble.length + 1);
|
|
10762
|
+
const actionLocation = sliceLocation(token.location, actionOffset, actionOffset + action.length);
|
|
10763
|
+
const optionsLocation = data
|
|
10764
|
+
? sliceLocation(token.location, optionsOffset, optionsOffset + data.length)
|
|
10765
|
+
: undefined;
|
|
10766
|
+
const commentLocation = comment
|
|
10767
|
+
? sliceLocation(token.location, commentOffset, commentOffset + comment.length)
|
|
10768
|
+
: undefined;
|
|
10610
10769
|
this.trigger("directive", {
|
|
10611
10770
|
action,
|
|
10612
10771
|
data,
|
|
10613
10772
|
comment: comment || "",
|
|
10614
|
-
location
|
|
10773
|
+
location,
|
|
10774
|
+
actionLocation,
|
|
10775
|
+
optionsLocation,
|
|
10776
|
+
commentLocation,
|
|
10615
10777
|
});
|
|
10616
10778
|
}
|
|
10617
10779
|
/**
|
|
@@ -10897,6 +11059,18 @@ function messageSort(a, b) {
|
|
|
10897
11059
|
return 0;
|
|
10898
11060
|
}
|
|
10899
11061
|
|
|
11062
|
+
let blockerCounter = 1;
|
|
11063
|
+
/**
|
|
11064
|
+
* Creates a new rule blocker for using when blocking rules from generating
|
|
11065
|
+
* errors.
|
|
11066
|
+
*
|
|
11067
|
+
* @internal
|
|
11068
|
+
*/
|
|
11069
|
+
function createBlocker() {
|
|
11070
|
+
const id = blockerCounter++;
|
|
11071
|
+
return id;
|
|
11072
|
+
}
|
|
11073
|
+
|
|
10900
11074
|
/**
|
|
10901
11075
|
* @internal
|
|
10902
11076
|
*/
|
|
@@ -10924,6 +11098,15 @@ class Engine {
|
|
|
10924
11098
|
const parser = this.instantiateParser();
|
|
10925
11099
|
/* setup plugins and rules */
|
|
10926
11100
|
const { rules } = this.setupPlugins(source, this.config, parser);
|
|
11101
|
+
const noUnusedDisable = rules["no-unused-disable"];
|
|
11102
|
+
const directiveContext = {
|
|
11103
|
+
rules,
|
|
11104
|
+
reportUnused(rules, unused, options, location) {
|
|
11105
|
+
if (noUnusedDisable && !rules.has(noUnusedDisable.name)) {
|
|
11106
|
+
noUnusedDisable.reportUnused(unused, options, location);
|
|
11107
|
+
}
|
|
11108
|
+
},
|
|
11109
|
+
};
|
|
10927
11110
|
/* create a faux location at the start of the stream for the next events */
|
|
10928
11111
|
const location = {
|
|
10929
11112
|
filename: source.filename,
|
|
@@ -10949,7 +11132,7 @@ class Engine {
|
|
|
10949
11132
|
parser.trigger("source:ready", sourceEvent);
|
|
10950
11133
|
/* setup directive handling */
|
|
10951
11134
|
parser.on("directive", (_, event) => {
|
|
10952
|
-
this.processDirective(event, parser,
|
|
11135
|
+
this.processDirective(event, parser, directiveContext);
|
|
10953
11136
|
});
|
|
10954
11137
|
/* parse token stream */
|
|
10955
11138
|
try {
|
|
@@ -11056,12 +11239,15 @@ class Engine {
|
|
|
11056
11239
|
instantiateParser() {
|
|
11057
11240
|
return new this.ParserClass(this.config);
|
|
11058
11241
|
}
|
|
11059
|
-
processDirective(event, parser,
|
|
11242
|
+
processDirective(event, parser, context) {
|
|
11243
|
+
var _a;
|
|
11060
11244
|
const rules = event.data
|
|
11061
11245
|
.split(",")
|
|
11062
11246
|
.map((name) => name.trim())
|
|
11063
|
-
.map((name) =>
|
|
11247
|
+
.map((name) => context.rules[name])
|
|
11064
11248
|
.filter((rule) => rule); /* filter out missing rules */
|
|
11249
|
+
/* istanbul ignore next: option must be present or there would be no rules to disable */
|
|
11250
|
+
const location = (_a = event.optionsLocation) !== null && _a !== void 0 ? _a : event.location;
|
|
11065
11251
|
switch (event.action) {
|
|
11066
11252
|
case "enable":
|
|
11067
11253
|
this.processEnableDirective(rules, parser);
|
|
@@ -11070,10 +11256,10 @@ class Engine {
|
|
|
11070
11256
|
this.processDisableDirective(rules, parser);
|
|
11071
11257
|
break;
|
|
11072
11258
|
case "disable-block":
|
|
11073
|
-
this.processDisableBlockDirective(rules, parser);
|
|
11259
|
+
this.processDisableBlockDirective(context, rules, parser, event.data, location);
|
|
11074
11260
|
break;
|
|
11075
11261
|
case "disable-next":
|
|
11076
|
-
this.processDisableNextDirective(rules, parser);
|
|
11262
|
+
this.processDisableNextDirective(context, rules, parser, event.data, location);
|
|
11077
11263
|
break;
|
|
11078
11264
|
}
|
|
11079
11265
|
}
|
|
@@ -11098,10 +11284,13 @@ class Engine {
|
|
|
11098
11284
|
data.target.disableRules(rules.map((rule) => rule.name));
|
|
11099
11285
|
});
|
|
11100
11286
|
}
|
|
11101
|
-
processDisableBlockDirective(rules, parser) {
|
|
11287
|
+
processDisableBlockDirective(context, rules, parser, options, location) {
|
|
11288
|
+
const ruleIds = new Set(rules.map((it) => it.name));
|
|
11289
|
+
const unused = new Set(ruleIds);
|
|
11290
|
+
const blocker = createBlocker();
|
|
11102
11291
|
let directiveBlock = null;
|
|
11103
11292
|
for (const rule of rules) {
|
|
11104
|
-
rule.
|
|
11293
|
+
rule.block(blocker);
|
|
11105
11294
|
}
|
|
11106
11295
|
const unregisterOpen = parser.on("tag:start", (event, data) => {
|
|
11107
11296
|
var _a, _b;
|
|
@@ -11113,7 +11302,7 @@ class Engine {
|
|
|
11113
11302
|
}
|
|
11114
11303
|
/* disable rules directly on the node so it will be recorded for later,
|
|
11115
11304
|
* more specifically when using the domtree to trigger errors */
|
|
11116
|
-
data.target.
|
|
11305
|
+
data.target.blockRules(ruleIds, blocker);
|
|
11117
11306
|
});
|
|
11118
11307
|
const unregisterClose = parser.on("tag:end", (event, data) => {
|
|
11119
11308
|
/* if the directive is the last thing in a block no id would be set */
|
|
@@ -11126,26 +11315,45 @@ class Engine {
|
|
|
11126
11315
|
unregisterClose();
|
|
11127
11316
|
unregisterOpen();
|
|
11128
11317
|
for (const rule of rules) {
|
|
11129
|
-
rule.
|
|
11318
|
+
rule.unblock(blocker);
|
|
11130
11319
|
}
|
|
11131
11320
|
}
|
|
11132
11321
|
});
|
|
11322
|
+
parser.on("rule:error", (event, data) => {
|
|
11323
|
+
if (data.blockers.includes(blocker)) {
|
|
11324
|
+
unused.delete(data.ruleId);
|
|
11325
|
+
}
|
|
11326
|
+
});
|
|
11327
|
+
parser.on("parse:end", () => {
|
|
11328
|
+
context.reportUnused(ruleIds, unused, options, location);
|
|
11329
|
+
});
|
|
11133
11330
|
}
|
|
11134
|
-
processDisableNextDirective(rules, parser) {
|
|
11331
|
+
processDisableNextDirective(context, rules, parser, options, location) {
|
|
11332
|
+
const ruleIds = new Set(rules.map((it) => it.name));
|
|
11333
|
+
const unused = new Set(ruleIds);
|
|
11334
|
+
const blocker = createBlocker();
|
|
11135
11335
|
for (const rule of rules) {
|
|
11136
|
-
rule.
|
|
11336
|
+
rule.block(blocker);
|
|
11137
11337
|
}
|
|
11138
|
-
/*
|
|
11338
|
+
/* block rules directly on the node so it will be recorded for later,
|
|
11139
11339
|
* more specifically when using the domtree to trigger errors */
|
|
11140
11340
|
const unregister = parser.on("tag:start", (event, data) => {
|
|
11141
|
-
data.target.
|
|
11341
|
+
data.target.blockRules(ruleIds, blocker);
|
|
11342
|
+
});
|
|
11343
|
+
parser.on("rule:error", (event, data) => {
|
|
11344
|
+
if (data.blockers.includes(blocker)) {
|
|
11345
|
+
unused.delete(data.ruleId);
|
|
11346
|
+
}
|
|
11347
|
+
});
|
|
11348
|
+
parser.on("parse:end", () => {
|
|
11349
|
+
context.reportUnused(ruleIds, unused, options, location);
|
|
11142
11350
|
});
|
|
11143
11351
|
/* disable directive after next event occurs */
|
|
11144
11352
|
parser.once("tag:ready, tag:end, attr", () => {
|
|
11145
11353
|
unregister();
|
|
11146
11354
|
parser.defer(() => {
|
|
11147
11355
|
for (const rule of rules) {
|
|
11148
|
-
rule.
|
|
11356
|
+
rule.unblock(blocker);
|
|
11149
11357
|
}
|
|
11150
11358
|
});
|
|
11151
11359
|
});
|
|
@@ -11537,7 +11745,7 @@ class HtmlValidate {
|
|
|
11537
11745
|
/** @public */
|
|
11538
11746
|
const name = "html-validate";
|
|
11539
11747
|
/** @public */
|
|
11540
|
-
const version = "7.
|
|
11748
|
+
const version = "7.13.1";
|
|
11541
11749
|
/** @public */
|
|
11542
11750
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11543
11751
|
|
|
@@ -12000,6 +12208,7 @@ exports.StaticConfigLoader = StaticConfigLoader;
|
|
|
12000
12208
|
exports.TemplateExtractor = TemplateExtractor;
|
|
12001
12209
|
exports.TextNode = TextNode;
|
|
12002
12210
|
exports.UserError = UserError;
|
|
12211
|
+
exports.Validator = Validator;
|
|
12003
12212
|
exports.WrappedError = WrappedError;
|
|
12004
12213
|
exports.bugs = bugs;
|
|
12005
12214
|
exports.codeframe = codeframe;
|