html-validate 8.21.0 → 8.22.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.
@@ -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.
@@ -12797,7 +12843,7 @@ class HtmlValidate {
12797
12843
  }
12798
12844
 
12799
12845
  const name = "html-validate";
12800
- const version = "8.21.0";
12846
+ const version = "8.22.0";
12801
12847
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12802
12848
 
12803
12849
  function definePlugin(plugin) {
@@ -12885,17 +12931,26 @@ const REPLACERS = [
12885
12931
  [
12886
12932
  // (a\ ) -> (a )
12887
12933
  // (a ) -> (a)
12934
+ // (a ) -> (a)
12888
12935
  // (a \ ) -> (a )
12889
- /\\?\s+$/,
12890
- match => match.indexOf('\\') === 0
12891
- ? SPACE
12892
- : EMPTY
12936
+ /((?:\\\\)*?)(\\?\s+)$/,
12937
+ (_, m1, m2) => m1 + (
12938
+ m2.indexOf('\\') === 0
12939
+ ? SPACE
12940
+ : EMPTY
12941
+ )
12893
12942
  ],
12894
12943
 
12895
12944
  // replace (\ ) with ' '
12945
+ // (\ ) -> ' '
12946
+ // (\\ ) -> '\\ '
12947
+ // (\\\ ) -> '\\ '
12896
12948
  [
12897
- /\\\s/g,
12898
- () => SPACE
12949
+ /(\\+?)\s/g,
12950
+ (_, m1) => {
12951
+ const {length} = m1;
12952
+ return m1.slice(0, length - length % 2) + SPACE
12953
+ }
12899
12954
  ],
12900
12955
 
12901
12956
  // Escape metacharacters
@@ -13123,7 +13178,8 @@ const makeRegex = (pattern, ignoreCase) => {
13123
13178
 
13124
13179
  if (!source) {
13125
13180
  source = REPLACERS.reduce(
13126
- (prev, current) => prev.replace(current[0], current[1].bind(pattern)),
13181
+ (prev, [matcher, replacer]) =>
13182
+ prev.replace(matcher, replacer.bind(pattern)),
13127
13183
  pattern
13128
13184
  );
13129
13185
  regexCache[pattern] = source;
@@ -13489,6 +13545,81 @@ const defaults = {
13489
13545
  showSummary: true,
13490
13546
  showSelector: false
13491
13547
  };
13548
+ const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
13549
+ function getMarkerLines(loc, source) {
13550
+ const startLoc = {
13551
+ ...loc.start
13552
+ };
13553
+ const endLoc = {
13554
+ ...startLoc,
13555
+ ...loc.end
13556
+ };
13557
+ const linesAbove = 2;
13558
+ const linesBelow = 3;
13559
+ const startLine = startLoc.line;
13560
+ const startColumn = startLoc.column;
13561
+ const endLine = endLoc.line;
13562
+ const endColumn = endLoc.column;
13563
+ const start = Math.max(startLine - (linesAbove + 1), 0);
13564
+ const end = Math.min(source.length, endLine + linesBelow);
13565
+ const lineDiff = endLine - startLine;
13566
+ const markerLines = {};
13567
+ if (lineDiff) {
13568
+ for (let i = 0; i <= lineDiff; i++) {
13569
+ const lineNumber = i + startLine;
13570
+ if (!startColumn) {
13571
+ markerLines[lineNumber] = true;
13572
+ } else if (i === 0) {
13573
+ const sourceLength = source[lineNumber - 1].length;
13574
+ markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
13575
+ } else if (i === lineDiff) {
13576
+ markerLines[lineNumber] = [0, endColumn];
13577
+ } else {
13578
+ const sourceLength = source[lineNumber - i].length;
13579
+ markerLines[lineNumber] = [0, sourceLength];
13580
+ }
13581
+ }
13582
+ } else {
13583
+ if (startColumn === endColumn) {
13584
+ if (startColumn) {
13585
+ markerLines[startLine] = [startColumn, 0];
13586
+ } else {
13587
+ markerLines[startLine] = true;
13588
+ }
13589
+ } else {
13590
+ markerLines[startLine] = [startColumn, endColumn - startColumn];
13591
+ }
13592
+ }
13593
+ return { start, end, markerLines };
13594
+ }
13595
+ function codeFrameColumns(rawLines, loc) {
13596
+ const lines = rawLines.split(NEWLINE);
13597
+ const { start, end, markerLines } = getMarkerLines(loc, lines);
13598
+ const numberMaxWidth = String(end).length;
13599
+ return rawLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
13600
+ const number = start + 1 + index;
13601
+ const paddedNumber = ` ${String(number)}`.slice(-numberMaxWidth);
13602
+ const gutter = ` ${paddedNumber} |`;
13603
+ const hasMarker = markerLines[number];
13604
+ if (hasMarker) {
13605
+ let markerLine = "";
13606
+ if (Array.isArray(hasMarker)) {
13607
+ const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
13608
+ const numberOfMarkers = hasMarker[1] || 1;
13609
+ markerLine = [
13610
+ "\n ",
13611
+ gutter.replace(/\d/g, " "),
13612
+ " ",
13613
+ markerSpacing,
13614
+ "^".repeat(numberOfMarkers)
13615
+ ].join("");
13616
+ }
13617
+ return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
13618
+ } else {
13619
+ return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
13620
+ }
13621
+ }).join("\n");
13622
+ }
13492
13623
  function pluralize(word, count) {
13493
13624
  return count === 1 ? word : `${word}s`;
13494
13625
  }
@@ -13531,16 +13662,11 @@ function formatMessage(message, parentResult, options) {
13531
13662
  ].filter(String).join(" ");
13532
13663
  const result = [firstLine];
13533
13664
  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
- );
13665
+ const output = codeFrameColumns(sourceCode, {
13666
+ start: getStartLocation(message),
13667
+ end: getEndLocation(message, sourceCode)
13668
+ });
13669
+ result.push(output);
13544
13670
  }
13545
13671
  if (options.showSelector) {
13546
13672
  result.push(`${kleur__default.default.bold("Selector:")} ${message.selector ?? "-"}`);