html-validate 8.25.1 → 8.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/core.js CHANGED
@@ -4,7 +4,7 @@ var Ajv = require('ajv');
4
4
  var elements = require('./elements.js');
5
5
  var betterAjvErrors = require('@sidvind/better-ajv-errors');
6
6
  var utils_naturalJoin = require('./utils/natural-join.js');
7
- var fs = require('fs');
7
+ var fs = require('node:fs');
8
8
  var kleur = require('kleur');
9
9
  var stylish$1 = require('@html-validate/stylish');
10
10
  var semver = require('semver');
@@ -5059,6 +5059,27 @@ class CloseAttr extends Rule {
5059
5059
  }
5060
5060
  }
5061
5061
 
5062
+ function* ancestors(node) {
5063
+ if (!node) {
5064
+ return;
5065
+ }
5066
+ let ancestor = node;
5067
+ while (ancestor && !ancestor.isRootElement()) {
5068
+ yield ancestor;
5069
+ ancestor = ancestor.parent;
5070
+ }
5071
+ if (ancestor) {
5072
+ yield ancestor;
5073
+ }
5074
+ }
5075
+ function findAncestor(node, predicate) {
5076
+ for (const ancestor of ancestors(node)) {
5077
+ if (predicate(ancestor)) {
5078
+ return ancestor;
5079
+ }
5080
+ }
5081
+ return null;
5082
+ }
5062
5083
  class CloseOrder extends Rule {
5063
5084
  documentation() {
5064
5085
  return {
@@ -5067,15 +5088,28 @@ class CloseOrder extends Rule {
5067
5088
  };
5068
5089
  }
5069
5090
  setup() {
5091
+ let reported;
5092
+ this.on("parse:begin", () => {
5093
+ reported = /* @__PURE__ */ new Set();
5094
+ });
5095
+ this.on("tag:end", (event) => {
5096
+ const current = event.target;
5097
+ const active = event.previous;
5098
+ if (current) {
5099
+ return;
5100
+ }
5101
+ for (const ancestor of ancestors(active)) {
5102
+ if (ancestor.isRootElement() || reported.has(ancestor.unique)) {
5103
+ continue;
5104
+ }
5105
+ this.report(ancestor, `Unclosed element '<${ancestor.tagName}>'`, ancestor.location);
5106
+ reported.add(ancestor.unique);
5107
+ }
5108
+ });
5070
5109
  this.on("tag:end", (event) => {
5071
5110
  const current = event.target;
5072
5111
  const active = event.previous;
5073
5112
  if (!current) {
5074
- this.report(
5075
- null,
5076
- `Missing close-tag, expected '</${active.tagName}>' but document ended before it was found.`,
5077
- event.location
5078
- );
5079
5113
  return;
5080
5114
  }
5081
5115
  if (current.voidElement) {
@@ -5092,15 +5126,32 @@ class CloseOrder extends Rule {
5092
5126
  offset: current.location.offset,
5093
5127
  size: current.tagName.length + 1
5094
5128
  };
5095
- this.report(null, "Unexpected close-tag, expected opening tag.", location);
5129
+ this.report(null, `Stray end tag '</${current.tagName}>'`, location);
5096
5130
  return;
5097
5131
  }
5098
- if (current.tagName !== active.tagName) {
5132
+ if (current.tagName === active.tagName) {
5133
+ return;
5134
+ }
5135
+ const ancestor = findAncestor(active.parent, (node) => node.is(current.tagName));
5136
+ if (ancestor && !ancestor.isRootElement()) {
5137
+ for (const element of ancestors(active)) {
5138
+ if (ancestor.isSameNode(element)) {
5139
+ break;
5140
+ }
5141
+ if (reported.has(element.unique)) {
5142
+ continue;
5143
+ }
5144
+ this.report(element, `Unclosed element '<${element.tagName}>'`, element.location);
5145
+ reported.add(element.unique);
5146
+ }
5099
5147
  this.report(
5100
5148
  null,
5101
- `Mismatched close-tag, expected '</${active.tagName}>' but found '</${current.tagName}>'.`,
5149
+ `End tag '</${current.tagName}>' seen but there were open elements`,
5102
5150
  current.location
5103
5151
  );
5152
+ reported.add(ancestor.unique);
5153
+ } else {
5154
+ this.report(null, `Stray end tag '</${current.tagName}>'`, current.location);
5104
5155
  }
5105
5156
  });
5106
5157
  }
@@ -10521,10 +10572,6 @@ var configurationSchema = {
10521
10572
  properties: properties
10522
10573
  };
10523
10574
 
10524
- const TRANSFORMER_API = {
10525
- VERSION: 1
10526
- };
10527
-
10528
10575
  var defaultConfig = {};
10529
10576
 
10530
10577
  const config$5 = {
@@ -10731,6 +10778,99 @@ const presets = {
10731
10778
  "html-validate:a17y": config$5
10732
10779
  };
10733
10780
 
10781
+ function getNamedTransformerFromPlugin(name, plugins, pluginName, key) {
10782
+ const plugin = plugins.find((cur) => cur.name === pluginName);
10783
+ if (!plugin) {
10784
+ throw new ConfigError(`No plugin named "${pluginName}" has been loaded`);
10785
+ }
10786
+ if (!plugin.transformer) {
10787
+ throw new ConfigError(`Plugin does not expose any transformers`);
10788
+ }
10789
+ if (typeof plugin.transformer === "function") {
10790
+ throw new ConfigError(
10791
+ `Transformer "${name}" refers to named transformer but plugin exposes only unnamed, use "${pluginName}" instead.`
10792
+ );
10793
+ }
10794
+ const transformer = plugin.transformer[key];
10795
+ if (!transformer) {
10796
+ throw new ConfigError(`Plugin "${pluginName}" does not expose a transformer named "${key}".`);
10797
+ }
10798
+ return transformer;
10799
+ }
10800
+
10801
+ function getTransformerFromModule(resolvers, name) {
10802
+ return resolveTransformer(resolvers, name, { cache: true });
10803
+ }
10804
+
10805
+ function getUnnamedTransformerFromPlugin(name, plugin) {
10806
+ if (!plugin.transformer) {
10807
+ throw new ConfigError(`Plugin does not expose any transformers`);
10808
+ }
10809
+ if (typeof plugin.transformer !== "function") {
10810
+ if (plugin.transformer.default) {
10811
+ return plugin.transformer.default;
10812
+ }
10813
+ throw new ConfigError(
10814
+ `Transformer "${name}" refers to unnamed transformer but plugin exposes only named.`
10815
+ );
10816
+ }
10817
+ return plugin.transformer;
10818
+ }
10819
+
10820
+ const TRANSFORMER_API = {
10821
+ VERSION: 1
10822
+ };
10823
+
10824
+ function validateTransformer(transformer) {
10825
+ const version = transformer.api ?? 0;
10826
+ if (version !== TRANSFORMER_API.VERSION) {
10827
+ throw new ConfigError(
10828
+ `Transformer uses API version ${String(version)} but only version ${String(TRANSFORMER_API.VERSION)} is supported`
10829
+ );
10830
+ }
10831
+ }
10832
+ function loadTransformerFunction(resolvers, name, plugins) {
10833
+ const match = name.match(/(.*):(.*)/);
10834
+ if (match) {
10835
+ const [, pluginName, key] = match;
10836
+ const transformer2 = getNamedTransformerFromPlugin(name, plugins, pluginName, key);
10837
+ validateTransformer(transformer2);
10838
+ return transformer2;
10839
+ }
10840
+ const plugin = plugins.find((cur) => cur.name === name);
10841
+ if (plugin) {
10842
+ const transformer2 = getUnnamedTransformerFromPlugin(name, plugin);
10843
+ validateTransformer(transformer2);
10844
+ return transformer2;
10845
+ }
10846
+ const transformer = getTransformerFromModule(resolvers, name);
10847
+ validateTransformer(transformer);
10848
+ return transformer;
10849
+ }
10850
+ function getTransformerFunction(resolvers, name, plugins) {
10851
+ try {
10852
+ const transformer = loadTransformerFunction(resolvers, name, plugins);
10853
+ validateTransformer(transformer);
10854
+ return transformer;
10855
+ } catch (err) {
10856
+ if (err instanceof ConfigError) {
10857
+ throw new ConfigError(`Failed to load transformer "${name}": ${err.message}`, err);
10858
+ } else {
10859
+ throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
10860
+ }
10861
+ }
10862
+ }
10863
+ function getCachedTransformerFunction(cache, resolvers, name, plugins) {
10864
+ const cached = cache.get(name);
10865
+ if (cached) {
10866
+ return cached;
10867
+ } else {
10868
+ const transformer = getTransformerFunction(resolvers, name, plugins);
10869
+ cache.set(name, transformer);
10870
+ return transformer;
10871
+ }
10872
+ }
10873
+
10734
10874
  class ResolvedConfig {
10735
10875
  /**
10736
10876
  * @internal
@@ -10740,6 +10880,7 @@ class ResolvedConfig {
10740
10880
  this.plugins = plugins;
10741
10881
  this.rules = rules;
10742
10882
  this.transformers = transformers;
10883
+ this.cache = /* @__PURE__ */ new Map();
10743
10884
  this.original = original;
10744
10885
  }
10745
10886
  /**
@@ -10763,48 +10904,48 @@ class ResolvedConfig {
10763
10904
  *
10764
10905
  * When transforming zero or more new sources will be generated.
10765
10906
  *
10907
+ * @internal
10766
10908
  * @param source - Current source to transform.
10767
10909
  * @param filename - If set it is the filename used to match
10768
10910
  * transformer. Default is to use filename from source.
10769
10911
  * @returns A list of transformed sources ready for validation.
10770
10912
  */
10771
- transformSource(source, filename) {
10913
+ transformSource(resolvers, source, filename) {
10772
10914
  const transformer = this.findTransformer(filename ?? source.filename);
10773
10915
  const context = {
10774
10916
  hasChain: (filename2) => {
10775
10917
  return !!this.findTransformer(filename2);
10776
10918
  },
10777
10919
  chain: (source2, filename2) => {
10778
- return this.transformSource(source2, filename2);
10920
+ return this.transformSource(resolvers, source2, filename2);
10779
10921
  }
10780
10922
  };
10781
- if (transformer) {
10782
- try {
10783
- return Array.from(transformer.fn.call(context, source), (cur) => {
10784
- cur.transformedBy ??= [];
10785
- cur.transformedBy.push(transformer.name);
10786
- return cur;
10787
- });
10788
- } catch (err) {
10789
- const message = err instanceof Error ? err.message : String(err);
10790
- throw new NestedError(
10791
- `When transforming "${source.filename}": ${message}`,
10792
- ensureError(err)
10793
- );
10794
- }
10795
- } else {
10923
+ if (!transformer) {
10796
10924
  return [source];
10797
10925
  }
10926
+ const fn = getCachedTransformerFunction(this.cache, resolvers, transformer.name, this.plugins);
10927
+ try {
10928
+ const transformedSources = Array.from(fn.call(context, source));
10929
+ for (const source2 of transformedSources) {
10930
+ source2.transformedBy ??= [];
10931
+ source2.transformedBy.push(transformer.name);
10932
+ }
10933
+ return transformedSources;
10934
+ } catch (err) {
10935
+ const message = err instanceof Error ? err.message : String(err);
10936
+ throw new NestedError(`When transforming "${source.filename}": ${message}`, ensureError(err));
10937
+ }
10798
10938
  }
10799
10939
  /**
10800
10940
  * Wrapper around [[transformSource]] which reads a file before passing it
10801
10941
  * as-is to transformSource.
10802
10942
  *
10943
+ * @internal
10803
10944
  * @param filename - Filename to transform (according to configured
10804
10945
  * transformations)
10805
10946
  * @returns A list of transformed sources ready for validation.
10806
10947
  */
10807
- transformFilename(filename) {
10948
+ transformFilename(resolvers, filename) {
10808
10949
  const stdin = 0;
10809
10950
  const src = filename !== "/dev/stdin" ? filename : stdin;
10810
10951
  const data = fs__default.default.readFileSync(src, { encoding: "utf8" });
@@ -10816,10 +10957,12 @@ class ResolvedConfig {
10816
10957
  offset: 0,
10817
10958
  originalData: data
10818
10959
  };
10819
- return this.transformSource(source);
10960
+ return this.transformSource(resolvers, source);
10820
10961
  }
10821
10962
  /**
10822
10963
  * Returns true if a transformer matches given filename.
10964
+ *
10965
+ * @public
10823
10966
  */
10824
10967
  canTransform(filename) {
10825
10968
  const entry = this.findTransformer(filename);
@@ -10938,6 +11081,12 @@ function toArray(value) {
10938
11081
  return [value];
10939
11082
  }
10940
11083
  }
11084
+ function transformerEntries(transform) {
11085
+ return Object.entries(transform).map(([pattern, name]) => {
11086
+ const regex = new RegExp(pattern);
11087
+ return { pattern: regex, name };
11088
+ });
11089
+ }
10941
11090
  class Config {
10942
11091
  /**
10943
11092
  * @internal
@@ -10952,10 +11101,10 @@ class Config {
10952
11101
  };
10953
11102
  this.config = mergeInternal(initial, options);
10954
11103
  this.configurations = /* @__PURE__ */ new Map();
10955
- this.initialized = false;
10956
11104
  this.resolvers = toArray(resolvers);
10957
11105
  this.metaTable = null;
10958
11106
  this.plugins = [];
11107
+ this.transformers = transformerEntries(this.config.transform ?? {});
10959
11108
  }
10960
11109
  /**
10961
11110
  * Create a new blank configuration. See also `Config.defaultConfig()`.
@@ -11038,19 +11187,10 @@ class Config {
11038
11187
  return instance;
11039
11188
  }
11040
11189
  /**
11041
- * Initialize plugins, transforms etc.
11042
- *
11043
- * Must be called before trying to use config. Can safely be called multiple
11044
- * times.
11045
- *
11046
11190
  * @public
11191
+ * @deprecated Not needed any longer, this is a dummy noop method.
11047
11192
  */
11048
11193
  init() {
11049
- if (this.initialized) {
11050
- return;
11051
- }
11052
- this.transformers = this.precompileTransformers(this.config.transform ?? {});
11053
- this.initialized = true;
11054
11194
  }
11055
11195
  /**
11056
11196
  * Returns true if this configuration is marked as "root".
@@ -11163,6 +11303,14 @@ class Config {
11163
11303
  getPlugins() {
11164
11304
  return this.plugins;
11165
11305
  }
11306
+ /**
11307
+ * Get all configured transformers.
11308
+ *
11309
+ * @internal
11310
+ */
11311
+ getTransformers() {
11312
+ return this.transformers;
11313
+ }
11166
11314
  loadPlugins(plugins) {
11167
11315
  return plugins.map((moduleName, index) => {
11168
11316
  if (typeof moduleName !== "string") {
@@ -11246,99 +11394,6 @@ class Config {
11246
11394
  transformers: this.transformers
11247
11395
  };
11248
11396
  }
11249
- precompileTransformers(transform) {
11250
- return Object.entries(transform).map(([pattern, name]) => {
11251
- try {
11252
- const fn = this.getTransformFunction(name);
11253
- const version = fn.api ?? 0;
11254
- if (version !== TRANSFORMER_API.VERSION) {
11255
- throw new ConfigError(
11256
- `Transformer uses API version ${String(version)} but only version ${String(TRANSFORMER_API.VERSION)} is supported`
11257
- );
11258
- }
11259
- return {
11260
- // eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp
11261
- pattern: new RegExp(pattern),
11262
- name,
11263
- fn
11264
- };
11265
- } catch (err) {
11266
- if (err instanceof ConfigError) {
11267
- throw new ConfigError(`Failed to load transformer "${name}": ${err.message}`, err);
11268
- } else {
11269
- throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
11270
- }
11271
- }
11272
- });
11273
- }
11274
- /**
11275
- * Get transformation function requested by configuration.
11276
- *
11277
- * Searches:
11278
- *
11279
- * - Named transformers from plugins.
11280
- * - Unnamed transformer from plugin.
11281
- * - Standalone modules (local or node_modules)
11282
- *
11283
- * @param name - Key from configuration
11284
- */
11285
- getTransformFunction(name) {
11286
- const match = name.match(/(.*):(.*)/);
11287
- if (match) {
11288
- const [, pluginName, key] = match;
11289
- return this.getNamedTransformerFromPlugin(name, pluginName, key);
11290
- }
11291
- const plugin = this.plugins.find((cur) => cur.name === name);
11292
- if (plugin) {
11293
- return this.getUnnamedTransformerFromPlugin(name, plugin);
11294
- }
11295
- return this.getTransformerFromModule(name);
11296
- }
11297
- /**
11298
- * @param name - Original name from configuration
11299
- * @param pluginName - Name of plugin
11300
- * @param key - Name of transform (from plugin)
11301
- */
11302
- getNamedTransformerFromPlugin(name, pluginName, key) {
11303
- const plugin = this.plugins.find((cur) => cur.name === pluginName);
11304
- if (!plugin) {
11305
- throw new ConfigError(`No plugin named "${pluginName}" has been loaded`);
11306
- }
11307
- if (!plugin.transformer) {
11308
- throw new ConfigError(`Plugin does not expose any transformer`);
11309
- }
11310
- if (typeof plugin.transformer === "function") {
11311
- throw new ConfigError(
11312
- `Transformer "${name}" refers to named transformer but plugin exposes only unnamed, use "${pluginName}" instead.`
11313
- );
11314
- }
11315
- const transformer = plugin.transformer[key];
11316
- if (!transformer) {
11317
- throw new ConfigError(`Plugin "${pluginName}" does not expose a transformer named "${key}".`);
11318
- }
11319
- return transformer;
11320
- }
11321
- /**
11322
- * @param name - Original name from configuration
11323
- * @param plugin - Plugin instance
11324
- */
11325
- getUnnamedTransformerFromPlugin(name, plugin) {
11326
- if (!plugin.transformer) {
11327
- throw new ConfigError(`Plugin does not expose any transformer`);
11328
- }
11329
- if (typeof plugin.transformer !== "function") {
11330
- if (plugin.transformer.default) {
11331
- return plugin.transformer.default;
11332
- }
11333
- throw new ConfigError(
11334
- `Transformer "${name}" refers to unnamed transformer but plugin exposes only named.`
11335
- );
11336
- }
11337
- return plugin.transformer;
11338
- }
11339
- getTransformerFromModule(name) {
11340
- return resolveTransformer(this.resolvers, name, { cache: true });
11341
- }
11342
11397
  }
11343
11398
 
11344
11399
  class ConfigLoader {
@@ -11356,6 +11411,12 @@ class ConfigLoader {
11356
11411
  configData ? this.loadFromObject(configData) : this.defaultConfig()
11357
11412
  );
11358
11413
  }
11414
+ /**
11415
+ * @internal
11416
+ */
11417
+ getResolvers() {
11418
+ return this.resolvers;
11419
+ }
11359
11420
  /**
11360
11421
  * @internal For testing only
11361
11422
  */
@@ -11656,8 +11717,9 @@ class Parser {
11656
11717
  node.closed = NodeClosed.EndTag;
11657
11718
  }
11658
11719
  this.closeElement(source, node, active, endToken.location);
11720
+ const mismatched = node.tagName !== active.tagName;
11659
11721
  const voidClosed = !isStartTag && node.voidElement;
11660
- if (!voidClosed) {
11722
+ if (!voidClosed && !mismatched) {
11661
11723
  this.dom.popActive();
11662
11724
  }
11663
11725
  } else if (isForeign) {
@@ -11675,6 +11737,9 @@ class Parser {
11675
11737
  location
11676
11738
  };
11677
11739
  this.trigger("tag:end", event);
11740
+ if (node && node.tagName !== active.tagName && active.closed !== NodeClosed.ImplicitClosed) {
11741
+ return;
11742
+ }
11678
11743
  if (!active.isRootElement()) {
11679
11744
  this.trigger("element:ready", {
11680
11745
  target: active,
@@ -12535,11 +12600,9 @@ class StaticConfigLoader extends ConfigLoader {
12535
12600
  getConfigFor(_handle, configOverride) {
12536
12601
  const override = this.loadFromObject(configOverride ?? {});
12537
12602
  if (override.isRootFound()) {
12538
- override.init();
12539
12603
  return override.resolve();
12540
12604
  }
12541
12605
  const merged = this.globalConfig.merge(this.resolvers, override);
12542
- merged.init();
12543
12606
  return merged.resolve();
12544
12607
  }
12545
12608
  flushCache() {
@@ -12609,7 +12672,8 @@ class HtmlValidate {
12609
12672
  async validateSource(input, configOverride) {
12610
12673
  const source = normalizeSource(input);
12611
12674
  const config = await this.getConfigFor(source.filename, configOverride);
12612
- const transformedSource = config.transformSource(source);
12675
+ const resolvers = this.configLoader.getResolvers();
12676
+ const transformedSource = config.transformSource(resolvers, source);
12613
12677
  const engine = new Engine(config, Parser);
12614
12678
  return engine.lint(transformedSource);
12615
12679
  }
@@ -12623,7 +12687,8 @@ class HtmlValidate {
12623
12687
  validateSourceSync(input, configOverride) {
12624
12688
  const source = normalizeSource(input);
12625
12689
  const config = this.getConfigForSync(source.filename, configOverride);
12626
- const transformedSource = config.transformSource(source);
12690
+ const resolvers = this.configLoader.getResolvers();
12691
+ const transformedSource = config.transformSource(resolvers, source);
12627
12692
  const engine = new Engine(config, Parser);
12628
12693
  return engine.lint(transformedSource);
12629
12694
  }
@@ -12636,7 +12701,8 @@ class HtmlValidate {
12636
12701
  */
12637
12702
  async validateFile(filename) {
12638
12703
  const config = await this.getConfigFor(filename);
12639
- const source = config.transformFilename(filename);
12704
+ const resolvers = this.configLoader.getResolvers();
12705
+ const source = config.transformFilename(resolvers, filename);
12640
12706
  const engine = new Engine(config, Parser);
12641
12707
  return Promise.resolve(engine.lint(source));
12642
12708
  }
@@ -12649,7 +12715,8 @@ class HtmlValidate {
12649
12715
  */
12650
12716
  validateFileSync(filename) {
12651
12717
  const config = this.getConfigForSync(filename);
12652
- const source = config.transformFilename(filename);
12718
+ const resolvers = this.configLoader.getResolvers();
12719
+ const source = config.transformFilename(resolvers, filename);
12653
12720
  const engine = new Engine(config, Parser);
12654
12721
  return engine.lint(source);
12655
12722
  }
@@ -12717,7 +12784,8 @@ class HtmlValidate {
12717
12784
  */
12718
12785
  dumpTokens(filename) {
12719
12786
  const config = this.getConfigForSync(filename);
12720
- const source = config.transformFilename(filename);
12787
+ const resolvers = this.configLoader.getResolvers();
12788
+ const source = config.transformFilename(resolvers, filename);
12721
12789
  const engine = new Engine(config, Parser);
12722
12790
  return engine.dumpTokens(source);
12723
12791
  }
@@ -12732,7 +12800,8 @@ class HtmlValidate {
12732
12800
  */
12733
12801
  dumpEvents(filename) {
12734
12802
  const config = this.getConfigForSync(filename);
12735
- const source = config.transformFilename(filename);
12803
+ const resolvers = this.configLoader.getResolvers();
12804
+ const source = config.transformFilename(resolvers, filename);
12736
12805
  const engine = new Engine(config, Parser);
12737
12806
  return engine.dumpEvents(source);
12738
12807
  }
@@ -12747,7 +12816,8 @@ class HtmlValidate {
12747
12816
  */
12748
12817
  dumpTree(filename) {
12749
12818
  const config = this.getConfigForSync(filename);
12750
- const source = config.transformFilename(filename);
12819
+ const resolvers = this.configLoader.getResolvers();
12820
+ const source = config.transformFilename(resolvers, filename);
12751
12821
  const engine = new Engine(config, Parser);
12752
12822
  return engine.dumpTree(source);
12753
12823
  }
@@ -12762,7 +12832,8 @@ class HtmlValidate {
12762
12832
  */
12763
12833
  dumpSource(filename) {
12764
12834
  const config = this.getConfigForSync(filename);
12765
- const sources = config.transformFilename(filename);
12835
+ const resolvers = this.configLoader.getResolvers();
12836
+ const sources = config.transformFilename(resolvers, filename);
12766
12837
  return sources.reduce((result, source) => {
12767
12838
  const line = String(source.line);
12768
12839
  const column = String(source.column);
@@ -12957,7 +13028,7 @@ class HtmlValidate {
12957
13028
  }
12958
13029
 
12959
13030
  const name = "html-validate";
12960
- const version = "8.25.1";
13031
+ const version = "8.26.0";
12961
13032
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12962
13033
 
12963
13034
  function definePlugin(plugin) {