html-validate 6.7.1 → 6.9.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/core.js CHANGED
@@ -274,6 +274,42 @@ var ajvSchemaDraft = {
274
274
  }
275
275
  };
276
276
 
277
+ function stringify(value) {
278
+ if (typeof value === "string") {
279
+ return String(value);
280
+ }
281
+ else {
282
+ return JSON.stringify(value);
283
+ }
284
+ }
285
+ /**
286
+ * Represents an `Error` created from arbitrary values.
287
+ *
288
+ * @public
289
+ */
290
+ class WrappedError extends Error {
291
+ constructor(message) {
292
+ super(stringify(message));
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Ensures the value is an Error.
298
+ *
299
+ * If the passed value is not an `Error` instance a [[WrappedError]] is
300
+ * constructed with the stringified value.
301
+ *
302
+ * @internal
303
+ */
304
+ function ensureError(value) {
305
+ if (value instanceof Error) {
306
+ return value;
307
+ }
308
+ else {
309
+ return new WrappedError(value);
310
+ }
311
+ }
312
+
277
313
  class NestedError extends Error {
278
314
  constructor(message, nested) {
279
315
  super(message);
@@ -962,7 +998,7 @@ class MetaTable {
962
998
  if (err instanceof SchemaValidationError) {
963
999
  throw err;
964
1000
  }
965
- throw new UserError(`Failed to load element metadata from "${filename}"`, err);
1001
+ throw new UserError(`Failed to load element metadata from "${filename}"`, ensureError(err));
966
1002
  }
967
1003
  }
968
1004
  /**
@@ -1233,6 +1269,27 @@ class Attribute {
1233
1269
  }
1234
1270
  }
1235
1271
 
1272
+ function getCSSDeclarations(value) {
1273
+ return value
1274
+ .trim()
1275
+ .split(";")
1276
+ .filter(Boolean)
1277
+ .map((it) => {
1278
+ const [property, value] = it.split(":", 2);
1279
+ return [property.trim(), value ? value.trim() : ""];
1280
+ });
1281
+ }
1282
+ /**
1283
+ * @internal
1284
+ */
1285
+ function parseCssDeclaration(value) {
1286
+ if (!value || value instanceof DynamicValue) {
1287
+ return {};
1288
+ }
1289
+ const pairs = getCSSDeclarations(value);
1290
+ return Object.fromEntries(pairs);
1291
+ }
1292
+
1236
1293
  function sliceSize(size, begin, end) {
1237
1294
  if (typeof size !== "number") {
1238
1295
  return size;
@@ -1988,9 +2045,10 @@ class HtmlElement extends DOMNode {
1988
2045
  /* if a unique id is present, use it and short-circuit */
1989
2046
  if (cur.id) {
1990
2047
  const escaped = escapeSelectorComponent(cur.id);
1991
- const matches = root.querySelectorAll(`#${escaped}`);
2048
+ const selector = escaped.match(/^\d/) ? `[id="${escaped}"]` : `#${escaped}`;
2049
+ const matches = root.querySelectorAll(selector);
1992
2050
  if (matches.length === 1) {
1993
- parts.push(`#${escaped}`);
2051
+ parts.push(selector);
1994
2052
  break;
1995
2053
  }
1996
2054
  }
@@ -2181,6 +2239,10 @@ class HtmlElement extends DOMNode {
2181
2239
  get id() {
2182
2240
  return this.getAttributeValue("id");
2183
2241
  }
2242
+ get style() {
2243
+ const attr = this.getAttribute("style");
2244
+ return parseCssDeclaration(attr === null || attr === void 0 ? void 0 : attr.value);
2245
+ }
2184
2246
  /**
2185
2247
  * Returns the first child element or null if there are no child elements.
2186
2248
  */
@@ -2986,7 +3048,7 @@ var TRANSFORMER_API;
2986
3048
  /** @public */
2987
3049
  const name = "html-validate";
2988
3050
  /** @public */
2989
- const version = "6.7.1";
3051
+ const version = "6.9.1";
2990
3052
  /** @public */
2991
3053
  const homepage = "https://html-validate.org";
2992
3054
  /** @public */
@@ -3307,7 +3369,7 @@ function ruleDocumentationUrl(filename) {
3307
3369
  return `${homepage}/rules/${normalized}.html`;
3308
3370
  }
3309
3371
 
3310
- const defaults$q = {
3372
+ const defaults$r = {
3311
3373
  allowExternal: true,
3312
3374
  allowRelative: true,
3313
3375
  allowAbsolute: true,
@@ -3351,7 +3413,7 @@ function matchList(value, list) {
3351
3413
  }
3352
3414
  class AllowedLinks extends Rule {
3353
3415
  constructor(options) {
3354
- super({ ...defaults$q, ...options });
3416
+ super({ ...defaults$r, ...options });
3355
3417
  this.allowExternal = parseAllow(this.options.allowExternal);
3356
3418
  this.allowRelative = parseAllow(this.options.allowRelative);
3357
3419
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -3652,13 +3714,13 @@ class CaseStyle {
3652
3714
  }
3653
3715
  }
3654
3716
 
3655
- const defaults$p = {
3717
+ const defaults$q = {
3656
3718
  style: "lowercase",
3657
3719
  ignoreForeign: true,
3658
3720
  };
3659
3721
  class AttrCase extends Rule {
3660
3722
  constructor(options) {
3661
- super({ ...defaults$p, ...options });
3723
+ super({ ...defaults$q, ...options });
3662
3724
  this.style = new CaseStyle(this.options.style, "attr-case");
3663
3725
  }
3664
3726
  static schema() {
@@ -3720,7 +3782,7 @@ class AttrCase extends Rule {
3720
3782
  }
3721
3783
  }
3722
3784
 
3723
- exports.TokenType = void 0;
3785
+ var TokenType;
3724
3786
  (function (TokenType) {
3725
3787
  TokenType[TokenType["UNICODE_BOM"] = 1] = "UNICODE_BOM";
3726
3788
  TokenType[TokenType["WHITESPACE"] = 2] = "WHITESPACE";
@@ -3739,7 +3801,7 @@ exports.TokenType = void 0;
3739
3801
  TokenType[TokenType["CONDITIONAL"] = 15] = "CONDITIONAL";
3740
3802
  TokenType[TokenType["DIRECTIVE"] = 16] = "DIRECTIVE";
3741
3803
  TokenType[TokenType["EOF"] = 17] = "EOF";
3742
- })(exports.TokenType || (exports.TokenType = {}));
3804
+ })(TokenType || (TokenType = {}));
3743
3805
 
3744
3806
  /* eslint-disable no-useless-escape */
3745
3807
  const MATCH_UNICODE_BOM = /^\uFEFF/;
@@ -3818,7 +3880,7 @@ class Lexer {
3818
3880
  previousState = context.state;
3819
3881
  previousLength = context.string.length;
3820
3882
  }
3821
- yield this.token(context, exports.TokenType.EOF, []);
3883
+ yield this.token(context, TokenType.EOF, []);
3822
3884
  }
3823
3885
  token(context, type, data) {
3824
3886
  const size = data.length > 0 ? data[0].length : 0;
@@ -3889,21 +3951,21 @@ class Lexer {
3889
3951
  }
3890
3952
  *tokenizeInitial(context) {
3891
3953
  yield* this.match(context, [
3892
- [MATCH_UNICODE_BOM, State.INITIAL, exports.TokenType.UNICODE_BOM],
3954
+ [MATCH_UNICODE_BOM, State.INITIAL, TokenType.UNICODE_BOM],
3893
3955
  [MATCH_XML_TAG, State.INITIAL, false],
3894
- [MATCH_DOCTYPE_OPEN, State.DOCTYPE, exports.TokenType.DOCTYPE_OPEN],
3895
- [MATCH_WHITESPACE, State.INITIAL, exports.TokenType.WHITESPACE],
3896
- [MATCH_DIRECTIVE, State.INITIAL, exports.TokenType.DIRECTIVE],
3897
- [MATCH_CONDITIONAL, State.INITIAL, exports.TokenType.CONDITIONAL],
3898
- [MATCH_COMMENT, State.INITIAL, exports.TokenType.COMMENT],
3956
+ [MATCH_DOCTYPE_OPEN, State.DOCTYPE, TokenType.DOCTYPE_OPEN],
3957
+ [MATCH_WHITESPACE, State.INITIAL, TokenType.WHITESPACE],
3958
+ [MATCH_DIRECTIVE, State.INITIAL, TokenType.DIRECTIVE],
3959
+ [MATCH_CONDITIONAL, State.INITIAL, TokenType.CONDITIONAL],
3960
+ [MATCH_COMMENT, State.INITIAL, TokenType.COMMENT],
3899
3961
  [false, State.TEXT, false],
3900
3962
  ], "expected doctype");
3901
3963
  }
3902
3964
  *tokenizeDoctype(context) {
3903
3965
  yield* this.match(context, [
3904
- [MATCH_WHITESPACE, State.DOCTYPE, exports.TokenType.WHITESPACE],
3905
- [MATCH_DOCTYPE_VALUE, State.DOCTYPE, exports.TokenType.DOCTYPE_VALUE],
3906
- [MATCH_DOCTYPE_CLOSE, State.TEXT, exports.TokenType.DOCTYPE_CLOSE],
3966
+ [MATCH_WHITESPACE, State.DOCTYPE, TokenType.WHITESPACE],
3967
+ [MATCH_DOCTYPE_VALUE, State.DOCTYPE, TokenType.DOCTYPE_VALUE],
3968
+ [MATCH_DOCTYPE_CLOSE, State.TEXT, TokenType.DOCTYPE_CLOSE],
3907
3969
  ], "expected doctype name");
3908
3970
  }
3909
3971
  *tokenizeTag(context) {
@@ -3930,30 +3992,30 @@ class Lexer {
3930
3992
  }
3931
3993
  }
3932
3994
  yield* this.match(context, [
3933
- [MATCH_TAG_CLOSE, nextState, exports.TokenType.TAG_CLOSE],
3934
- [MATCH_ATTR_START, State.ATTR, exports.TokenType.ATTR_NAME],
3935
- [MATCH_WHITESPACE, State.TAG, exports.TokenType.WHITESPACE],
3995
+ [MATCH_TAG_CLOSE, nextState, TokenType.TAG_CLOSE],
3996
+ [MATCH_ATTR_START, State.ATTR, TokenType.ATTR_NAME],
3997
+ [MATCH_WHITESPACE, State.TAG, TokenType.WHITESPACE],
3936
3998
  ], 'expected attribute, ">" or "/>"');
3937
3999
  }
3938
4000
  *tokenizeAttr(context) {
3939
4001
  yield* this.match(context, [
3940
- [MATCH_ATTR_SINGLE, State.TAG, exports.TokenType.ATTR_VALUE],
3941
- [MATCH_ATTR_DOUBLE, State.TAG, exports.TokenType.ATTR_VALUE],
3942
- [MATCH_ATTR_UNQUOTED, State.TAG, exports.TokenType.ATTR_VALUE],
4002
+ [MATCH_ATTR_SINGLE, State.TAG, TokenType.ATTR_VALUE],
4003
+ [MATCH_ATTR_DOUBLE, State.TAG, TokenType.ATTR_VALUE],
4004
+ [MATCH_ATTR_UNQUOTED, State.TAG, TokenType.ATTR_VALUE],
3943
4005
  [false, State.TAG, false],
3944
4006
  ], 'expected attribute, ">" or "/>"');
3945
4007
  }
3946
4008
  *tokenizeText(context) {
3947
4009
  yield* this.match(context, [
3948
- [MATCH_WHITESPACE, State.TEXT, exports.TokenType.WHITESPACE],
4010
+ [MATCH_WHITESPACE, State.TEXT, TokenType.WHITESPACE],
3949
4011
  [MATCH_CDATA_BEGIN, State.CDATA, false],
3950
- [MATCH_DIRECTIVE, State.TEXT, exports.TokenType.DIRECTIVE],
3951
- [MATCH_CONDITIONAL, State.TEXT, exports.TokenType.CONDITIONAL],
3952
- [MATCH_COMMENT, State.TEXT, exports.TokenType.COMMENT],
3953
- [MATCH_TEMPLATING, State.TEXT, exports.TokenType.TEMPLATING],
3954
- [MATCH_TAG_OPEN, State.TAG, exports.TokenType.TAG_OPEN],
3955
- [MATCH_TEXT, State.TEXT, exports.TokenType.TEXT],
3956
- [MATCH_TAG_LOOKAHEAD, State.TEXT, exports.TokenType.TEXT],
4012
+ [MATCH_DIRECTIVE, State.TEXT, TokenType.DIRECTIVE],
4013
+ [MATCH_CONDITIONAL, State.TEXT, TokenType.CONDITIONAL],
4014
+ [MATCH_COMMENT, State.TEXT, TokenType.COMMENT],
4015
+ [MATCH_TEMPLATING, State.TEXT, TokenType.TEMPLATING],
4016
+ [MATCH_TAG_OPEN, State.TAG, TokenType.TAG_OPEN],
4017
+ [MATCH_TEXT, State.TEXT, TokenType.TEXT],
4018
+ [MATCH_TAG_LOOKAHEAD, State.TEXT, TokenType.TEXT],
3957
4019
  ], 'expected text or "<"');
3958
4020
  }
3959
4021
  *tokenizeCDATA(context) {
@@ -3961,22 +4023,19 @@ class Lexer {
3961
4023
  }
3962
4024
  *tokenizeScript(context) {
3963
4025
  yield* this.match(context, [
3964
- [MATCH_SCRIPT_END, State.TAG, exports.TokenType.TAG_OPEN],
3965
- [MATCH_SCRIPT_DATA, State.SCRIPT, exports.TokenType.SCRIPT],
4026
+ [MATCH_SCRIPT_END, State.TAG, TokenType.TAG_OPEN],
4027
+ [MATCH_SCRIPT_DATA, State.SCRIPT, TokenType.SCRIPT],
3966
4028
  ], "expected </script>");
3967
4029
  }
3968
4030
  *tokenizeStyle(context) {
3969
4031
  yield* this.match(context, [
3970
- [MATCH_STYLE_END, State.TAG, exports.TokenType.TAG_OPEN],
3971
- [MATCH_STYLE_DATA, State.STYLE, exports.TokenType.STYLE],
4032
+ [MATCH_STYLE_END, State.TAG, TokenType.TAG_OPEN],
4033
+ [MATCH_STYLE_DATA, State.STYLE, TokenType.STYLE],
3972
4034
  ], "expected </style>");
3973
4035
  }
3974
4036
  }
3975
4037
 
3976
4038
  const whitespace = /(\s+)/;
3977
- function isRelevant$3(event) {
3978
- return event.type === exports.TokenType.ATTR_VALUE;
3979
- }
3980
4039
  class AttrDelimiter extends Rule {
3981
4040
  documentation() {
3982
4041
  return {
@@ -3985,8 +4044,12 @@ class AttrDelimiter extends Rule {
3985
4044
  };
3986
4045
  }
3987
4046
  setup() {
3988
- this.on("token", isRelevant$3, (event) => {
3989
- const delimiter = event.data[1];
4047
+ this.on("token", (event) => {
4048
+ const { token } = event;
4049
+ if (token.type !== TokenType.ATTR_VALUE) {
4050
+ return;
4051
+ }
4052
+ const delimiter = token.data[1];
3990
4053
  const match = whitespace.exec(delimiter);
3991
4054
  if (match) {
3992
4055
  const location = sliceLocation(event.location, 0, delimiter.length);
@@ -3997,7 +4060,7 @@ class AttrDelimiter extends Rule {
3997
4060
  }
3998
4061
 
3999
4062
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4000
- const defaults$o = {
4063
+ const defaults$p = {
4001
4064
  pattern: DEFAULT_PATTERN,
4002
4065
  ignoreForeign: true,
4003
4066
  };
@@ -4034,7 +4097,7 @@ function generateDescription(name, pattern) {
4034
4097
  }
4035
4098
  class AttrPattern extends Rule {
4036
4099
  constructor(options) {
4037
- super({ ...defaults$o, ...options });
4100
+ super({ ...defaults$p, ...options });
4038
4101
  this.pattern = generateRegexp(this.options.pattern);
4039
4102
  }
4040
4103
  static schema() {
@@ -4094,13 +4157,13 @@ var QuoteStyle;
4094
4157
  QuoteStyle["DOUBLE_QUOTE"] = "\"";
4095
4158
  QuoteStyle["AUTO_QUOTE"] = "auto";
4096
4159
  })(QuoteStyle || (QuoteStyle = {}));
4097
- const defaults$n = {
4160
+ const defaults$o = {
4098
4161
  style: "auto",
4099
4162
  unquoted: false,
4100
4163
  };
4101
4164
  class AttrQuotes extends Rule {
4102
4165
  constructor(options) {
4103
- super({ ...defaults$n, ...options });
4166
+ super({ ...defaults$o, ...options });
4104
4167
  this.style = parseStyle$4(this.options.style);
4105
4168
  }
4106
4169
  static schema() {
@@ -4179,7 +4242,7 @@ class AttrSpacing extends Rule {
4179
4242
  setup() {
4180
4243
  let previousToken;
4181
4244
  this.on("token", (event) => {
4182
- if (event.type === exports.TokenType.ATTR_NAME && previousToken !== exports.TokenType.WHITESPACE) {
4245
+ if (event.type === TokenType.ATTR_NAME && previousToken !== TokenType.WHITESPACE) {
4183
4246
  this.report(null, "No space between attributes", event.location);
4184
4247
  }
4185
4248
  previousToken = event.type;
@@ -4265,12 +4328,12 @@ class AttributeAllowedValues extends Rule {
4265
4328
  }
4266
4329
  }
4267
4330
 
4268
- const defaults$m = {
4331
+ const defaults$n = {
4269
4332
  style: "omit",
4270
4333
  };
4271
4334
  class AttributeBooleanStyle extends Rule {
4272
4335
  constructor(options) {
4273
- super({ ...defaults$m, ...options });
4336
+ super({ ...defaults$n, ...options });
4274
4337
  this.hasInvalidStyle = parseStyle$3(this.options.style);
4275
4338
  }
4276
4339
  static schema() {
@@ -4346,12 +4409,12 @@ function reportMessage$1(attr, style) {
4346
4409
  return "";
4347
4410
  }
4348
4411
 
4349
- const defaults$l = {
4412
+ const defaults$m = {
4350
4413
  style: "omit",
4351
4414
  };
4352
4415
  class AttributeEmptyStyle extends Rule {
4353
4416
  constructor(options) {
4354
- super({ ...defaults$l, ...options });
4417
+ super({ ...defaults$m, ...options });
4355
4418
  this.hasInvalidStyle = parseStyle$2(this.options.style);
4356
4419
  }
4357
4420
  static schema() {
@@ -4459,12 +4522,12 @@ function describePattern(pattern) {
4459
4522
  }
4460
4523
  }
4461
4524
 
4462
- const defaults$k = {
4525
+ const defaults$l = {
4463
4526
  pattern: "kebabcase",
4464
4527
  };
4465
4528
  class ClassPattern extends Rule {
4466
4529
  constructor(options) {
4467
- super({ ...defaults$k, ...options });
4530
+ super({ ...defaults$l, ...options });
4468
4531
  this.pattern = parsePattern(this.options.pattern);
4469
4532
  }
4470
4533
  static schema() {
@@ -4573,13 +4636,13 @@ class CloseOrder extends Rule {
4573
4636
  }
4574
4637
  }
4575
4638
 
4576
- const defaults$j = {
4639
+ const defaults$k = {
4577
4640
  include: null,
4578
4641
  exclude: null,
4579
4642
  };
4580
4643
  class Deprecated extends Rule {
4581
4644
  constructor(options) {
4582
- super({ ...defaults$j, ...options });
4645
+ super({ ...defaults$k, ...options });
4583
4646
  }
4584
4647
  static schema() {
4585
4648
  return {
@@ -4742,12 +4805,12 @@ class NoStyleTag$1 extends Rule {
4742
4805
  }
4743
4806
  }
4744
4807
 
4745
- const defaults$i = {
4808
+ const defaults$j = {
4746
4809
  style: "uppercase",
4747
4810
  };
4748
4811
  class DoctypeStyle extends Rule {
4749
4812
  constructor(options) {
4750
- super({ ...defaults$i, ...options });
4813
+ super({ ...defaults$j, ...options });
4751
4814
  }
4752
4815
  static schema() {
4753
4816
  return {
@@ -4779,12 +4842,12 @@ class DoctypeStyle extends Rule {
4779
4842
  }
4780
4843
  }
4781
4844
 
4782
- const defaults$h = {
4845
+ const defaults$i = {
4783
4846
  style: "lowercase",
4784
4847
  };
4785
4848
  class ElementCase extends Rule {
4786
4849
  constructor(options) {
4787
- super({ ...defaults$h, ...options });
4850
+ super({ ...defaults$i, ...options });
4788
4851
  this.style = new CaseStyle(this.options.style, "element-case");
4789
4852
  }
4790
4853
  static schema() {
@@ -4850,14 +4913,14 @@ class ElementCase extends Rule {
4850
4913
  }
4851
4914
  }
4852
4915
 
4853
- const defaults$g = {
4916
+ const defaults$h = {
4854
4917
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
4855
4918
  whitelist: [],
4856
4919
  blacklist: [],
4857
4920
  };
4858
4921
  class ElementName extends Rule {
4859
4922
  constructor(options) {
4860
- super({ ...defaults$g, ...options });
4923
+ super({ ...defaults$h, ...options });
4861
4924
  // eslint-disable-next-line security/detect-non-literal-regexp
4862
4925
  this.pattern = new RegExp(this.options.pattern);
4863
4926
  }
@@ -4898,7 +4961,7 @@ class ElementName extends Rule {
4898
4961
  ...context.blacklist.map((cur) => `- ${cur}`),
4899
4962
  ];
4900
4963
  }
4901
- if (context.pattern !== defaults$g.pattern) {
4964
+ if (context.pattern !== defaults$h.pattern) {
4902
4965
  return [
4903
4966
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
4904
4967
  "",
@@ -5300,7 +5363,7 @@ class EmptyTitle extends Rule {
5300
5363
  }
5301
5364
  }
5302
5365
 
5303
- const defaults$f = {
5366
+ const defaults$g = {
5304
5367
  allowMultipleH1: false,
5305
5368
  minInitialRank: "h1",
5306
5369
  sectioningRoots: ["dialog", '[role="dialog"]'],
@@ -5331,7 +5394,7 @@ function parseMaxInitial(value) {
5331
5394
  }
5332
5395
  class HeadingLevel extends Rule {
5333
5396
  constructor(options) {
5334
- super({ ...defaults$f, ...options });
5397
+ super({ ...defaults$g, ...options });
5335
5398
  this.stack = [];
5336
5399
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
5337
5400
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
@@ -5489,12 +5552,12 @@ class HeadingLevel extends Rule {
5489
5552
  }
5490
5553
  }
5491
5554
 
5492
- const defaults$e = {
5555
+ const defaults$f = {
5493
5556
  pattern: "kebabcase",
5494
5557
  };
5495
5558
  class IdPattern extends Rule {
5496
5559
  constructor(options) {
5497
- super({ ...defaults$e, ...options });
5560
+ super({ ...defaults$f, ...options });
5498
5561
  this.pattern = parsePattern(this.options.pattern);
5499
5562
  }
5500
5563
  static schema() {
@@ -5845,12 +5908,12 @@ function findLabelByParent(el) {
5845
5908
  return [];
5846
5909
  }
5847
5910
 
5848
- const defaults$d = {
5911
+ const defaults$e = {
5849
5912
  maxlength: 70,
5850
5913
  };
5851
5914
  class LongTitle extends Rule {
5852
5915
  constructor(options) {
5853
- super({ ...defaults$d, ...options });
5916
+ super({ ...defaults$e, ...options });
5854
5917
  this.maxlength = this.options.maxlength;
5855
5918
  }
5856
5919
  static schema() {
@@ -5997,13 +6060,13 @@ class MultipleLabeledControls extends Rule {
5997
6060
  }
5998
6061
  }
5999
6062
 
6000
- const defaults$c = {
6063
+ const defaults$d = {
6001
6064
  include: null,
6002
6065
  exclude: null,
6003
6066
  };
6004
6067
  class NoAutoplay extends Rule {
6005
6068
  constructor(options) {
6006
- super({ ...defaults$c, ...options });
6069
+ super({ ...defaults$d, ...options });
6007
6070
  }
6008
6071
  documentation(context) {
6009
6072
  const tagName = context ? ` on <${context.tagName}>` : "";
@@ -6244,24 +6307,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
6244
6307
  }
6245
6308
  }
6246
6309
 
6247
- const defaults$b = {
6310
+ const defaults$c = {
6248
6311
  include: null,
6249
6312
  exclude: null,
6250
6313
  allowedProperties: ["display"],
6251
6314
  };
6252
- function getCSSDeclarations(value) {
6253
- return value
6254
- .trim()
6255
- .split(";")
6256
- .filter(Boolean)
6257
- .map((it) => {
6258
- const [property, value] = it.split(":", 2);
6259
- return { property: property.trim(), value: value ? value.trim() : undefined };
6260
- });
6261
- }
6262
6315
  class NoInlineStyle extends Rule {
6263
6316
  constructor(options) {
6264
- super({ ...defaults$b, ...options });
6317
+ super({ ...defaults$c, ...options });
6265
6318
  }
6266
6319
  static schema() {
6267
6320
  return {
@@ -6339,18 +6392,15 @@ class NoInlineStyle extends Rule {
6339
6392
  return true;
6340
6393
  }
6341
6394
  allPropertiesAllowed(value) {
6342
- if (typeof value !== "string") {
6343
- return false;
6344
- }
6345
6395
  const allowProperties = this.options.allowedProperties;
6346
6396
  /* quick path: no properties are allowed, no need to check each one individually */
6347
6397
  if (allowProperties.length === 0) {
6348
6398
  return false;
6349
6399
  }
6350
- const declarations = getCSSDeclarations(value);
6400
+ const declarations = Object.keys(parseCssDeclaration(value));
6351
6401
  return (declarations.length > 0 &&
6352
6402
  declarations.every((it) => {
6353
- return allowProperties.includes(it.property);
6403
+ return allowProperties.includes(it);
6354
6404
  }));
6355
6405
  }
6356
6406
  }
@@ -6466,7 +6516,7 @@ class NoMultipleMain extends Rule {
6466
6516
  }
6467
6517
  }
6468
6518
 
6469
- const defaults$a = {
6519
+ const defaults$b = {
6470
6520
  relaxed: false,
6471
6521
  };
6472
6522
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -6483,7 +6533,7 @@ const replacementTable = {
6483
6533
  };
6484
6534
  class NoRawCharacters extends Rule {
6485
6535
  constructor(options) {
6486
- super({ ...defaults$a, ...options });
6536
+ super({ ...defaults$b, ...options });
6487
6537
  this.relaxed = this.options.relaxed;
6488
6538
  }
6489
6539
  static schema() {
@@ -6661,13 +6711,13 @@ class NoRedundantRole extends Rule {
6661
6711
  }
6662
6712
 
6663
6713
  const xmlns = /^(.+):.+$/;
6664
- const defaults$9 = {
6714
+ const defaults$a = {
6665
6715
  ignoreForeign: true,
6666
6716
  ignoreXML: true,
6667
6717
  };
6668
6718
  class NoSelfClosing extends Rule {
6669
6719
  constructor(options) {
6670
- super({ ...defaults$9, ...options });
6720
+ super({ ...defaults$a, ...options });
6671
6721
  }
6672
6722
  static schema() {
6673
6723
  return {
@@ -6783,7 +6833,7 @@ class NoUtf8Bom extends Rule {
6783
6833
  }
6784
6834
  setup() {
6785
6835
  const unregister = this.on("token", (event) => {
6786
- if (event.type === exports.TokenType.UNICODE_BOM) {
6836
+ if (event.type === TokenType.UNICODE_BOM) {
6787
6837
  this.report(null, "File should be saved without UTF-8 BOM", event.location);
6788
6838
  }
6789
6839
  /* since the BOM must be the very first thing the rule can now be disabled for the rest of the run */
@@ -6800,13 +6850,13 @@ const replacement = {
6800
6850
  reset: '<button type="reset">',
6801
6851
  image: '<button type="button">',
6802
6852
  };
6803
- const defaults$8 = {
6853
+ const defaults$9 = {
6804
6854
  include: null,
6805
6855
  exclude: null,
6806
6856
  };
6807
6857
  class PreferButton extends Rule {
6808
6858
  constructor(options) {
6809
- super({ ...defaults$8, ...options });
6859
+ super({ ...defaults$9, ...options });
6810
6860
  }
6811
6861
  static schema() {
6812
6862
  return {
@@ -6881,7 +6931,7 @@ class PreferButton extends Rule {
6881
6931
  }
6882
6932
  }
6883
6933
 
6884
- const defaults$7 = {
6934
+ const defaults$8 = {
6885
6935
  mapping: {
6886
6936
  article: "article",
6887
6937
  banner: "header",
@@ -6911,7 +6961,7 @@ const defaults$7 = {
6911
6961
  };
6912
6962
  class PreferNativeElement extends Rule {
6913
6963
  constructor(options) {
6914
- super({ ...defaults$7, ...options });
6964
+ super({ ...defaults$8, ...options });
6915
6965
  }
6916
6966
  static schema() {
6917
6967
  return {
@@ -7031,7 +7081,7 @@ class PreferTbody extends Rule {
7031
7081
  }
7032
7082
  }
7033
7083
 
7034
- const defaults$6 = {
7084
+ const defaults$7 = {
7035
7085
  target: "all",
7036
7086
  };
7037
7087
  const crossorigin = new RegExp("^(\\w+://|//)"); /* e.g. https:// or // */
@@ -7041,7 +7091,7 @@ const supportSri = {
7041
7091
  };
7042
7092
  class RequireSri extends Rule {
7043
7093
  constructor(options) {
7044
- super({ ...defaults$6, ...options });
7094
+ super({ ...defaults$7, ...options });
7045
7095
  this.target = this.options.target;
7046
7096
  }
7047
7097
  static schema() {
@@ -7169,12 +7219,13 @@ class SvgFocusable extends Rule {
7169
7219
  }
7170
7220
  }
7171
7221
 
7172
- const defaults$5 = {
7222
+ const defaults$6 = {
7173
7223
  characters: [
7174
7224
  { pattern: " ", replacement: "&nbsp;", description: "non-breaking space" },
7175
7225
  { pattern: "-", replacement: "&#8209;", description: "non-breaking hyphen" },
7176
7226
  ],
7177
7227
  ignoreClasses: [],
7228
+ ignoreStyle: true,
7178
7229
  };
7179
7230
  function constructRegex(characters) {
7180
7231
  const disallowed = characters
@@ -7211,7 +7262,7 @@ function matchAll(text, regexp) {
7211
7262
  }
7212
7263
  class TelNonBreaking extends Rule {
7213
7264
  constructor(options) {
7214
- super({ ...defaults$5, ...options });
7265
+ super({ ...defaults$6, ...options });
7215
7266
  this.regex = constructRegex(this.options.characters);
7216
7267
  }
7217
7268
  static schema() {
@@ -7240,6 +7291,9 @@ class TelNonBreaking extends Rule {
7240
7291
  type: "string",
7241
7292
  },
7242
7293
  },
7294
+ ignoreStyle: {
7295
+ type: "boolean",
7296
+ },
7243
7297
  };
7244
7298
  }
7245
7299
  documentation(context) {
@@ -7266,10 +7320,7 @@ class TelNonBreaking extends Rule {
7266
7320
  setup() {
7267
7321
  this.on("element:ready", this.isRelevant, (event) => {
7268
7322
  const { target } = event;
7269
- const { ignoreClasses } = this.options;
7270
- /* skip if element has a class in the ignore list */
7271
- const isIgnored = ignoreClasses.some((it) => target.classList.contains(it));
7272
- if (isIgnored) {
7323
+ if (this.isIgnored(target)) {
7273
7324
  return;
7274
7325
  }
7275
7326
  this.walk(target, target);
@@ -7288,6 +7339,25 @@ class TelNonBreaking extends Rule {
7288
7339
  }
7289
7340
  return true;
7290
7341
  }
7342
+ isIgnoredClass(node) {
7343
+ const { ignoreClasses } = this.options;
7344
+ const { classList } = node;
7345
+ return ignoreClasses.some((it) => classList.contains(it));
7346
+ }
7347
+ isIgnoredStyle(node) {
7348
+ const { ignoreStyle } = this.options;
7349
+ const { style } = node;
7350
+ if (!ignoreStyle) {
7351
+ return false;
7352
+ }
7353
+ if (style["white-space"] === "nowrap" || style["white-space"] === "pre") {
7354
+ return true;
7355
+ }
7356
+ return false;
7357
+ }
7358
+ isIgnored(node) {
7359
+ return this.isIgnoredClass(node) || this.isIgnoredStyle(node);
7360
+ }
7291
7361
  walk(anchor, node) {
7292
7362
  for (const child of node.childNodes) {
7293
7363
  if (isTextNode(child)) {
@@ -9271,6 +9341,95 @@ class UnknownCharReference extends Rule {
9271
9341
  }
9272
9342
  }
9273
9343
 
9344
+ var RuleContext;
9345
+ (function (RuleContext) {
9346
+ RuleContext[RuleContext["EMPTY"] = 1] = "EMPTY";
9347
+ RuleContext[RuleContext["WHITESPACE"] = 2] = "WHITESPACE";
9348
+ RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
9349
+ RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
9350
+ })(RuleContext || (RuleContext = {}));
9351
+ const defaults$5 = {
9352
+ relaxed: false,
9353
+ };
9354
+ class ValidID extends Rule {
9355
+ constructor(options) {
9356
+ super({ ...defaults$5, ...options });
9357
+ }
9358
+ static schema() {
9359
+ return {
9360
+ relaxed: {
9361
+ type: "boolean",
9362
+ },
9363
+ };
9364
+ }
9365
+ documentation(context) {
9366
+ const { relaxed } = this.options;
9367
+ const message = context
9368
+ ? this.messages[context].replace("id", "ID").replace(/^(.)/, (m) => m.toUpperCase())
9369
+ : "Element ID is not valid";
9370
+ const relaxedDescription = relaxed
9371
+ ? []
9372
+ : [
9373
+ " - ID must begin with a letter",
9374
+ " - ID must only contain alphanumerical characters, `-` and `_`",
9375
+ ];
9376
+ return {
9377
+ description: [
9378
+ `${message}.`,
9379
+ "",
9380
+ "Under the current configuration the following rules are applied:",
9381
+ "",
9382
+ " - ID must not be empty",
9383
+ " - ID must not contain any whitespace characters",
9384
+ ...relaxedDescription,
9385
+ ].join("\n"),
9386
+ url: ruleDocumentationUrl("@/rules/valid-id.ts"),
9387
+ };
9388
+ }
9389
+ setup() {
9390
+ this.on("attr", this.isRelevant, (event) => {
9391
+ const { value } = event;
9392
+ if (value === null || value instanceof DynamicValue) {
9393
+ return;
9394
+ }
9395
+ if (value === "") {
9396
+ const context = RuleContext.EMPTY;
9397
+ this.report(event.target, this.messages[context], event.location, context);
9398
+ return;
9399
+ }
9400
+ if (value.match(/\s/)) {
9401
+ const context = RuleContext.WHITESPACE;
9402
+ this.report(event.target, this.messages[context], event.valueLocation, context);
9403
+ return;
9404
+ }
9405
+ const { relaxed } = this.options;
9406
+ if (relaxed) {
9407
+ return;
9408
+ }
9409
+ if (value.match(/^[^a-zA-Z]/)) {
9410
+ const context = RuleContext.LEADING_CHARACTER;
9411
+ this.report(event.target, this.messages[context], event.valueLocation, context);
9412
+ return;
9413
+ }
9414
+ if (value.match(/[^a-zA-Z0-9-_]/)) {
9415
+ const context = RuleContext.DISALLOWED_CHARACTER;
9416
+ this.report(event.target, this.messages[context], event.valueLocation, context);
9417
+ }
9418
+ });
9419
+ }
9420
+ get messages() {
9421
+ return {
9422
+ [RuleContext.EMPTY]: "element id must not be empty",
9423
+ [RuleContext.WHITESPACE]: "element id must not contain whitespace",
9424
+ [RuleContext.LEADING_CHARACTER]: "element id must begin with a letter",
9425
+ [RuleContext.DISALLOWED_CHARACTER]: "element id must only contain alphanumerical, dash and underscore characters",
9426
+ };
9427
+ }
9428
+ isRelevant(event) {
9429
+ return event.key === "id";
9430
+ }
9431
+ }
9432
+
9274
9433
  var Style$1;
9275
9434
  (function (Style) {
9276
9435
  Style[Style["Any"] = 0] = "Any";
@@ -9782,6 +9941,7 @@ const bundledRules = {
9782
9941
  "tel-non-breaking": TelNonBreaking,
9783
9942
  "text-content": TextContent,
9784
9943
  "unrecognized-char-ref": UnknownCharReference,
9944
+ "valid-id": ValidID,
9785
9945
  void: Void,
9786
9946
  "void-content": VoidContent,
9787
9947
  "void-style": VoidStyle,
@@ -9879,6 +10039,7 @@ const config$1 = {
9879
10039
  "tel-non-breaking": "error",
9880
10040
  "text-content": "error",
9881
10041
  "unrecognized-char-ref": "error",
10042
+ "valid-id": ["error", { relaxed: false }],
9882
10043
  void: "off",
9883
10044
  "void-content": "error",
9884
10045
  "void-style": "error",
@@ -9914,6 +10075,7 @@ const config = {
9914
10075
  "no-raw-characters": ["error", { relaxed: true }],
9915
10076
  "script-element": "error",
9916
10077
  "unrecognized-char-ref": "error",
10078
+ "valid-id": ["error", { relaxed: true }],
9917
10079
  "void-content": "error",
9918
10080
  },
9919
10081
  };
@@ -9983,7 +10145,7 @@ class ResolvedConfig {
9983
10145
  }
9984
10146
  catch (err) {
9985
10147
  const message = err instanceof Error ? err.message : String(err);
9986
- throw new NestedError(`When transforming "${source.filename}": ${message}`, err);
10148
+ throw new NestedError(`When transforming "${source.filename}": ${message}`, ensureError(err));
9987
10149
  }
9988
10150
  }
9989
10151
  else {
@@ -10055,7 +10217,7 @@ function loadFromFile(filename) {
10055
10217
  json = requireUncached(filename);
10056
10218
  }
10057
10219
  catch (err) {
10058
- throw new ConfigError(`Failed to read configuration from "${filename}"`, err);
10220
+ throw new ConfigError(`Failed to read configuration from "${filename}"`, ensureError(err));
10059
10221
  }
10060
10222
  /* expand any relative paths */
10061
10223
  for (const key of ["extends", "elements", "plugins"]) {
@@ -10243,7 +10405,7 @@ class Config {
10243
10405
  }
10244
10406
  let filename;
10245
10407
  /* try searching builtin metadata */
10246
- filename = path__default["default"].join(projectRoot, "elements", `${entry}.json`);
10408
+ filename = path__default["default"].join(projectRoot, "elements", `${entry}.js`);
10247
10409
  if (fs__default["default"].existsSync(filename)) {
10248
10410
  metaTable.loadFromFile(filename);
10249
10411
  continue;
@@ -10260,7 +10422,7 @@ class Config {
10260
10422
  }
10261
10423
  catch (err) {
10262
10424
  const message = err instanceof Error ? err.message : String(err);
10263
- throw new ConfigError(`Failed to load elements from "${entry}": ${message}`, err);
10425
+ throw new ConfigError(`Failed to load elements from "${entry}": ${message}`, ensureError(err));
10264
10426
  }
10265
10427
  }
10266
10428
  metaTable.init();
@@ -10337,7 +10499,7 @@ class Config {
10337
10499
  }
10338
10500
  catch (err) {
10339
10501
  const message = err instanceof Error ? err.message : String(err);
10340
- throw new ConfigError(`Failed to load plugin "${moduleName}": ${message}`, err);
10502
+ throw new ConfigError(`Failed to load plugin "${moduleName}": ${message}`, ensureError(err));
10341
10503
  }
10342
10504
  });
10343
10505
  }
@@ -10430,7 +10592,7 @@ class Config {
10430
10592
  throw new ConfigError(`Failed to load transformer "${name}": ${err.message}`, err);
10431
10593
  }
10432
10594
  else {
10433
- throw new ConfigError(`Failed to load transformer "${name}"`, err);
10595
+ throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
10434
10596
  }
10435
10597
  }
10436
10598
  });
@@ -10657,7 +10819,7 @@ class ParserError extends Error {
10657
10819
  }
10658
10820
 
10659
10821
  function isAttrValueToken(token) {
10660
- return Boolean(token && token.type === exports.TokenType.ATTR_VALUE);
10822
+ return Boolean(token && token.type === TokenType.ATTR_VALUE);
10661
10823
  }
10662
10824
  function svgShouldRetainTag(foreignTagName, tagName) {
10663
10825
  return foreignTagName === "svg" && ["title", "desc"].includes(tagName);
@@ -10765,43 +10927,43 @@ class Parser {
10765
10927
  /* eslint-disable-next-line complexity */
10766
10928
  consume(source, token, tokenStream) {
10767
10929
  switch (token.type) {
10768
- case exports.TokenType.UNICODE_BOM:
10930
+ case TokenType.UNICODE_BOM:
10769
10931
  /* ignore */
10770
10932
  break;
10771
- case exports.TokenType.TAG_OPEN:
10933
+ case TokenType.TAG_OPEN:
10772
10934
  this.consumeTag(source, token, tokenStream);
10773
10935
  break;
10774
- case exports.TokenType.WHITESPACE:
10936
+ case TokenType.WHITESPACE:
10775
10937
  this.trigger("whitespace", {
10776
10938
  text: token.data[0],
10777
10939
  location: token.location,
10778
10940
  });
10779
10941
  this.appendText(token.data[0], token.location);
10780
10942
  break;
10781
- case exports.TokenType.DIRECTIVE:
10943
+ case TokenType.DIRECTIVE:
10782
10944
  this.consumeDirective(token);
10783
10945
  break;
10784
- case exports.TokenType.CONDITIONAL:
10946
+ case TokenType.CONDITIONAL:
10785
10947
  this.consumeConditional(token);
10786
10948
  break;
10787
- case exports.TokenType.COMMENT:
10949
+ case TokenType.COMMENT:
10788
10950
  this.consumeComment(token);
10789
10951
  break;
10790
- case exports.TokenType.DOCTYPE_OPEN:
10952
+ case TokenType.DOCTYPE_OPEN:
10791
10953
  this.consumeDoctype(token, tokenStream);
10792
10954
  break;
10793
- case exports.TokenType.TEXT:
10794
- case exports.TokenType.TEMPLATING:
10955
+ case TokenType.TEXT:
10956
+ case TokenType.TEMPLATING:
10795
10957
  this.appendText(token.data[0], token.location);
10796
10958
  break;
10797
- case exports.TokenType.EOF:
10959
+ case TokenType.EOF:
10798
10960
  this.closeTree(source, token.location);
10799
10961
  break;
10800
10962
  }
10801
10963
  }
10802
10964
  /* eslint-disable-next-line complexity, sonarjs/cognitive-complexity */
10803
10965
  consumeTag(source, startToken, tokenStream) {
10804
- const tokens = Array.from(this.consumeUntil(tokenStream, exports.TokenType.TAG_CLOSE, startToken.location));
10966
+ const tokens = Array.from(this.consumeUntil(tokenStream, TokenType.TAG_CLOSE, startToken.location));
10805
10967
  const endToken = tokens.slice(-1)[0];
10806
10968
  const closeOptional = this.closeOptional(startToken);
10807
10969
  const parent = closeOptional ? this.dom.getActive().parent : this.dom.getActive();
@@ -10827,9 +10989,9 @@ class Parser {
10827
10989
  for (let i = 0; i < tokens.length; i++) {
10828
10990
  const token = tokens[i];
10829
10991
  switch (token.type) {
10830
- case exports.TokenType.WHITESPACE:
10992
+ case TokenType.WHITESPACE:
10831
10993
  break;
10832
- case exports.TokenType.ATTR_NAME:
10994
+ case TokenType.ATTR_NAME:
10833
10995
  this.consumeAttribute(source, node, token, tokens[i + 1]);
10834
10996
  break;
10835
10997
  }
@@ -10907,7 +11069,7 @@ class Parser {
10907
11069
  let endToken;
10908
11070
  do {
10909
11071
  /* search for tags */
10910
- const tokens = Array.from(this.consumeUntil(tokenStream, exports.TokenType.TAG_OPEN, errorLocation));
11072
+ const tokens = Array.from(this.consumeUntil(tokenStream, TokenType.TAG_OPEN, errorLocation));
10911
11073
  const [last] = tokens.slice(-1);
10912
11074
  const [, tagClosed, tagName] = last.data;
10913
11075
  /* special case: svg <title> and <desc> should be intact as it affects accessibility */
@@ -10924,7 +11086,7 @@ class Parser {
10924
11086
  continue;
10925
11087
  }
10926
11088
  /* locate end token and determine if this is a self-closed tag */
10927
- const endTokens = Array.from(this.consumeUntil(tokenStream, exports.TokenType.TAG_CLOSE, last.location));
11089
+ const endTokens = Array.from(this.consumeUntil(tokenStream, TokenType.TAG_CLOSE, last.location));
10928
11090
  endToken = endTokens.slice(-1)[0];
10929
11091
  const selfClosed = endToken.data[0] === "/>";
10930
11092
  /* since foreign element may be nested keep a count for the number of
@@ -11010,7 +11172,7 @@ class Parser {
11010
11172
  * ^^^ ^^^ ^^^ (null) (null)
11011
11173
  */
11012
11174
  getAttributeValueLocation(token) {
11013
- if (!token || token.type !== exports.TokenType.ATTR_VALUE || token.data[2] === "") {
11175
+ if (!token || token.type !== TokenType.ATTR_VALUE || token.data[2] === "") {
11014
11176
  return null;
11015
11177
  }
11016
11178
  const quote = token.data[3];
@@ -11028,7 +11190,7 @@ class Parser {
11028
11190
  getAttributeLocation(key, value) {
11029
11191
  var _a;
11030
11192
  const begin = key.location;
11031
- const end = value && value.type === exports.TokenType.ATTR_VALUE ? value.location : undefined;
11193
+ const end = value && value.type === TokenType.ATTR_VALUE ? value.location : undefined;
11032
11194
  return {
11033
11195
  filename: begin.filename,
11034
11196
  line: begin.line,
@@ -11089,7 +11251,7 @@ class Parser {
11089
11251
  * Consumes doctype tokens. Emits doctype event.
11090
11252
  */
11091
11253
  consumeDoctype(startToken, tokenStream) {
11092
- const tokens = Array.from(this.consumeUntil(tokenStream, exports.TokenType.DOCTYPE_CLOSE, startToken.location));
11254
+ const tokens = Array.from(this.consumeUntil(tokenStream, TokenType.DOCTYPE_CLOSE, startToken.location));
11093
11255
  /* first token is the doctype, second is the closing ">" */
11094
11256
  const doctype = tokens[0];
11095
11257
  const value = doctype.data[0];
@@ -11115,7 +11277,7 @@ class Parser {
11115
11277
  return;
11116
11278
  it = this.next(tokenStream);
11117
11279
  }
11118
- throw new ParserError(errorLocation, `stream ended before ${exports.TokenType[search]} token was found`);
11280
+ throw new ParserError(errorLocation, `stream ended before ${TokenType[search]} token was found`);
11119
11281
  }
11120
11282
  /**
11121
11283
  * Consumes tokens until a matching close-tag is found. Tags are appended to
@@ -11129,7 +11291,7 @@ class Parser {
11129
11291
  while (!it.done) {
11130
11292
  const token = it.value;
11131
11293
  this.consume(source, token, tokenStream);
11132
- if (token.type === exports.TokenType.TAG_OPEN) {
11294
+ if (token.type === TokenType.TAG_OPEN) {
11133
11295
  const [, close, tagName] = token.data;
11134
11296
  if (tagName === searchTag) {
11135
11297
  if (close) {
@@ -11154,6 +11316,7 @@ class Parser {
11154
11316
  location: token.location,
11155
11317
  type: token.type,
11156
11318
  data: Array.from(token.data),
11319
+ token,
11157
11320
  });
11158
11321
  }
11159
11322
  return it;
@@ -11202,6 +11365,12 @@ class Parser {
11202
11365
  }
11203
11366
  }
11204
11367
 
11368
+ function freeze(src) {
11369
+ return {
11370
+ ...src,
11371
+ selector: src.selector(),
11372
+ };
11373
+ }
11205
11374
  /**
11206
11375
  * @internal
11207
11376
  */
@@ -11253,7 +11422,9 @@ class Reporter {
11253
11422
  line: location.line,
11254
11423
  column: location.column,
11255
11424
  size: location.size || 0,
11256
- selector: node ? node.generateSelector() : null,
11425
+ selector() {
11426
+ return node ? node.generateSelector() : null;
11427
+ },
11257
11428
  context,
11258
11429
  });
11259
11430
  }
@@ -11267,7 +11438,7 @@ class Reporter {
11267
11438
  const report = {
11268
11439
  valid: this.isValid(),
11269
11440
  results: Object.keys(this.result).map((filePath) => {
11270
- const messages = Array.from(this.result[filePath]).sort(messageSort);
11441
+ const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
11271
11442
  const source = (sources || []).find((source) => { var _a; return filePath === ((_a = source.filename) !== null && _a !== void 0 ? _a : ""); });
11272
11443
  return {
11273
11444
  filePath,
@@ -11420,7 +11591,7 @@ class Engine {
11420
11591
  for (const token of lexer.tokenize(src)) {
11421
11592
  const data = (_a = token.data[0]) !== null && _a !== void 0 ? _a : "";
11422
11593
  lines.push({
11423
- token: exports.TokenType[token.type],
11594
+ token: TokenType[token.type],
11424
11595
  data,
11425
11596
  location: `${token.location.filename}:${token.location.line}:${token.location.column}`,
11426
11597
  });
@@ -11464,8 +11635,9 @@ class Engine {
11464
11635
  getRuleDocumentation(ruleId, context // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
11465
11636
  ) {
11466
11637
  const rules = this.config.getRules();
11467
- if (rules.has(ruleId)) {
11468
- const [, options] = rules.get(ruleId);
11638
+ const ruleData = rules.get(ruleId);
11639
+ if (ruleData) {
11640
+ const [, options] = ruleData;
11469
11641
  const rule = this.instantiateRule(ruleId, options);
11470
11642
  return rule.documentation(context);
11471
11643
  }
@@ -11669,7 +11841,7 @@ class Engine {
11669
11841
  line: location.line,
11670
11842
  column: location.column,
11671
11843
  size: location.size || 0,
11672
- selector: null,
11844
+ selector: () => null,
11673
11845
  });
11674
11846
  }
11675
11847
  }
@@ -12192,6 +12364,7 @@ const formatter$4 = checkstyleFormatter;
12192
12364
  const defaults = {
12193
12365
  showLink: true,
12194
12366
  showSummary: true,
12367
+ showSelector: false,
12195
12368
  };
12196
12369
  /**
12197
12370
  * Codeframe formatter based on ESLint codeframe.
@@ -12247,6 +12420,7 @@ function getEndLocation(message, source) {
12247
12420
  * @returns The formatted output.
12248
12421
  */
12249
12422
  function formatMessage(message, parentResult, options) {
12423
+ var _a;
12250
12424
  const type = message.severity === 2 ? kleur__default["default"].red("error") : kleur__default["default"].yellow("warning");
12251
12425
  const msg = `${kleur__default["default"].bold(message.message.replace(/([^ ])\.$/, "$1"))}`;
12252
12426
  const ruleId = kleur__default["default"].dim(`(${message.ruleId})`);
@@ -12269,6 +12443,9 @@ function formatMessage(message, parentResult, options) {
12269
12443
  end: getEndLocation(message, sourceCode),
12270
12444
  }, { highlightCode: false }));
12271
12445
  }
12446
+ if (options.showSelector) {
12447
+ result.push(`${kleur__default["default"].bold("Selector:")} ${(_a = message.selector) !== null && _a !== void 0 ? _a : "-"}`);
12448
+ }
12272
12449
  if (options.showLink && message.ruleUrl) {
12273
12450
  result.push(`${kleur__default["default"].bold("Details:")} ${message.ruleUrl}`);
12274
12451
  }
@@ -12401,6 +12578,7 @@ exports.HtmlElement = HtmlElement;
12401
12578
  exports.HtmlValidate = HtmlValidate;
12402
12579
  exports.MetaCopyableProperty = MetaCopyableProperty;
12403
12580
  exports.MetaTable = MetaTable;
12581
+ exports.NestedError = NestedError;
12404
12582
  exports.Parser = Parser;
12405
12583
  exports.Reporter = Reporter;
12406
12584
  exports.Rule = Rule;
@@ -12409,8 +12587,11 @@ exports.StaticConfigLoader = StaticConfigLoader;
12409
12587
  exports.TemplateExtractor = TemplateExtractor;
12410
12588
  exports.TextNode = TextNode;
12411
12589
  exports.UserError = UserError;
12590
+ exports.WrappedError = WrappedError;
12412
12591
  exports.bugs = bugs;
12592
+ exports.codeframe = codeframe;
12413
12593
  exports.compatibilityCheck = compatibilityCheck;
12594
+ exports.ensureError = ensureError;
12414
12595
  exports.getFormatter = getFormatter;
12415
12596
  exports.legacyRequire = legacyRequire;
12416
12597
  exports.name = name;