html-validate 8.21.0 → 9.0.0-rc.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.
@@ -8,7 +8,6 @@ require('./elements.js');
8
8
  require('@sidvind/better-ajv-errors');
9
9
  require('./utils/natural-join.js');
10
10
  require('fs');
11
- require('@babel/code-frame');
12
11
  require('kleur');
13
12
  require('@html-validate/stylish');
14
13
  require('semver');
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"browser.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/cjs/core.js CHANGED
@@ -5,7 +5,6 @@ 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
7
  var fs = require('fs');
8
- var codeFrame = require('@babel/code-frame');
9
8
  var kleur = require('kleur');
10
9
  var stylish$1 = require('@html-validate/stylish');
11
10
  var semver = require('semver');
@@ -1681,6 +1680,7 @@ class DOMNode {
1681
1680
  /**
1682
1681
  * Create a new DOMNode.
1683
1682
  *
1683
+ * @internal
1684
1684
  * @param nodeType - What node type to create.
1685
1685
  * @param nodeName - What node name to use. For `HtmlElement` this corresponds
1686
1686
  * to the tagName but other node types have specific predefined values.
@@ -2349,8 +2349,15 @@ function createAdapter(node) {
2349
2349
  };
2350
2350
  }
2351
2351
  class HtmlElement extends DOMNode {
2352
- constructor(tagName, parent, closed, meta, location) {
2353
- const nodeType = tagName ? NodeType.ELEMENT_NODE : NodeType.DOCUMENT_NODE;
2352
+ constructor(details) {
2353
+ const {
2354
+ nodeType,
2355
+ tagName,
2356
+ parent = null,
2357
+ closed = 1 /* EndTag */,
2358
+ meta = null,
2359
+ location
2360
+ } = details;
2354
2361
  super(nodeType, tagName, location);
2355
2362
  if (isInvalidTagName(tagName)) {
2356
2363
  throw new Error(`The tag name provided ("${tagName}") is not a valid name`);
@@ -2373,11 +2380,39 @@ class HtmlElement extends DOMNode {
2373
2380
  }
2374
2381
  }
2375
2382
  }
2383
+ /**
2384
+ * Manually create a new element. This is primary useful for test-cases. While
2385
+ * the API is public it is not meant for general consumption and is not
2386
+ * guaranteed to be stable across versions.
2387
+ *
2388
+ * Use at your own risk. Prefer to use [[Parser]] to parse a string of markup
2389
+ * instead.
2390
+ *
2391
+ * @public
2392
+ * @since 8.22.0
2393
+ * @param tagName - Element tagname.
2394
+ * @param location - Element location.
2395
+ * @param details - Additional element details.
2396
+ */
2397
+ static createElement(tagName, location, details = {}) {
2398
+ const { closed = 1 /* EndTag */, meta = null, parent = null } = details;
2399
+ return new HtmlElement({
2400
+ nodeType: NodeType.ELEMENT_NODE,
2401
+ tagName,
2402
+ parent,
2403
+ closed,
2404
+ meta,
2405
+ location
2406
+ });
2407
+ }
2376
2408
  /**
2377
2409
  * @internal
2378
2410
  */
2379
2411
  static rootNode(location) {
2380
- const root = new HtmlElement(void 0, null, 1 /* EndTag */, null, location);
2412
+ const root = new HtmlElement({
2413
+ nodeType: NodeType.DOCUMENT_NODE,
2414
+ location
2415
+ });
2381
2416
  root.setAnnotation("#document");
2382
2417
  return root;
2383
2418
  }
@@ -2396,7 +2431,14 @@ class HtmlElement extends DOMNode {
2396
2431
  const open = startToken.data[1] !== "/";
2397
2432
  const closed = isClosed(endToken, meta);
2398
2433
  const location = sliceLocation(startToken.location, 1);
2399
- return new HtmlElement(tagName, open ? parent : null, closed, meta, location);
2434
+ return new HtmlElement({
2435
+ nodeType: NodeType.ELEMENT_NODE,
2436
+ tagName,
2437
+ parent: open ? parent : null,
2438
+ closed,
2439
+ meta,
2440
+ location
2441
+ });
2400
2442
  }
2401
2443
  /**
2402
2444
  * Returns annotated name if set or defaults to `<tagName>`.
@@ -2826,6 +2868,35 @@ function isClosed(endToken, meta) {
2826
2868
  return closed;
2827
2869
  }
2828
2870
 
2871
+ function dumpTree(root) {
2872
+ const lines = [];
2873
+ function decoration(node) {
2874
+ let output = "";
2875
+ if (node.id) {
2876
+ output += `#${node.id}`;
2877
+ }
2878
+ if (node.hasAttribute("class")) {
2879
+ output += `.${node.classList.join(".")}`;
2880
+ }
2881
+ return output;
2882
+ }
2883
+ function writeNode(node, level, sibling) {
2884
+ if (node.parent) {
2885
+ const indent = " ".repeat(level - 1);
2886
+ const l = node.childElements.length > 0 ? "\u252C" : "\u2500";
2887
+ const b = sibling < node.parent.childElements.length - 1 ? "\u251C" : "\u2514";
2888
+ lines.push(`${indent}${b}\u2500${l} ${node.tagName}${decoration(node)}`);
2889
+ } else {
2890
+ lines.push("(root)");
2891
+ }
2892
+ node.childElements.forEach((child, index) => {
2893
+ writeNode(child, level + 1, index);
2894
+ });
2895
+ }
2896
+ writeNode(root, 0, 0);
2897
+ return lines;
2898
+ }
2899
+
2829
2900
  function escape(value) {
2830
2901
  return JSON.stringify(value);
2831
2902
  }
@@ -12096,33 +12167,8 @@ class Engine {
12096
12167
  }
12097
12168
  dumpTree(source) {
12098
12169
  const parser = this.instantiateParser();
12099
- const document = parser.parseHtml(source[0]);
12100
- const lines = [];
12101
- function decoration(node) {
12102
- let output = "";
12103
- if (node.id) {
12104
- output += `#${node.id}`;
12105
- }
12106
- if (node.hasAttribute("class")) {
12107
- output += `.${node.classList.join(".")}`;
12108
- }
12109
- return output;
12110
- }
12111
- function writeNode(node, level, sibling) {
12112
- if (node.parent) {
12113
- const indent = " ".repeat(level - 1);
12114
- const l = node.childElements.length > 0 ? "\u252C" : "\u2500";
12115
- const b = sibling < node.parent.childElements.length - 1 ? "\u251C" : "\u2514";
12116
- lines.push(`${indent}${b}\u2500${l} ${node.tagName}${decoration(node)}`);
12117
- } else {
12118
- lines.push("(root)");
12119
- }
12120
- node.childElements.forEach((child, index) => {
12121
- writeNode(child, level + 1, index);
12122
- });
12123
- }
12124
- writeNode(document, 0, 0);
12125
- return lines;
12170
+ const root = parser.parseHtml(source[0]);
12171
+ return dumpTree(root);
12126
12172
  }
12127
12173
  /**
12128
12174
  * Get rule documentation.
@@ -12759,7 +12805,11 @@ class HtmlValidate {
12759
12805
  * @param configOverride - Configuration to apply last.
12760
12806
  */
12761
12807
  getConfigForSync(filename, configOverride) {
12762
- return this.configLoader.getConfigFor(filename, configOverride);
12808
+ const config = this.configLoader.getConfigFor(filename, configOverride);
12809
+ if (isThenable(config)) {
12810
+ throw new UserError("Cannot use asynchronous config loader with synchronous api");
12811
+ }
12812
+ return config;
12763
12813
  }
12764
12814
  /**
12765
12815
  * Get current configuration loader.
@@ -12797,7 +12847,7 @@ class HtmlValidate {
12797
12847
  }
12798
12848
 
12799
12849
  const name = "html-validate";
12800
- const version = "8.21.0";
12850
+ const version = "9.0.0-rc.1";
12801
12851
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12802
12852
 
12803
12853
  function definePlugin(plugin) {
@@ -12885,17 +12935,26 @@ const REPLACERS = [
12885
12935
  [
12886
12936
  // (a\ ) -> (a )
12887
12937
  // (a ) -> (a)
12938
+ // (a ) -> (a)
12888
12939
  // (a \ ) -> (a )
12889
- /\\?\s+$/,
12890
- match => match.indexOf('\\') === 0
12891
- ? SPACE
12892
- : EMPTY
12940
+ /((?:\\\\)*?)(\\?\s+)$/,
12941
+ (_, m1, m2) => m1 + (
12942
+ m2.indexOf('\\') === 0
12943
+ ? SPACE
12944
+ : EMPTY
12945
+ )
12893
12946
  ],
12894
12947
 
12895
12948
  // replace (\ ) with ' '
12949
+ // (\ ) -> ' '
12950
+ // (\\ ) -> '\\ '
12951
+ // (\\\ ) -> '\\ '
12896
12952
  [
12897
- /\\\s/g,
12898
- () => SPACE
12953
+ /(\\+?)\s/g,
12954
+ (_, m1) => {
12955
+ const {length} = m1;
12956
+ return m1.slice(0, length - length % 2) + SPACE
12957
+ }
12899
12958
  ],
12900
12959
 
12901
12960
  // Escape metacharacters
@@ -13123,7 +13182,8 @@ const makeRegex = (pattern, ignoreCase) => {
13123
13182
 
13124
13183
  if (!source) {
13125
13184
  source = REPLACERS.reduce(
13126
- (prev, current) => prev.replace(current[0], current[1].bind(pattern)),
13185
+ (prev, [matcher, replacer]) =>
13186
+ prev.replace(matcher, replacer.bind(pattern)),
13127
13187
  pattern
13128
13188
  );
13129
13189
  regexCache[pattern] = source;
@@ -13489,6 +13549,81 @@ const defaults = {
13489
13549
  showSummary: true,
13490
13550
  showSelector: false
13491
13551
  };
13552
+ const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
13553
+ function getMarkerLines(loc, source) {
13554
+ const startLoc = {
13555
+ ...loc.start
13556
+ };
13557
+ const endLoc = {
13558
+ ...startLoc,
13559
+ ...loc.end
13560
+ };
13561
+ const linesAbove = 2;
13562
+ const linesBelow = 3;
13563
+ const startLine = startLoc.line;
13564
+ const startColumn = startLoc.column;
13565
+ const endLine = endLoc.line;
13566
+ const endColumn = endLoc.column;
13567
+ const start = Math.max(startLine - (linesAbove + 1), 0);
13568
+ const end = Math.min(source.length, endLine + linesBelow);
13569
+ const lineDiff = endLine - startLine;
13570
+ const markerLines = {};
13571
+ if (lineDiff) {
13572
+ for (let i = 0; i <= lineDiff; i++) {
13573
+ const lineNumber = i + startLine;
13574
+ if (!startColumn) {
13575
+ markerLines[lineNumber] = true;
13576
+ } else if (i === 0) {
13577
+ const sourceLength = source[lineNumber - 1].length;
13578
+ markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
13579
+ } else if (i === lineDiff) {
13580
+ markerLines[lineNumber] = [0, endColumn];
13581
+ } else {
13582
+ const sourceLength = source[lineNumber - i].length;
13583
+ markerLines[lineNumber] = [0, sourceLength];
13584
+ }
13585
+ }
13586
+ } else {
13587
+ if (startColumn === endColumn) {
13588
+ if (startColumn) {
13589
+ markerLines[startLine] = [startColumn, 0];
13590
+ } else {
13591
+ markerLines[startLine] = true;
13592
+ }
13593
+ } else {
13594
+ markerLines[startLine] = [startColumn, endColumn - startColumn];
13595
+ }
13596
+ }
13597
+ return { start, end, markerLines };
13598
+ }
13599
+ function codeFrameColumns(rawLines, loc) {
13600
+ const lines = rawLines.split(NEWLINE);
13601
+ const { start, end, markerLines } = getMarkerLines(loc, lines);
13602
+ const numberMaxWidth = String(end).length;
13603
+ return rawLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
13604
+ const number = start + 1 + index;
13605
+ const paddedNumber = ` ${String(number)}`.slice(-numberMaxWidth);
13606
+ const gutter = ` ${paddedNumber} |`;
13607
+ const hasMarker = markerLines[number];
13608
+ if (hasMarker) {
13609
+ let markerLine = "";
13610
+ if (Array.isArray(hasMarker)) {
13611
+ const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
13612
+ const numberOfMarkers = hasMarker[1] || 1;
13613
+ markerLine = [
13614
+ "\n ",
13615
+ gutter.replace(/\d/g, " "),
13616
+ " ",
13617
+ markerSpacing,
13618
+ "^".repeat(numberOfMarkers)
13619
+ ].join("");
13620
+ }
13621
+ return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
13622
+ } else {
13623
+ return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
13624
+ }
13625
+ }).join("\n");
13626
+ }
13492
13627
  function pluralize(word, count) {
13493
13628
  return count === 1 ? word : `${word}s`;
13494
13629
  }
@@ -13531,16 +13666,11 @@ function formatMessage(message, parentResult, options) {
13531
13666
  ].filter(String).join(" ");
13532
13667
  const result = [firstLine];
13533
13668
  if (sourceCode) {
13534
- result.push(
13535
- codeFrame.codeFrameColumns(
13536
- sourceCode,
13537
- {
13538
- start: getStartLocation(message),
13539
- end: getEndLocation(message, sourceCode)
13540
- },
13541
- { highlightCode: false }
13542
- )
13543
- );
13669
+ const output = codeFrameColumns(sourceCode, {
13670
+ start: getStartLocation(message),
13671
+ end: getEndLocation(message, sourceCode)
13672
+ });
13673
+ result.push(output);
13544
13674
  }
13545
13675
  if (options.showSelector) {
13546
13676
  result.push(`${kleur__default.default.bold("Selector:")} ${message.selector ?? "-"}`);