html-validate 6.6.1 → 6.8.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.d.ts +1 -1
- package/dist/cjs/browser.js +2 -0
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/cli.js +9 -5
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core.d.ts +15 -8
- package/dist/cjs/core.js +399 -159
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/html-validate.js +11 -6
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/jest-lib.js +83 -65
- package/dist/cjs/jest-lib.js.map +1 -1
- package/dist/cjs/jest.d.ts +35 -2
- package/dist/cjs/jest.js +14 -3
- package/dist/cjs/jest.js.map +1 -1
- package/dist/cjs/test-utils.d.ts +1 -1
- package/dist/es/browser.d.ts +1 -1
- package/dist/es/browser.js +2 -0
- package/dist/es/browser.js.map +1 -1
- package/dist/es/cli.js +9 -5
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core.d.ts +15 -8
- package/dist/es/core.js +322 -103
- package/dist/es/core.js.map +1 -1
- package/dist/es/html-validate.js +11 -6
- package/dist/es/html-validate.js.map +1 -1
- package/dist/es/index.d.ts +2 -2
- package/dist/es/index.js +2 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/jest-lib.js +76 -64
- package/dist/es/jest-lib.js.map +1 -1
- package/dist/es/jest.d.ts +35 -2
- package/dist/es/jest.js +15 -3
- package/dist/es/jest.js.map +1 -1
- package/dist/es/test-utils.d.ts +1 -1
- package/elements/html5.js +1881 -0
- package/package.json +38 -29
- package/dist/cjs/jest-lib.d.ts +0 -35
- package/dist/es/jest-lib.d.ts +0 -35
- package/elements/html5.json +0 -1876
package/dist/cjs/core.js
CHANGED
|
@@ -4,6 +4,8 @@ var fs = require('fs');
|
|
|
4
4
|
var betterAjvErrors = require('@sidvind/better-ajv-errors');
|
|
5
5
|
var Ajv = require('ajv');
|
|
6
6
|
var deepmerge = require('deepmerge');
|
|
7
|
+
var espree = require('espree');
|
|
8
|
+
var walk = require('acorn-walk');
|
|
7
9
|
var path = require('path');
|
|
8
10
|
var semver = require('semver');
|
|
9
11
|
var kleur = require('kleur');
|
|
@@ -12,10 +14,30 @@ var stylishImpl = require('@html-validate/stylish');
|
|
|
12
14
|
|
|
13
15
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
16
|
|
|
17
|
+
function _interopNamespace(e) {
|
|
18
|
+
if (e && e.__esModule) return e;
|
|
19
|
+
var n = Object.create(null);
|
|
20
|
+
if (e) {
|
|
21
|
+
Object.keys(e).forEach(function (k) {
|
|
22
|
+
if (k !== 'default') {
|
|
23
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
24
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return e[k]; }
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
n["default"] = e;
|
|
32
|
+
return Object.freeze(n);
|
|
33
|
+
}
|
|
34
|
+
|
|
15
35
|
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
16
36
|
var betterAjvErrors__default = /*#__PURE__*/_interopDefaultLegacy(betterAjvErrors);
|
|
17
37
|
var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv);
|
|
18
38
|
var deepmerge__default = /*#__PURE__*/_interopDefaultLegacy(deepmerge);
|
|
39
|
+
var espree__namespace = /*#__PURE__*/_interopNamespace(espree);
|
|
40
|
+
var walk__namespace = /*#__PURE__*/_interopNamespace(walk);
|
|
19
41
|
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
20
42
|
var semver__default = /*#__PURE__*/_interopDefaultLegacy(semver);
|
|
21
43
|
var kleur__default = /*#__PURE__*/_interopDefaultLegacy(kleur);
|
|
@@ -256,7 +278,7 @@ class NestedError extends Error {
|
|
|
256
278
|
constructor(message, nested) {
|
|
257
279
|
super(message);
|
|
258
280
|
Error.captureStackTrace(this, NestedError);
|
|
259
|
-
if (nested) {
|
|
281
|
+
if (nested && nested.stack) {
|
|
260
282
|
this.stack += `\nCaused by: ${nested.stack}`;
|
|
261
283
|
}
|
|
262
284
|
}
|
|
@@ -1211,6 +1233,27 @@ class Attribute {
|
|
|
1211
1233
|
}
|
|
1212
1234
|
}
|
|
1213
1235
|
|
|
1236
|
+
function getCSSDeclarations(value) {
|
|
1237
|
+
return value
|
|
1238
|
+
.trim()
|
|
1239
|
+
.split(";")
|
|
1240
|
+
.filter(Boolean)
|
|
1241
|
+
.map((it) => {
|
|
1242
|
+
const [property, value] = it.split(":", 2);
|
|
1243
|
+
return [property.trim(), value ? value.trim() : ""];
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
/**
|
|
1247
|
+
* @internal
|
|
1248
|
+
*/
|
|
1249
|
+
function parseCssDeclaration(value) {
|
|
1250
|
+
if (!value || value instanceof DynamicValue) {
|
|
1251
|
+
return {};
|
|
1252
|
+
}
|
|
1253
|
+
const pairs = getCSSDeclarations(value);
|
|
1254
|
+
return Object.fromEntries(pairs);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1214
1257
|
function sliceSize(size, begin, end) {
|
|
1215
1258
|
if (typeof size !== "number") {
|
|
1216
1259
|
return size;
|
|
@@ -1849,8 +1892,13 @@ exports.NodeClosed = void 0;
|
|
|
1849
1892
|
NodeClosed[NodeClosed["VoidSelfClosed"] = 3] = "VoidSelfClosed";
|
|
1850
1893
|
NodeClosed[NodeClosed["ImplicitClosed"] = 4] = "ImplicitClosed";
|
|
1851
1894
|
})(exports.NodeClosed || (exports.NodeClosed = {}));
|
|
1852
|
-
|
|
1853
|
-
|
|
1895
|
+
/**
|
|
1896
|
+
* Returns true if the node is an element node.
|
|
1897
|
+
*
|
|
1898
|
+
* @public
|
|
1899
|
+
*/
|
|
1900
|
+
function isElementNode(node) {
|
|
1901
|
+
return Boolean(node && node.nodeType === NodeType.ELEMENT_NODE);
|
|
1854
1902
|
}
|
|
1855
1903
|
function isValidTagName(tagName) {
|
|
1856
1904
|
return Boolean(tagName !== "" && tagName !== "*");
|
|
@@ -1924,7 +1972,7 @@ class HtmlElement extends DOMNode {
|
|
|
1924
1972
|
* Similar to childNodes but only elements.
|
|
1925
1973
|
*/
|
|
1926
1974
|
get childElements() {
|
|
1927
|
-
return this.childNodes.filter(
|
|
1975
|
+
return this.childNodes.filter(isElementNode);
|
|
1928
1976
|
}
|
|
1929
1977
|
/**
|
|
1930
1978
|
* Find the first ancestor matching a selector.
|
|
@@ -2154,6 +2202,10 @@ class HtmlElement extends DOMNode {
|
|
|
2154
2202
|
get id() {
|
|
2155
2203
|
return this.getAttributeValue("id");
|
|
2156
2204
|
}
|
|
2205
|
+
get style() {
|
|
2206
|
+
const attr = this.getAttribute("style");
|
|
2207
|
+
return parseCssDeclaration(attr === null || attr === void 0 ? void 0 : attr.value);
|
|
2208
|
+
}
|
|
2157
2209
|
/**
|
|
2158
2210
|
* Returns the first child element or null if there are no child elements.
|
|
2159
2211
|
*/
|
|
@@ -2185,8 +2237,9 @@ class HtmlElement extends DOMNode {
|
|
|
2185
2237
|
}, []);
|
|
2186
2238
|
}
|
|
2187
2239
|
querySelector(selector) {
|
|
2240
|
+
var _a;
|
|
2188
2241
|
const it = this.querySelectorImpl(selector);
|
|
2189
|
-
return it.next().value
|
|
2242
|
+
return (_a = it.next().value) !== null && _a !== void 0 ? _a : null; // eslint-disable-line @typescript-eslint/no-unsafe-return
|
|
2190
2243
|
}
|
|
2191
2244
|
querySelectorAll(selector) {
|
|
2192
2245
|
const it = this.querySelectorImpl(selector);
|
|
@@ -2753,8 +2806,6 @@ var configurationSchema = {
|
|
|
2753
2806
|
};
|
|
2754
2807
|
|
|
2755
2808
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2756
|
-
const espree = legacyRequire("espree");
|
|
2757
|
-
const walk = legacyRequire("acorn-walk");
|
|
2758
2809
|
function joinTemplateLiteral(nodes) {
|
|
2759
2810
|
let offset = nodes[0].start + 1;
|
|
2760
2811
|
let output = "";
|
|
@@ -2870,7 +2921,7 @@ class TemplateExtractor {
|
|
|
2870
2921
|
}
|
|
2871
2922
|
static fromFilename(filename) {
|
|
2872
2923
|
const source = fs__default["default"].readFileSync(filename, "utf-8");
|
|
2873
|
-
const ast =
|
|
2924
|
+
const ast = espree__namespace.parse(source, {
|
|
2874
2925
|
ecmaVersion: 2017,
|
|
2875
2926
|
sourceType: "module",
|
|
2876
2927
|
loc: true,
|
|
@@ -2889,7 +2940,7 @@ class TemplateExtractor {
|
|
|
2889
2940
|
* `Source`. Defauls to `"inline"`.
|
|
2890
2941
|
*/
|
|
2891
2942
|
static fromString(source, filename) {
|
|
2892
|
-
const ast =
|
|
2943
|
+
const ast = espree__namespace.parse(source, {
|
|
2893
2944
|
ecmaVersion: 2017,
|
|
2894
2945
|
sourceType: "module",
|
|
2895
2946
|
loc: true,
|
|
@@ -2935,7 +2986,8 @@ class TemplateExtractor {
|
|
|
2935
2986
|
extractObjectProperty(key) {
|
|
2936
2987
|
const result = [];
|
|
2937
2988
|
const { filename, data } = this;
|
|
2938
|
-
|
|
2989
|
+
const node = this.ast;
|
|
2990
|
+
walk__namespace.simple(node, {
|
|
2939
2991
|
Property(node) {
|
|
2940
2992
|
if (compareKey(node.key, key, filename)) {
|
|
2941
2993
|
const source = extractLiteral(node.value, filename, data);
|
|
@@ -2959,7 +3011,7 @@ var TRANSFORMER_API;
|
|
|
2959
3011
|
/** @public */
|
|
2960
3012
|
const name = "html-validate";
|
|
2961
3013
|
/** @public */
|
|
2962
|
-
const version = "6.
|
|
3014
|
+
const version = "6.8.0";
|
|
2963
3015
|
/** @public */
|
|
2964
3016
|
const homepage = "https://html-validate.org";
|
|
2965
3017
|
/** @public */
|
|
@@ -3280,7 +3332,7 @@ function ruleDocumentationUrl(filename) {
|
|
|
3280
3332
|
return `${homepage}/rules/${normalized}.html`;
|
|
3281
3333
|
}
|
|
3282
3334
|
|
|
3283
|
-
const defaults$
|
|
3335
|
+
const defaults$q = {
|
|
3284
3336
|
allowExternal: true,
|
|
3285
3337
|
allowRelative: true,
|
|
3286
3338
|
allowAbsolute: true,
|
|
@@ -3324,7 +3376,7 @@ function matchList(value, list) {
|
|
|
3324
3376
|
}
|
|
3325
3377
|
class AllowedLinks extends Rule {
|
|
3326
3378
|
constructor(options) {
|
|
3327
|
-
super({ ...defaults$
|
|
3379
|
+
super({ ...defaults$q, ...options });
|
|
3328
3380
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3329
3381
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3330
3382
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3603,7 +3655,7 @@ class CaseStyle {
|
|
|
3603
3655
|
default: {
|
|
3604
3656
|
const last = names.slice(-1);
|
|
3605
3657
|
const rest = names.slice(0, -1);
|
|
3606
|
-
return `${rest.join(", ")} or ${last}`;
|
|
3658
|
+
return `${rest.join(", ")} or ${last[0]}`;
|
|
3607
3659
|
}
|
|
3608
3660
|
}
|
|
3609
3661
|
}
|
|
@@ -3619,19 +3671,19 @@ class CaseStyle {
|
|
|
3619
3671
|
case "camelcase":
|
|
3620
3672
|
return { pattern: /^[a-z][A-Za-z]*$/, name: "camelCase" };
|
|
3621
3673
|
default:
|
|
3622
|
-
throw new ConfigError(`Invalid style "${
|
|
3674
|
+
throw new ConfigError(`Invalid style "${cur}" for ${ruleId} rule`);
|
|
3623
3675
|
}
|
|
3624
3676
|
});
|
|
3625
3677
|
}
|
|
3626
3678
|
}
|
|
3627
3679
|
|
|
3628
|
-
const defaults$
|
|
3680
|
+
const defaults$p = {
|
|
3629
3681
|
style: "lowercase",
|
|
3630
3682
|
ignoreForeign: true,
|
|
3631
3683
|
};
|
|
3632
3684
|
class AttrCase extends Rule {
|
|
3633
3685
|
constructor(options) {
|
|
3634
|
-
super({ ...defaults$
|
|
3686
|
+
super({ ...defaults$p, ...options });
|
|
3635
3687
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
3636
3688
|
}
|
|
3637
3689
|
static schema() {
|
|
@@ -3658,8 +3710,11 @@ class AttrCase extends Rule {
|
|
|
3658
3710
|
};
|
|
3659
3711
|
}
|
|
3660
3712
|
documentation() {
|
|
3713
|
+
const { style } = this.options;
|
|
3661
3714
|
return {
|
|
3662
|
-
description:
|
|
3715
|
+
description: Array.isArray(style)
|
|
3716
|
+
? [`Attribute name must be in one of:`, "", ...style.map((it) => `- ${it}`)].join("\n")
|
|
3717
|
+
: `Attribute name must be in ${style}.`,
|
|
3663
3718
|
url: ruleDocumentationUrl("@/rules/attr-case.ts"),
|
|
3664
3719
|
};
|
|
3665
3720
|
}
|
|
@@ -3690,7 +3745,7 @@ class AttrCase extends Rule {
|
|
|
3690
3745
|
}
|
|
3691
3746
|
}
|
|
3692
3747
|
|
|
3693
|
-
|
|
3748
|
+
var TokenType;
|
|
3694
3749
|
(function (TokenType) {
|
|
3695
3750
|
TokenType[TokenType["UNICODE_BOM"] = 1] = "UNICODE_BOM";
|
|
3696
3751
|
TokenType[TokenType["WHITESPACE"] = 2] = "WHITESPACE";
|
|
@@ -3709,7 +3764,7 @@ exports.TokenType = void 0;
|
|
|
3709
3764
|
TokenType[TokenType["CONDITIONAL"] = 15] = "CONDITIONAL";
|
|
3710
3765
|
TokenType[TokenType["DIRECTIVE"] = 16] = "DIRECTIVE";
|
|
3711
3766
|
TokenType[TokenType["EOF"] = 17] = "EOF";
|
|
3712
|
-
})(
|
|
3767
|
+
})(TokenType || (TokenType = {}));
|
|
3713
3768
|
|
|
3714
3769
|
/* eslint-disable no-useless-escape */
|
|
3715
3770
|
const MATCH_UNICODE_BOM = /^\uFEFF/;
|
|
@@ -3788,7 +3843,7 @@ class Lexer {
|
|
|
3788
3843
|
previousState = context.state;
|
|
3789
3844
|
previousLength = context.string.length;
|
|
3790
3845
|
}
|
|
3791
|
-
yield this.token(context,
|
|
3846
|
+
yield this.token(context, TokenType.EOF, []);
|
|
3792
3847
|
}
|
|
3793
3848
|
token(context, type, data) {
|
|
3794
3849
|
const size = data.length > 0 ? data[0].length : 0;
|
|
@@ -3859,21 +3914,21 @@ class Lexer {
|
|
|
3859
3914
|
}
|
|
3860
3915
|
*tokenizeInitial(context) {
|
|
3861
3916
|
yield* this.match(context, [
|
|
3862
|
-
[MATCH_UNICODE_BOM, State.INITIAL,
|
|
3917
|
+
[MATCH_UNICODE_BOM, State.INITIAL, TokenType.UNICODE_BOM],
|
|
3863
3918
|
[MATCH_XML_TAG, State.INITIAL, false],
|
|
3864
|
-
[MATCH_DOCTYPE_OPEN, State.DOCTYPE,
|
|
3865
|
-
[MATCH_WHITESPACE, State.INITIAL,
|
|
3866
|
-
[MATCH_DIRECTIVE, State.INITIAL,
|
|
3867
|
-
[MATCH_CONDITIONAL, State.INITIAL,
|
|
3868
|
-
[MATCH_COMMENT, State.INITIAL,
|
|
3919
|
+
[MATCH_DOCTYPE_OPEN, State.DOCTYPE, TokenType.DOCTYPE_OPEN],
|
|
3920
|
+
[MATCH_WHITESPACE, State.INITIAL, TokenType.WHITESPACE],
|
|
3921
|
+
[MATCH_DIRECTIVE, State.INITIAL, TokenType.DIRECTIVE],
|
|
3922
|
+
[MATCH_CONDITIONAL, State.INITIAL, TokenType.CONDITIONAL],
|
|
3923
|
+
[MATCH_COMMENT, State.INITIAL, TokenType.COMMENT],
|
|
3869
3924
|
[false, State.TEXT, false],
|
|
3870
3925
|
], "expected doctype");
|
|
3871
3926
|
}
|
|
3872
3927
|
*tokenizeDoctype(context) {
|
|
3873
3928
|
yield* this.match(context, [
|
|
3874
|
-
[MATCH_WHITESPACE, State.DOCTYPE,
|
|
3875
|
-
[MATCH_DOCTYPE_VALUE, State.DOCTYPE,
|
|
3876
|
-
[MATCH_DOCTYPE_CLOSE, State.TEXT,
|
|
3929
|
+
[MATCH_WHITESPACE, State.DOCTYPE, TokenType.WHITESPACE],
|
|
3930
|
+
[MATCH_DOCTYPE_VALUE, State.DOCTYPE, TokenType.DOCTYPE_VALUE],
|
|
3931
|
+
[MATCH_DOCTYPE_CLOSE, State.TEXT, TokenType.DOCTYPE_CLOSE],
|
|
3877
3932
|
], "expected doctype name");
|
|
3878
3933
|
}
|
|
3879
3934
|
*tokenizeTag(context) {
|
|
@@ -3900,30 +3955,30 @@ class Lexer {
|
|
|
3900
3955
|
}
|
|
3901
3956
|
}
|
|
3902
3957
|
yield* this.match(context, [
|
|
3903
|
-
[MATCH_TAG_CLOSE, nextState,
|
|
3904
|
-
[MATCH_ATTR_START, State.ATTR,
|
|
3905
|
-
[MATCH_WHITESPACE, State.TAG,
|
|
3958
|
+
[MATCH_TAG_CLOSE, nextState, TokenType.TAG_CLOSE],
|
|
3959
|
+
[MATCH_ATTR_START, State.ATTR, TokenType.ATTR_NAME],
|
|
3960
|
+
[MATCH_WHITESPACE, State.TAG, TokenType.WHITESPACE],
|
|
3906
3961
|
], 'expected attribute, ">" or "/>"');
|
|
3907
3962
|
}
|
|
3908
3963
|
*tokenizeAttr(context) {
|
|
3909
3964
|
yield* this.match(context, [
|
|
3910
|
-
[MATCH_ATTR_SINGLE, State.TAG,
|
|
3911
|
-
[MATCH_ATTR_DOUBLE, State.TAG,
|
|
3912
|
-
[MATCH_ATTR_UNQUOTED, State.TAG,
|
|
3965
|
+
[MATCH_ATTR_SINGLE, State.TAG, TokenType.ATTR_VALUE],
|
|
3966
|
+
[MATCH_ATTR_DOUBLE, State.TAG, TokenType.ATTR_VALUE],
|
|
3967
|
+
[MATCH_ATTR_UNQUOTED, State.TAG, TokenType.ATTR_VALUE],
|
|
3913
3968
|
[false, State.TAG, false],
|
|
3914
3969
|
], 'expected attribute, ">" or "/>"');
|
|
3915
3970
|
}
|
|
3916
3971
|
*tokenizeText(context) {
|
|
3917
3972
|
yield* this.match(context, [
|
|
3918
|
-
[MATCH_WHITESPACE, State.TEXT,
|
|
3973
|
+
[MATCH_WHITESPACE, State.TEXT, TokenType.WHITESPACE],
|
|
3919
3974
|
[MATCH_CDATA_BEGIN, State.CDATA, false],
|
|
3920
|
-
[MATCH_DIRECTIVE, State.TEXT,
|
|
3921
|
-
[MATCH_CONDITIONAL, State.TEXT,
|
|
3922
|
-
[MATCH_COMMENT, State.TEXT,
|
|
3923
|
-
[MATCH_TEMPLATING, State.TEXT,
|
|
3924
|
-
[MATCH_TAG_OPEN, State.TAG,
|
|
3925
|
-
[MATCH_TEXT, State.TEXT,
|
|
3926
|
-
[MATCH_TAG_LOOKAHEAD, State.TEXT,
|
|
3975
|
+
[MATCH_DIRECTIVE, State.TEXT, TokenType.DIRECTIVE],
|
|
3976
|
+
[MATCH_CONDITIONAL, State.TEXT, TokenType.CONDITIONAL],
|
|
3977
|
+
[MATCH_COMMENT, State.TEXT, TokenType.COMMENT],
|
|
3978
|
+
[MATCH_TEMPLATING, State.TEXT, TokenType.TEMPLATING],
|
|
3979
|
+
[MATCH_TAG_OPEN, State.TAG, TokenType.TAG_OPEN],
|
|
3980
|
+
[MATCH_TEXT, State.TEXT, TokenType.TEXT],
|
|
3981
|
+
[MATCH_TAG_LOOKAHEAD, State.TEXT, TokenType.TEXT],
|
|
3927
3982
|
], 'expected text or "<"');
|
|
3928
3983
|
}
|
|
3929
3984
|
*tokenizeCDATA(context) {
|
|
@@ -3931,26 +3986,26 @@ class Lexer {
|
|
|
3931
3986
|
}
|
|
3932
3987
|
*tokenizeScript(context) {
|
|
3933
3988
|
yield* this.match(context, [
|
|
3934
|
-
[MATCH_SCRIPT_END, State.TAG,
|
|
3935
|
-
[MATCH_SCRIPT_DATA, State.SCRIPT,
|
|
3989
|
+
[MATCH_SCRIPT_END, State.TAG, TokenType.TAG_OPEN],
|
|
3990
|
+
[MATCH_SCRIPT_DATA, State.SCRIPT, TokenType.SCRIPT],
|
|
3936
3991
|
], "expected </script>");
|
|
3937
3992
|
}
|
|
3938
3993
|
*tokenizeStyle(context) {
|
|
3939
3994
|
yield* this.match(context, [
|
|
3940
|
-
[MATCH_STYLE_END, State.TAG,
|
|
3941
|
-
[MATCH_STYLE_DATA, State.STYLE,
|
|
3995
|
+
[MATCH_STYLE_END, State.TAG, TokenType.TAG_OPEN],
|
|
3996
|
+
[MATCH_STYLE_DATA, State.STYLE, TokenType.STYLE],
|
|
3942
3997
|
], "expected </style>");
|
|
3943
3998
|
}
|
|
3944
3999
|
}
|
|
3945
4000
|
|
|
3946
4001
|
const whitespace = /(\s+)/;
|
|
3947
4002
|
function isRelevant$3(event) {
|
|
3948
|
-
return event.type ===
|
|
4003
|
+
return event.type === TokenType.ATTR_VALUE;
|
|
3949
4004
|
}
|
|
3950
4005
|
class AttrDelimiter extends Rule {
|
|
3951
4006
|
documentation() {
|
|
3952
4007
|
return {
|
|
3953
|
-
description: `Attribute value
|
|
4008
|
+
description: `Attribute value must not be separated by whitespace.`,
|
|
3954
4009
|
url: ruleDocumentationUrl("@/rules/attr-delimiter.ts"),
|
|
3955
4010
|
};
|
|
3956
4011
|
}
|
|
@@ -3967,7 +4022,7 @@ class AttrDelimiter extends Rule {
|
|
|
3967
4022
|
}
|
|
3968
4023
|
|
|
3969
4024
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
3970
|
-
const defaults$
|
|
4025
|
+
const defaults$o = {
|
|
3971
4026
|
pattern: DEFAULT_PATTERN,
|
|
3972
4027
|
ignoreForeign: true,
|
|
3973
4028
|
};
|
|
@@ -4004,7 +4059,7 @@ function generateDescription(name, pattern) {
|
|
|
4004
4059
|
}
|
|
4005
4060
|
class AttrPattern extends Rule {
|
|
4006
4061
|
constructor(options) {
|
|
4007
|
-
super({ ...defaults$
|
|
4062
|
+
super({ ...defaults$o, ...options });
|
|
4008
4063
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4009
4064
|
}
|
|
4010
4065
|
static schema() {
|
|
@@ -4064,13 +4119,13 @@ var QuoteStyle;
|
|
|
4064
4119
|
QuoteStyle["DOUBLE_QUOTE"] = "\"";
|
|
4065
4120
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4066
4121
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4067
|
-
const defaults$
|
|
4122
|
+
const defaults$n = {
|
|
4068
4123
|
style: "auto",
|
|
4069
4124
|
unquoted: false,
|
|
4070
4125
|
};
|
|
4071
4126
|
class AttrQuotes extends Rule {
|
|
4072
4127
|
constructor(options) {
|
|
4073
|
-
super({ ...defaults$
|
|
4128
|
+
super({ ...defaults$n, ...options });
|
|
4074
4129
|
this.style = parseStyle$4(this.options.style);
|
|
4075
4130
|
}
|
|
4076
4131
|
static schema() {
|
|
@@ -4149,7 +4204,7 @@ class AttrSpacing extends Rule {
|
|
|
4149
4204
|
setup() {
|
|
4150
4205
|
let previousToken;
|
|
4151
4206
|
this.on("token", (event) => {
|
|
4152
|
-
if (event.type ===
|
|
4207
|
+
if (event.type === TokenType.ATTR_NAME && previousToken !== TokenType.WHITESPACE) {
|
|
4153
4208
|
this.report(null, "No space between attributes", event.location);
|
|
4154
4209
|
}
|
|
4155
4210
|
previousToken = event.type;
|
|
@@ -4235,12 +4290,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4235
4290
|
}
|
|
4236
4291
|
}
|
|
4237
4292
|
|
|
4238
|
-
const defaults$
|
|
4293
|
+
const defaults$m = {
|
|
4239
4294
|
style: "omit",
|
|
4240
4295
|
};
|
|
4241
4296
|
class AttributeBooleanStyle extends Rule {
|
|
4242
4297
|
constructor(options) {
|
|
4243
|
-
super({ ...defaults$
|
|
4298
|
+
super({ ...defaults$m, ...options });
|
|
4244
4299
|
this.hasInvalidStyle = parseStyle$3(this.options.style);
|
|
4245
4300
|
}
|
|
4246
4301
|
static schema() {
|
|
@@ -4316,12 +4371,12 @@ function reportMessage$1(attr, style) {
|
|
|
4316
4371
|
return "";
|
|
4317
4372
|
}
|
|
4318
4373
|
|
|
4319
|
-
const defaults$
|
|
4374
|
+
const defaults$l = {
|
|
4320
4375
|
style: "omit",
|
|
4321
4376
|
};
|
|
4322
4377
|
class AttributeEmptyStyle extends Rule {
|
|
4323
4378
|
constructor(options) {
|
|
4324
|
-
super({ ...defaults$
|
|
4379
|
+
super({ ...defaults$l, ...options });
|
|
4325
4380
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4326
4381
|
}
|
|
4327
4382
|
static schema() {
|
|
@@ -4429,12 +4484,12 @@ function describePattern(pattern) {
|
|
|
4429
4484
|
}
|
|
4430
4485
|
}
|
|
4431
4486
|
|
|
4432
|
-
const defaults$
|
|
4487
|
+
const defaults$k = {
|
|
4433
4488
|
pattern: "kebabcase",
|
|
4434
4489
|
};
|
|
4435
4490
|
class ClassPattern extends Rule {
|
|
4436
4491
|
constructor(options) {
|
|
4437
|
-
super({ ...defaults$
|
|
4492
|
+
super({ ...defaults$k, ...options });
|
|
4438
4493
|
this.pattern = parsePattern(this.options.pattern);
|
|
4439
4494
|
}
|
|
4440
4495
|
static schema() {
|
|
@@ -4460,7 +4515,9 @@ class ClassPattern extends Rule {
|
|
|
4460
4515
|
classes.forEach((cur, index) => {
|
|
4461
4516
|
if (!cur.match(this.pattern)) {
|
|
4462
4517
|
const location = classes.location(index);
|
|
4463
|
-
|
|
4518
|
+
const pattern = this.pattern.toString();
|
|
4519
|
+
const message = `Class "${cur}" does not match required pattern "${pattern}"`;
|
|
4520
|
+
this.report(event.target, message, location);
|
|
4464
4521
|
}
|
|
4465
4522
|
});
|
|
4466
4523
|
});
|
|
@@ -4541,13 +4598,13 @@ class CloseOrder extends Rule {
|
|
|
4541
4598
|
}
|
|
4542
4599
|
}
|
|
4543
4600
|
|
|
4544
|
-
const defaults$
|
|
4601
|
+
const defaults$j = {
|
|
4545
4602
|
include: null,
|
|
4546
4603
|
exclude: null,
|
|
4547
4604
|
};
|
|
4548
4605
|
class Deprecated extends Rule {
|
|
4549
4606
|
constructor(options) {
|
|
4550
|
-
super({ ...defaults$
|
|
4607
|
+
super({ ...defaults$j, ...options });
|
|
4551
4608
|
}
|
|
4552
4609
|
static schema() {
|
|
4553
4610
|
return {
|
|
@@ -4710,12 +4767,12 @@ class NoStyleTag$1 extends Rule {
|
|
|
4710
4767
|
}
|
|
4711
4768
|
}
|
|
4712
4769
|
|
|
4713
|
-
const defaults$
|
|
4770
|
+
const defaults$i = {
|
|
4714
4771
|
style: "uppercase",
|
|
4715
4772
|
};
|
|
4716
4773
|
class DoctypeStyle extends Rule {
|
|
4717
4774
|
constructor(options) {
|
|
4718
|
-
super({ ...defaults$
|
|
4775
|
+
super({ ...defaults$i, ...options });
|
|
4719
4776
|
}
|
|
4720
4777
|
static schema() {
|
|
4721
4778
|
return {
|
|
@@ -4747,12 +4804,12 @@ class DoctypeStyle extends Rule {
|
|
|
4747
4804
|
}
|
|
4748
4805
|
}
|
|
4749
4806
|
|
|
4750
|
-
const defaults$
|
|
4807
|
+
const defaults$h = {
|
|
4751
4808
|
style: "lowercase",
|
|
4752
4809
|
};
|
|
4753
4810
|
class ElementCase extends Rule {
|
|
4754
4811
|
constructor(options) {
|
|
4755
|
-
super({ ...defaults$
|
|
4812
|
+
super({ ...defaults$h, ...options });
|
|
4756
4813
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
4757
4814
|
}
|
|
4758
4815
|
static schema() {
|
|
@@ -4776,8 +4833,11 @@ class ElementCase extends Rule {
|
|
|
4776
4833
|
};
|
|
4777
4834
|
}
|
|
4778
4835
|
documentation() {
|
|
4836
|
+
const { style } = this.options;
|
|
4779
4837
|
return {
|
|
4780
|
-
description:
|
|
4838
|
+
description: Array.isArray(style)
|
|
4839
|
+
? [`Element tagname must be in one of:`, "", ...style.map((it) => `- ${it}`)].join("\n")
|
|
4840
|
+
: `Element tagname must be in ${style}.`,
|
|
4781
4841
|
url: ruleDocumentationUrl("@/rules/element-case.ts"),
|
|
4782
4842
|
};
|
|
4783
4843
|
}
|
|
@@ -4815,14 +4875,14 @@ class ElementCase extends Rule {
|
|
|
4815
4875
|
}
|
|
4816
4876
|
}
|
|
4817
4877
|
|
|
4818
|
-
const defaults$
|
|
4878
|
+
const defaults$g = {
|
|
4819
4879
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
4820
4880
|
whitelist: [],
|
|
4821
4881
|
blacklist: [],
|
|
4822
4882
|
};
|
|
4823
4883
|
class ElementName extends Rule {
|
|
4824
4884
|
constructor(options) {
|
|
4825
|
-
super({ ...defaults$
|
|
4885
|
+
super({ ...defaults$g, ...options });
|
|
4826
4886
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
4827
4887
|
this.pattern = new RegExp(this.options.pattern);
|
|
4828
4888
|
}
|
|
@@ -4863,7 +4923,7 @@ class ElementName extends Rule {
|
|
|
4863
4923
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
4864
4924
|
];
|
|
4865
4925
|
}
|
|
4866
|
-
if (context.pattern !== defaults$
|
|
4926
|
+
if (context.pattern !== defaults$g.pattern) {
|
|
4867
4927
|
return [
|
|
4868
4928
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
4869
4929
|
"",
|
|
@@ -5265,7 +5325,7 @@ class EmptyTitle extends Rule {
|
|
|
5265
5325
|
}
|
|
5266
5326
|
}
|
|
5267
5327
|
|
|
5268
|
-
const defaults$
|
|
5328
|
+
const defaults$f = {
|
|
5269
5329
|
allowMultipleH1: false,
|
|
5270
5330
|
minInitialRank: "h1",
|
|
5271
5331
|
sectioningRoots: ["dialog", '[role="dialog"]'],
|
|
@@ -5296,7 +5356,7 @@ function parseMaxInitial(value) {
|
|
|
5296
5356
|
}
|
|
5297
5357
|
class HeadingLevel extends Rule {
|
|
5298
5358
|
constructor(options) {
|
|
5299
|
-
super({ ...defaults$
|
|
5359
|
+
super({ ...defaults$f, ...options });
|
|
5300
5360
|
this.stack = [];
|
|
5301
5361
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
5302
5362
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -5454,12 +5514,12 @@ class HeadingLevel extends Rule {
|
|
|
5454
5514
|
}
|
|
5455
5515
|
}
|
|
5456
5516
|
|
|
5457
|
-
const defaults$
|
|
5517
|
+
const defaults$e = {
|
|
5458
5518
|
pattern: "kebabcase",
|
|
5459
5519
|
};
|
|
5460
5520
|
class IdPattern extends Rule {
|
|
5461
5521
|
constructor(options) {
|
|
5462
|
-
super({ ...defaults$
|
|
5522
|
+
super({ ...defaults$e, ...options });
|
|
5463
5523
|
this.pattern = parsePattern(this.options.pattern);
|
|
5464
5524
|
}
|
|
5465
5525
|
static schema() {
|
|
@@ -5478,6 +5538,7 @@ class IdPattern extends Rule {
|
|
|
5478
5538
|
}
|
|
5479
5539
|
setup() {
|
|
5480
5540
|
this.on("attr", (event) => {
|
|
5541
|
+
var _a;
|
|
5481
5542
|
if (event.key.toLowerCase() !== "id") {
|
|
5482
5543
|
return;
|
|
5483
5544
|
}
|
|
@@ -5486,7 +5547,10 @@ class IdPattern extends Rule {
|
|
|
5486
5547
|
return;
|
|
5487
5548
|
}
|
|
5488
5549
|
if (!event.value || !event.value.match(this.pattern)) {
|
|
5489
|
-
|
|
5550
|
+
const value = (_a = event.value) !== null && _a !== void 0 ? _a : "";
|
|
5551
|
+
const pattern = this.pattern.toString();
|
|
5552
|
+
const message = `ID "${value}" does not match required pattern "${pattern}"`;
|
|
5553
|
+
this.report(event.target, message, event.valueLocation);
|
|
5490
5554
|
}
|
|
5491
5555
|
});
|
|
5492
5556
|
}
|
|
@@ -5806,12 +5870,12 @@ function findLabelByParent(el) {
|
|
|
5806
5870
|
return [];
|
|
5807
5871
|
}
|
|
5808
5872
|
|
|
5809
|
-
const defaults$
|
|
5873
|
+
const defaults$d = {
|
|
5810
5874
|
maxlength: 70,
|
|
5811
5875
|
};
|
|
5812
5876
|
class LongTitle extends Rule {
|
|
5813
5877
|
constructor(options) {
|
|
5814
|
-
super({ ...defaults$
|
|
5878
|
+
super({ ...defaults$d, ...options });
|
|
5815
5879
|
this.maxlength = this.options.maxlength;
|
|
5816
5880
|
}
|
|
5817
5881
|
static schema() {
|
|
@@ -5958,13 +6022,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
5958
6022
|
}
|
|
5959
6023
|
}
|
|
5960
6024
|
|
|
5961
|
-
const defaults$
|
|
6025
|
+
const defaults$c = {
|
|
5962
6026
|
include: null,
|
|
5963
6027
|
exclude: null,
|
|
5964
6028
|
};
|
|
5965
6029
|
class NoAutoplay extends Rule {
|
|
5966
6030
|
constructor(options) {
|
|
5967
|
-
super({ ...defaults$
|
|
6031
|
+
super({ ...defaults$c, ...options });
|
|
5968
6032
|
}
|
|
5969
6033
|
documentation(context) {
|
|
5970
6034
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -6205,24 +6269,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
6205
6269
|
}
|
|
6206
6270
|
}
|
|
6207
6271
|
|
|
6208
|
-
const defaults$
|
|
6272
|
+
const defaults$b = {
|
|
6209
6273
|
include: null,
|
|
6210
6274
|
exclude: null,
|
|
6211
6275
|
allowedProperties: ["display"],
|
|
6212
6276
|
};
|
|
6213
|
-
function getCSSDeclarations(value) {
|
|
6214
|
-
return value
|
|
6215
|
-
.trim()
|
|
6216
|
-
.split(";")
|
|
6217
|
-
.filter(Boolean)
|
|
6218
|
-
.map((it) => {
|
|
6219
|
-
const [property, value] = it.split(":", 2);
|
|
6220
|
-
return { property: property.trim(), value: value ? value.trim() : undefined };
|
|
6221
|
-
});
|
|
6222
|
-
}
|
|
6223
6277
|
class NoInlineStyle extends Rule {
|
|
6224
6278
|
constructor(options) {
|
|
6225
|
-
super({ ...defaults$
|
|
6279
|
+
super({ ...defaults$b, ...options });
|
|
6226
6280
|
}
|
|
6227
6281
|
static schema() {
|
|
6228
6282
|
return {
|
|
@@ -6300,18 +6354,15 @@ class NoInlineStyle extends Rule {
|
|
|
6300
6354
|
return true;
|
|
6301
6355
|
}
|
|
6302
6356
|
allPropertiesAllowed(value) {
|
|
6303
|
-
if (typeof value !== "string") {
|
|
6304
|
-
return false;
|
|
6305
|
-
}
|
|
6306
6357
|
const allowProperties = this.options.allowedProperties;
|
|
6307
6358
|
/* quick path: no properties are allowed, no need to check each one individually */
|
|
6308
6359
|
if (allowProperties.length === 0) {
|
|
6309
6360
|
return false;
|
|
6310
6361
|
}
|
|
6311
|
-
const declarations =
|
|
6362
|
+
const declarations = Object.keys(parseCssDeclaration(value));
|
|
6312
6363
|
return (declarations.length > 0 &&
|
|
6313
6364
|
declarations.every((it) => {
|
|
6314
|
-
return allowProperties.includes(it
|
|
6365
|
+
return allowProperties.includes(it);
|
|
6315
6366
|
}));
|
|
6316
6367
|
}
|
|
6317
6368
|
}
|
|
@@ -6427,24 +6478,24 @@ class NoMultipleMain extends Rule {
|
|
|
6427
6478
|
}
|
|
6428
6479
|
}
|
|
6429
6480
|
|
|
6430
|
-
const defaults$
|
|
6481
|
+
const defaults$a = {
|
|
6431
6482
|
relaxed: false,
|
|
6432
6483
|
};
|
|
6433
6484
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
6434
6485
|
const unquotedAttrRegexp = /([<>"'=`]|&(?![a-zA-Z0-9#]+;))/g;
|
|
6435
6486
|
const matchTemplate = /^(<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
|
|
6436
|
-
const replacementTable =
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6487
|
+
const replacementTable = {
|
|
6488
|
+
'"': """,
|
|
6489
|
+
"&": "&",
|
|
6490
|
+
"'": "'",
|
|
6491
|
+
"<": "<",
|
|
6492
|
+
"=": "=",
|
|
6493
|
+
">": ">",
|
|
6494
|
+
"`": "`",
|
|
6495
|
+
};
|
|
6445
6496
|
class NoRawCharacters extends Rule {
|
|
6446
6497
|
constructor(options) {
|
|
6447
|
-
super({ ...defaults$
|
|
6498
|
+
super({ ...defaults$a, ...options });
|
|
6448
6499
|
this.relaxed = this.options.relaxed;
|
|
6449
6500
|
}
|
|
6450
6501
|
static schema() {
|
|
@@ -6494,7 +6545,6 @@ class NoRawCharacters extends Rule {
|
|
|
6494
6545
|
* @param text - The full text to find unescaped raw characters in.
|
|
6495
6546
|
* @param location - Location of text.
|
|
6496
6547
|
* @param regexp - Regexp pattern to match using.
|
|
6497
|
-
* @param ignore - List of characters to ignore for this text.
|
|
6498
6548
|
*/
|
|
6499
6549
|
findRawChars(node, text, location, regexp) {
|
|
6500
6550
|
let match;
|
|
@@ -6510,7 +6560,7 @@ class NoRawCharacters extends Rule {
|
|
|
6510
6560
|
continue;
|
|
6511
6561
|
}
|
|
6512
6562
|
/* determine replacement character and location */
|
|
6513
|
-
const replacement = replacementTable
|
|
6563
|
+
const replacement = replacementTable[char];
|
|
6514
6564
|
const charLocation = sliceLocation(location, match.index, match.index + 1);
|
|
6515
6565
|
/* report as error */
|
|
6516
6566
|
this.report(node, `Raw "${char}" must be encoded as "${replacement}"`, charLocation);
|
|
@@ -6623,13 +6673,13 @@ class NoRedundantRole extends Rule {
|
|
|
6623
6673
|
}
|
|
6624
6674
|
|
|
6625
6675
|
const xmlns = /^(.+):.+$/;
|
|
6626
|
-
const defaults$
|
|
6676
|
+
const defaults$9 = {
|
|
6627
6677
|
ignoreForeign: true,
|
|
6628
6678
|
ignoreXML: true,
|
|
6629
6679
|
};
|
|
6630
6680
|
class NoSelfClosing extends Rule {
|
|
6631
6681
|
constructor(options) {
|
|
6632
|
-
super({ ...defaults$
|
|
6682
|
+
super({ ...defaults$9, ...options });
|
|
6633
6683
|
}
|
|
6634
6684
|
static schema() {
|
|
6635
6685
|
return {
|
|
@@ -6745,7 +6795,7 @@ class NoUtf8Bom extends Rule {
|
|
|
6745
6795
|
}
|
|
6746
6796
|
setup() {
|
|
6747
6797
|
const unregister = this.on("token", (event) => {
|
|
6748
|
-
if (event.type ===
|
|
6798
|
+
if (event.type === TokenType.UNICODE_BOM) {
|
|
6749
6799
|
this.report(null, "File should be saved without UTF-8 BOM", event.location);
|
|
6750
6800
|
}
|
|
6751
6801
|
/* since the BOM must be the very first thing the rule can now be disabled for the rest of the run */
|
|
@@ -6762,13 +6812,13 @@ const replacement = {
|
|
|
6762
6812
|
reset: '<button type="reset">',
|
|
6763
6813
|
image: '<button type="button">',
|
|
6764
6814
|
};
|
|
6765
|
-
const defaults$
|
|
6815
|
+
const defaults$8 = {
|
|
6766
6816
|
include: null,
|
|
6767
6817
|
exclude: null,
|
|
6768
6818
|
};
|
|
6769
6819
|
class PreferButton extends Rule {
|
|
6770
6820
|
constructor(options) {
|
|
6771
|
-
super({ ...defaults$
|
|
6821
|
+
super({ ...defaults$8, ...options });
|
|
6772
6822
|
}
|
|
6773
6823
|
static schema() {
|
|
6774
6824
|
return {
|
|
@@ -6843,7 +6893,7 @@ class PreferButton extends Rule {
|
|
|
6843
6893
|
}
|
|
6844
6894
|
}
|
|
6845
6895
|
|
|
6846
|
-
const defaults$
|
|
6896
|
+
const defaults$7 = {
|
|
6847
6897
|
mapping: {
|
|
6848
6898
|
article: "article",
|
|
6849
6899
|
banner: "header",
|
|
@@ -6873,7 +6923,7 @@ const defaults$6 = {
|
|
|
6873
6923
|
};
|
|
6874
6924
|
class PreferNativeElement extends Rule {
|
|
6875
6925
|
constructor(options) {
|
|
6876
|
-
super({ ...defaults$
|
|
6926
|
+
super({ ...defaults$7, ...options });
|
|
6877
6927
|
}
|
|
6878
6928
|
static schema() {
|
|
6879
6929
|
return {
|
|
@@ -6993,7 +7043,7 @@ class PreferTbody extends Rule {
|
|
|
6993
7043
|
}
|
|
6994
7044
|
}
|
|
6995
7045
|
|
|
6996
|
-
const defaults$
|
|
7046
|
+
const defaults$6 = {
|
|
6997
7047
|
target: "all",
|
|
6998
7048
|
};
|
|
6999
7049
|
const crossorigin = new RegExp("^(\\w+://|//)"); /* e.g. https:// or // */
|
|
@@ -7003,7 +7053,7 @@ const supportSri = {
|
|
|
7003
7053
|
};
|
|
7004
7054
|
class RequireSri extends Rule {
|
|
7005
7055
|
constructor(options) {
|
|
7006
|
-
super({ ...defaults$
|
|
7056
|
+
super({ ...defaults$6, ...options });
|
|
7007
7057
|
this.target = this.options.target;
|
|
7008
7058
|
}
|
|
7009
7059
|
static schema() {
|
|
@@ -7131,6 +7181,175 @@ class SvgFocusable extends Rule {
|
|
|
7131
7181
|
}
|
|
7132
7182
|
}
|
|
7133
7183
|
|
|
7184
|
+
const defaults$5 = {
|
|
7185
|
+
characters: [
|
|
7186
|
+
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
7187
|
+
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" },
|
|
7188
|
+
],
|
|
7189
|
+
ignoreClasses: [],
|
|
7190
|
+
ignoreStyle: true,
|
|
7191
|
+
};
|
|
7192
|
+
function constructRegex(characters) {
|
|
7193
|
+
const disallowed = characters
|
|
7194
|
+
.map((it) => {
|
|
7195
|
+
return it.pattern;
|
|
7196
|
+
})
|
|
7197
|
+
.join("|");
|
|
7198
|
+
const pattern = `(${disallowed})`;
|
|
7199
|
+
/* eslint-disable-next-line security/detect-non-literal-regexp */
|
|
7200
|
+
return new RegExp(pattern, "g");
|
|
7201
|
+
}
|
|
7202
|
+
function getText(node) {
|
|
7203
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
|
7204
|
+
const match = node.textContent.match(/^(\s*)(.*)$/);
|
|
7205
|
+
const [, leading, text] = match;
|
|
7206
|
+
return [leading.length, text.trimEnd()];
|
|
7207
|
+
}
|
|
7208
|
+
/**
|
|
7209
|
+
* Node 12 does not support String.matchAll, this simulates it's behavior.
|
|
7210
|
+
*/
|
|
7211
|
+
function matchAll(text, regexp) {
|
|
7212
|
+
/* eslint-disable-next-line security/detect-non-literal-regexp */
|
|
7213
|
+
const copy = new RegExp(regexp);
|
|
7214
|
+
const matches = [];
|
|
7215
|
+
/* eslint-disable-next-line no-constant-condition */
|
|
7216
|
+
while (true) {
|
|
7217
|
+
const match = copy.exec(text);
|
|
7218
|
+
if (match === null) {
|
|
7219
|
+
break;
|
|
7220
|
+
}
|
|
7221
|
+
matches.push(match);
|
|
7222
|
+
}
|
|
7223
|
+
return matches;
|
|
7224
|
+
}
|
|
7225
|
+
class TelNonBreaking extends Rule {
|
|
7226
|
+
constructor(options) {
|
|
7227
|
+
super({ ...defaults$5, ...options });
|
|
7228
|
+
this.regex = constructRegex(this.options.characters);
|
|
7229
|
+
}
|
|
7230
|
+
static schema() {
|
|
7231
|
+
return {
|
|
7232
|
+
characters: {
|
|
7233
|
+
type: "array",
|
|
7234
|
+
items: {
|
|
7235
|
+
type: "object",
|
|
7236
|
+
additionalProperties: false,
|
|
7237
|
+
properties: {
|
|
7238
|
+
pattern: {
|
|
7239
|
+
type: "string",
|
|
7240
|
+
},
|
|
7241
|
+
replacement: {
|
|
7242
|
+
type: "string",
|
|
7243
|
+
},
|
|
7244
|
+
description: {
|
|
7245
|
+
type: "string",
|
|
7246
|
+
},
|
|
7247
|
+
},
|
|
7248
|
+
},
|
|
7249
|
+
},
|
|
7250
|
+
ignoreClasses: {
|
|
7251
|
+
type: "array",
|
|
7252
|
+
items: {
|
|
7253
|
+
type: "string",
|
|
7254
|
+
},
|
|
7255
|
+
},
|
|
7256
|
+
ignoreStyle: {
|
|
7257
|
+
type: "boolean",
|
|
7258
|
+
},
|
|
7259
|
+
};
|
|
7260
|
+
}
|
|
7261
|
+
documentation(context) {
|
|
7262
|
+
const { characters } = this.options;
|
|
7263
|
+
const replacements = characters.map((it) => {
|
|
7264
|
+
return ` - \`${it.pattern}\` - replace with \`${it.replacement}\` (${it.description}).`;
|
|
7265
|
+
});
|
|
7266
|
+
return {
|
|
7267
|
+
description: [
|
|
7268
|
+
context
|
|
7269
|
+
? `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`
|
|
7270
|
+
: `Replace this character with a non-breaking version.`,
|
|
7271
|
+
"",
|
|
7272
|
+
"Unless non-breaking characters is used there could be a line break inserted at that character.",
|
|
7273
|
+
"Line breaks make is harder to read and understand the telephone number.",
|
|
7274
|
+
"",
|
|
7275
|
+
"The following characters should be avoided:",
|
|
7276
|
+
"",
|
|
7277
|
+
...replacements,
|
|
7278
|
+
].join("\n"),
|
|
7279
|
+
url: ruleDocumentationUrl("@/rules/tel-non-breaking.ts"),
|
|
7280
|
+
};
|
|
7281
|
+
}
|
|
7282
|
+
setup() {
|
|
7283
|
+
this.on("element:ready", this.isRelevant, (event) => {
|
|
7284
|
+
const { target } = event;
|
|
7285
|
+
if (this.isIgnored(target)) {
|
|
7286
|
+
return;
|
|
7287
|
+
}
|
|
7288
|
+
this.walk(target, target);
|
|
7289
|
+
});
|
|
7290
|
+
}
|
|
7291
|
+
isRelevant(event) {
|
|
7292
|
+
const { target } = event;
|
|
7293
|
+
/* should only deal with anchors */
|
|
7294
|
+
if (!target.is("a")) {
|
|
7295
|
+
return false;
|
|
7296
|
+
}
|
|
7297
|
+
/* ignore if anchor does not have tel href */
|
|
7298
|
+
const attr = target.getAttribute("href");
|
|
7299
|
+
if (!attr || !attr.valueMatches(/^tel:/, false)) {
|
|
7300
|
+
return false;
|
|
7301
|
+
}
|
|
7302
|
+
return true;
|
|
7303
|
+
}
|
|
7304
|
+
isIgnoredClass(node) {
|
|
7305
|
+
const { ignoreClasses } = this.options;
|
|
7306
|
+
const { classList } = node;
|
|
7307
|
+
return ignoreClasses.some((it) => classList.contains(it));
|
|
7308
|
+
}
|
|
7309
|
+
isIgnoredStyle(node) {
|
|
7310
|
+
const { ignoreStyle } = this.options;
|
|
7311
|
+
const { style } = node;
|
|
7312
|
+
if (!ignoreStyle) {
|
|
7313
|
+
return false;
|
|
7314
|
+
}
|
|
7315
|
+
if (style["white-space"] === "nowrap" || style["white-space"] === "pre") {
|
|
7316
|
+
return true;
|
|
7317
|
+
}
|
|
7318
|
+
return false;
|
|
7319
|
+
}
|
|
7320
|
+
isIgnored(node) {
|
|
7321
|
+
return this.isIgnoredClass(node) || this.isIgnoredStyle(node);
|
|
7322
|
+
}
|
|
7323
|
+
walk(anchor, node) {
|
|
7324
|
+
for (const child of node.childNodes) {
|
|
7325
|
+
if (isTextNode(child)) {
|
|
7326
|
+
this.detectDisallowed(anchor, child);
|
|
7327
|
+
}
|
|
7328
|
+
else if (isElementNode(child)) {
|
|
7329
|
+
this.walk(anchor, child);
|
|
7330
|
+
}
|
|
7331
|
+
}
|
|
7332
|
+
}
|
|
7333
|
+
detectDisallowed(anchor, node) {
|
|
7334
|
+
const [offset, text] = getText(node);
|
|
7335
|
+
const matches = matchAll(text, this.regex);
|
|
7336
|
+
for (const match of matches) {
|
|
7337
|
+
const detected = match[0];
|
|
7338
|
+
const entry = this.options.characters.find((it) => it.pattern === detected);
|
|
7339
|
+
/* istanbul ignore next: should never happen and cannot be tested, just a sanity check */
|
|
7340
|
+
if (!entry) {
|
|
7341
|
+
throw new Error(`Failed to find entry for "${detected}" when searching text "${text}"`);
|
|
7342
|
+
}
|
|
7343
|
+
const message = `"${detected}" should be replaced with "${entry.replacement}" (${entry.description}) in telephone number`;
|
|
7344
|
+
const begin = offset + match.index;
|
|
7345
|
+
const end = begin + detected.length;
|
|
7346
|
+
const location = sliceLocation(node.location, begin, end);
|
|
7347
|
+
const context = entry;
|
|
7348
|
+
this.report(anchor, message, location, context);
|
|
7349
|
+
}
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7352
|
+
|
|
7134
7353
|
function hasAltText(image) {
|
|
7135
7354
|
const alt = image.getAttribute("alt");
|
|
7136
7355
|
/* missing or boolean */
|
|
@@ -9161,9 +9380,6 @@ function parseStyle$1(name) {
|
|
|
9161
9380
|
case "selfclose":
|
|
9162
9381
|
case "selfclosing":
|
|
9163
9382
|
return Style$1.AlwaysSelfclose;
|
|
9164
|
-
/* istanbul ignore next: covered by schema validation */
|
|
9165
|
-
default:
|
|
9166
|
-
throw new Error(`Invalid style "${name}" for "void" rule`);
|
|
9167
9383
|
}
|
|
9168
9384
|
}
|
|
9169
9385
|
|
|
@@ -9595,6 +9811,7 @@ const bundledRules = {
|
|
|
9595
9811
|
"script-element": ScriptElement,
|
|
9596
9812
|
"script-type": ScriptType,
|
|
9597
9813
|
"svg-focusable": SvgFocusable,
|
|
9814
|
+
"tel-non-breaking": TelNonBreaking,
|
|
9598
9815
|
"text-content": TextContent,
|
|
9599
9816
|
"unrecognized-char-ref": UnknownCharReference,
|
|
9600
9817
|
void: Void,
|
|
@@ -9691,6 +9908,7 @@ const config$1 = {
|
|
|
9691
9908
|
"script-element": "error",
|
|
9692
9909
|
"script-type": "error",
|
|
9693
9910
|
"svg-focusable": "off",
|
|
9911
|
+
"tel-non-breaking": "error",
|
|
9694
9912
|
"text-content": "error",
|
|
9695
9913
|
"unrecognized-char-ref": "error",
|
|
9696
9914
|
void: "off",
|
|
@@ -9796,7 +10014,8 @@ class ResolvedConfig {
|
|
|
9796
10014
|
});
|
|
9797
10015
|
}
|
|
9798
10016
|
catch (err) {
|
|
9799
|
-
|
|
10017
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10018
|
+
throw new NestedError(`When transforming "${source.filename}": ${message}`, err);
|
|
9800
10019
|
}
|
|
9801
10020
|
}
|
|
9802
10021
|
else {
|
|
@@ -9872,9 +10091,10 @@ function loadFromFile(filename) {
|
|
|
9872
10091
|
}
|
|
9873
10092
|
/* expand any relative paths */
|
|
9874
10093
|
for (const key of ["extends", "elements", "plugins"]) {
|
|
9875
|
-
|
|
10094
|
+
const value = json[key];
|
|
10095
|
+
if (!value)
|
|
9876
10096
|
continue;
|
|
9877
|
-
json[key] =
|
|
10097
|
+
json[key] = value.map((ref) => {
|
|
9878
10098
|
return Config.expandRelative(ref, path__default["default"].dirname(filename));
|
|
9879
10099
|
});
|
|
9880
10100
|
}
|
|
@@ -10032,6 +10252,7 @@ class Config {
|
|
|
10032
10252
|
/**
|
|
10033
10253
|
* Get element metadata.
|
|
10034
10254
|
*/
|
|
10255
|
+
/* eslint-disable-next-line complexity, sonarjs/cognitive-complexity */
|
|
10035
10256
|
getMetaTable() {
|
|
10036
10257
|
/* use cached table if it exists */
|
|
10037
10258
|
if (this.metaTable) {
|
|
@@ -10054,7 +10275,7 @@ class Config {
|
|
|
10054
10275
|
}
|
|
10055
10276
|
let filename;
|
|
10056
10277
|
/* try searching builtin metadata */
|
|
10057
|
-
filename = path__default["default"].join(projectRoot, "elements", `${entry}.
|
|
10278
|
+
filename = path__default["default"].join(projectRoot, "elements", `${entry}.js`);
|
|
10058
10279
|
if (fs__default["default"].existsSync(filename)) {
|
|
10059
10280
|
metaTable.loadFromFile(filename);
|
|
10060
10281
|
continue;
|
|
@@ -10070,7 +10291,8 @@ class Config {
|
|
|
10070
10291
|
metaTable.loadFromObject(legacyRequire(entry));
|
|
10071
10292
|
}
|
|
10072
10293
|
catch (err) {
|
|
10073
|
-
|
|
10294
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10295
|
+
throw new ConfigError(`Failed to load elements from "${entry}": ${message}`, err);
|
|
10074
10296
|
}
|
|
10075
10297
|
}
|
|
10076
10298
|
metaTable.init();
|
|
@@ -10146,7 +10368,8 @@ class Config {
|
|
|
10146
10368
|
return plugin;
|
|
10147
10369
|
}
|
|
10148
10370
|
catch (err) {
|
|
10149
|
-
|
|
10371
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10372
|
+
throw new ConfigError(`Failed to load plugin "${moduleName}": ${message}`, err);
|
|
10150
10373
|
}
|
|
10151
10374
|
});
|
|
10152
10375
|
}
|
|
@@ -10466,7 +10689,7 @@ class ParserError extends Error {
|
|
|
10466
10689
|
}
|
|
10467
10690
|
|
|
10468
10691
|
function isAttrValueToken(token) {
|
|
10469
|
-
return Boolean(token && token.type ===
|
|
10692
|
+
return Boolean(token && token.type === TokenType.ATTR_VALUE);
|
|
10470
10693
|
}
|
|
10471
10694
|
function svgShouldRetainTag(foreignTagName, tagName) {
|
|
10472
10695
|
return foreignTagName === "svg" && ["title", "desc"].includes(tagName);
|
|
@@ -10574,43 +10797,43 @@ class Parser {
|
|
|
10574
10797
|
/* eslint-disable-next-line complexity */
|
|
10575
10798
|
consume(source, token, tokenStream) {
|
|
10576
10799
|
switch (token.type) {
|
|
10577
|
-
case
|
|
10800
|
+
case TokenType.UNICODE_BOM:
|
|
10578
10801
|
/* ignore */
|
|
10579
10802
|
break;
|
|
10580
|
-
case
|
|
10803
|
+
case TokenType.TAG_OPEN:
|
|
10581
10804
|
this.consumeTag(source, token, tokenStream);
|
|
10582
10805
|
break;
|
|
10583
|
-
case
|
|
10806
|
+
case TokenType.WHITESPACE:
|
|
10584
10807
|
this.trigger("whitespace", {
|
|
10585
10808
|
text: token.data[0],
|
|
10586
10809
|
location: token.location,
|
|
10587
10810
|
});
|
|
10588
10811
|
this.appendText(token.data[0], token.location);
|
|
10589
10812
|
break;
|
|
10590
|
-
case
|
|
10813
|
+
case TokenType.DIRECTIVE:
|
|
10591
10814
|
this.consumeDirective(token);
|
|
10592
10815
|
break;
|
|
10593
|
-
case
|
|
10816
|
+
case TokenType.CONDITIONAL:
|
|
10594
10817
|
this.consumeConditional(token);
|
|
10595
10818
|
break;
|
|
10596
|
-
case
|
|
10819
|
+
case TokenType.COMMENT:
|
|
10597
10820
|
this.consumeComment(token);
|
|
10598
10821
|
break;
|
|
10599
|
-
case
|
|
10822
|
+
case TokenType.DOCTYPE_OPEN:
|
|
10600
10823
|
this.consumeDoctype(token, tokenStream);
|
|
10601
10824
|
break;
|
|
10602
|
-
case
|
|
10603
|
-
case
|
|
10825
|
+
case TokenType.TEXT:
|
|
10826
|
+
case TokenType.TEMPLATING:
|
|
10604
10827
|
this.appendText(token.data[0], token.location);
|
|
10605
10828
|
break;
|
|
10606
|
-
case
|
|
10829
|
+
case TokenType.EOF:
|
|
10607
10830
|
this.closeTree(source, token.location);
|
|
10608
10831
|
break;
|
|
10609
10832
|
}
|
|
10610
10833
|
}
|
|
10611
10834
|
/* eslint-disable-next-line complexity, sonarjs/cognitive-complexity */
|
|
10612
10835
|
consumeTag(source, startToken, tokenStream) {
|
|
10613
|
-
const tokens = Array.from(this.consumeUntil(tokenStream,
|
|
10836
|
+
const tokens = Array.from(this.consumeUntil(tokenStream, TokenType.TAG_CLOSE, startToken.location));
|
|
10614
10837
|
const endToken = tokens.slice(-1)[0];
|
|
10615
10838
|
const closeOptional = this.closeOptional(startToken);
|
|
10616
10839
|
const parent = closeOptional ? this.dom.getActive().parent : this.dom.getActive();
|
|
@@ -10636,9 +10859,9 @@ class Parser {
|
|
|
10636
10859
|
for (let i = 0; i < tokens.length; i++) {
|
|
10637
10860
|
const token = tokens[i];
|
|
10638
10861
|
switch (token.type) {
|
|
10639
|
-
case
|
|
10862
|
+
case TokenType.WHITESPACE:
|
|
10640
10863
|
break;
|
|
10641
|
-
case
|
|
10864
|
+
case TokenType.ATTR_NAME:
|
|
10642
10865
|
this.consumeAttribute(source, node, token, tokens[i + 1]);
|
|
10643
10866
|
break;
|
|
10644
10867
|
}
|
|
@@ -10716,7 +10939,7 @@ class Parser {
|
|
|
10716
10939
|
let endToken;
|
|
10717
10940
|
do {
|
|
10718
10941
|
/* search for tags */
|
|
10719
|
-
const tokens = Array.from(this.consumeUntil(tokenStream,
|
|
10942
|
+
const tokens = Array.from(this.consumeUntil(tokenStream, TokenType.TAG_OPEN, errorLocation));
|
|
10720
10943
|
const [last] = tokens.slice(-1);
|
|
10721
10944
|
const [, tagClosed, tagName] = last.data;
|
|
10722
10945
|
/* special case: svg <title> and <desc> should be intact as it affects accessibility */
|
|
@@ -10733,7 +10956,7 @@ class Parser {
|
|
|
10733
10956
|
continue;
|
|
10734
10957
|
}
|
|
10735
10958
|
/* locate end token and determine if this is a self-closed tag */
|
|
10736
|
-
const endTokens = Array.from(this.consumeUntil(tokenStream,
|
|
10959
|
+
const endTokens = Array.from(this.consumeUntil(tokenStream, TokenType.TAG_CLOSE, last.location));
|
|
10737
10960
|
endToken = endTokens.slice(-1)[0];
|
|
10738
10961
|
const selfClosed = endToken.data[0] === "/>";
|
|
10739
10962
|
/* since foreign element may be nested keep a count for the number of
|
|
@@ -10819,7 +11042,7 @@ class Parser {
|
|
|
10819
11042
|
* ^^^ ^^^ ^^^ (null) (null)
|
|
10820
11043
|
*/
|
|
10821
11044
|
getAttributeValueLocation(token) {
|
|
10822
|
-
if (!token || token.type !==
|
|
11045
|
+
if (!token || token.type !== TokenType.ATTR_VALUE || token.data[2] === "") {
|
|
10823
11046
|
return null;
|
|
10824
11047
|
}
|
|
10825
11048
|
const quote = token.data[3];
|
|
@@ -10837,7 +11060,7 @@ class Parser {
|
|
|
10837
11060
|
getAttributeLocation(key, value) {
|
|
10838
11061
|
var _a;
|
|
10839
11062
|
const begin = key.location;
|
|
10840
|
-
const end = value && value.type ===
|
|
11063
|
+
const end = value && value.type === TokenType.ATTR_VALUE ? value.location : undefined;
|
|
10841
11064
|
return {
|
|
10842
11065
|
filename: begin.filename,
|
|
10843
11066
|
line: begin.line,
|
|
@@ -10898,7 +11121,7 @@ class Parser {
|
|
|
10898
11121
|
* Consumes doctype tokens. Emits doctype event.
|
|
10899
11122
|
*/
|
|
10900
11123
|
consumeDoctype(startToken, tokenStream) {
|
|
10901
|
-
const tokens = Array.from(this.consumeUntil(tokenStream,
|
|
11124
|
+
const tokens = Array.from(this.consumeUntil(tokenStream, TokenType.DOCTYPE_CLOSE, startToken.location));
|
|
10902
11125
|
/* first token is the doctype, second is the closing ">" */
|
|
10903
11126
|
const doctype = tokens[0];
|
|
10904
11127
|
const value = doctype.data[0];
|
|
@@ -10924,7 +11147,7 @@ class Parser {
|
|
|
10924
11147
|
return;
|
|
10925
11148
|
it = this.next(tokenStream);
|
|
10926
11149
|
}
|
|
10927
|
-
throw new ParserError(errorLocation, `stream ended before ${
|
|
11150
|
+
throw new ParserError(errorLocation, `stream ended before ${TokenType[search]} token was found`);
|
|
10928
11151
|
}
|
|
10929
11152
|
/**
|
|
10930
11153
|
* Consumes tokens until a matching close-tag is found. Tags are appended to
|
|
@@ -10938,7 +11161,7 @@ class Parser {
|
|
|
10938
11161
|
while (!it.done) {
|
|
10939
11162
|
const token = it.value;
|
|
10940
11163
|
this.consume(source, token, tokenStream);
|
|
10941
|
-
if (token.type ===
|
|
11164
|
+
if (token.type === TokenType.TAG_OPEN) {
|
|
10942
11165
|
const [, close, tagName] = token.data;
|
|
10943
11166
|
if (tagName === searchTag) {
|
|
10944
11167
|
if (close) {
|
|
@@ -11011,6 +11234,12 @@ class Parser {
|
|
|
11011
11234
|
}
|
|
11012
11235
|
}
|
|
11013
11236
|
|
|
11237
|
+
function freeze(src) {
|
|
11238
|
+
return {
|
|
11239
|
+
...src,
|
|
11240
|
+
selector: src.selector(),
|
|
11241
|
+
};
|
|
11242
|
+
}
|
|
11014
11243
|
/**
|
|
11015
11244
|
* @internal
|
|
11016
11245
|
*/
|
|
@@ -11062,7 +11291,9 @@ class Reporter {
|
|
|
11062
11291
|
line: location.line,
|
|
11063
11292
|
column: location.column,
|
|
11064
11293
|
size: location.size || 0,
|
|
11065
|
-
selector
|
|
11294
|
+
selector() {
|
|
11295
|
+
return node ? node.generateSelector() : null;
|
|
11296
|
+
},
|
|
11066
11297
|
context,
|
|
11067
11298
|
});
|
|
11068
11299
|
}
|
|
@@ -11076,7 +11307,7 @@ class Reporter {
|
|
|
11076
11307
|
const report = {
|
|
11077
11308
|
valid: this.isValid(),
|
|
11078
11309
|
results: Object.keys(this.result).map((filePath) => {
|
|
11079
|
-
const messages = Array.from(this.result[filePath]).sort(messageSort);
|
|
11310
|
+
const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
|
|
11080
11311
|
const source = (sources || []).find((source) => { var _a; return filePath === ((_a = source.filename) !== null && _a !== void 0 ? _a : ""); });
|
|
11081
11312
|
return {
|
|
11082
11313
|
filePath,
|
|
@@ -11150,7 +11381,7 @@ class Engine {
|
|
|
11150
11381
|
/**
|
|
11151
11382
|
* Lint sources and return report
|
|
11152
11383
|
*
|
|
11153
|
-
* @param
|
|
11384
|
+
* @param sources - Sources to lint.
|
|
11154
11385
|
* @returns Report output.
|
|
11155
11386
|
*/
|
|
11156
11387
|
lint(sources) {
|
|
@@ -11229,7 +11460,7 @@ class Engine {
|
|
|
11229
11460
|
for (const token of lexer.tokenize(src)) {
|
|
11230
11461
|
const data = (_a = token.data[0]) !== null && _a !== void 0 ? _a : "";
|
|
11231
11462
|
lines.push({
|
|
11232
|
-
token:
|
|
11463
|
+
token: TokenType[token.type],
|
|
11233
11464
|
data,
|
|
11234
11465
|
location: `${token.location.filename}:${token.location.line}:${token.location.column}`,
|
|
11235
11466
|
});
|
|
@@ -11244,7 +11475,7 @@ class Engine {
|
|
|
11244
11475
|
const lines = [];
|
|
11245
11476
|
function decoration(node) {
|
|
11246
11477
|
let output = "";
|
|
11247
|
-
if (node.
|
|
11478
|
+
if (node.id) {
|
|
11248
11479
|
output += `#${node.id}`;
|
|
11249
11480
|
}
|
|
11250
11481
|
if (node.hasAttribute("class")) {
|
|
@@ -11478,7 +11709,7 @@ class Engine {
|
|
|
11478
11709
|
line: location.line,
|
|
11479
11710
|
column: location.column,
|
|
11480
11711
|
size: location.size || 0,
|
|
11481
|
-
selector: null,
|
|
11712
|
+
selector: () => null,
|
|
11482
11713
|
});
|
|
11483
11714
|
}
|
|
11484
11715
|
}
|
|
@@ -12000,6 +12231,8 @@ const formatter$4 = checkstyleFormatter;
|
|
|
12000
12231
|
|
|
12001
12232
|
const defaults = {
|
|
12002
12233
|
showLink: true,
|
|
12234
|
+
showSummary: true,
|
|
12235
|
+
showSelector: false,
|
|
12003
12236
|
};
|
|
12004
12237
|
/**
|
|
12005
12238
|
* Codeframe formatter based on ESLint codeframe.
|
|
@@ -12055,6 +12288,7 @@ function getEndLocation(message, source) {
|
|
|
12055
12288
|
* @returns The formatted output.
|
|
12056
12289
|
*/
|
|
12057
12290
|
function formatMessage(message, parentResult, options) {
|
|
12291
|
+
var _a;
|
|
12058
12292
|
const type = message.severity === 2 ? kleur__default["default"].red("error") : kleur__default["default"].yellow("warning");
|
|
12059
12293
|
const msg = `${kleur__default["default"].bold(message.message.replace(/([^ ])\.$/, "$1"))}`;
|
|
12060
12294
|
const ruleId = kleur__default["default"].dim(`(${message.ruleId})`);
|
|
@@ -12077,6 +12311,9 @@ function formatMessage(message, parentResult, options) {
|
|
|
12077
12311
|
end: getEndLocation(message, sourceCode),
|
|
12078
12312
|
}, { highlightCode: false }));
|
|
12079
12313
|
}
|
|
12314
|
+
if (options.showSelector) {
|
|
12315
|
+
result.push(`${kleur__default["default"].bold("Selector:")} ${(_a = message.selector) !== null && _a !== void 0 ? _a : "-"}`);
|
|
12316
|
+
}
|
|
12080
12317
|
if (options.showLink && message.ruleUrl) {
|
|
12081
12318
|
result.push(`${kleur__default["default"].bold("Details:")} ${message.ruleUrl}`);
|
|
12082
12319
|
}
|
|
@@ -12114,9 +12351,11 @@ function codeframe(results, options) {
|
|
|
12114
12351
|
return resultsOutput.concat(messages);
|
|
12115
12352
|
}, [])
|
|
12116
12353
|
.join("\n");
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12354
|
+
if (merged.showSummary) {
|
|
12355
|
+
output += "\n";
|
|
12356
|
+
output += formatSummary(errors, warnings);
|
|
12357
|
+
output += "\n";
|
|
12358
|
+
}
|
|
12120
12359
|
return errors + warnings > 0 ? output : "";
|
|
12121
12360
|
}
|
|
12122
12361
|
const formatter$3 = codeframe;
|
|
@@ -12216,6 +12455,7 @@ exports.TemplateExtractor = TemplateExtractor;
|
|
|
12216
12455
|
exports.TextNode = TextNode;
|
|
12217
12456
|
exports.UserError = UserError;
|
|
12218
12457
|
exports.bugs = bugs;
|
|
12458
|
+
exports.codeframe = codeframe;
|
|
12219
12459
|
exports.compatibilityCheck = compatibilityCheck;
|
|
12220
12460
|
exports.getFormatter = getFormatter;
|
|
12221
12461
|
exports.legacyRequire = legacyRequire;
|