html-validate 8.21.0 → 8.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/browser.js +0 -1
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/core.js +184 -52
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/html-validate.js +0 -1
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/jest.js +0 -1
- package/dist/cjs/jest.js.map +1 -1
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/cjs/vitest.js +0 -1
- package/dist/cjs/vitest.js.map +1 -1
- package/dist/es/browser.js +0 -1
- package/dist/es/browser.js.map +1 -1
- package/dist/es/core.js +184 -52
- package/dist/es/core.js.map +1 -1
- package/dist/es/html-validate.js +0 -1
- package/dist/es/html-validate.js.map +1 -1
- package/dist/es/index.js +0 -1
- package/dist/es/index.js.map +1 -1
- package/dist/es/jest.js +0 -1
- package/dist/es/jest.js.map +1 -1
- package/dist/es/vitest.js +0 -1
- package/dist/es/vitest.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +28 -11
- package/dist/types/index.d.ts +28 -11
- package/package.json +25 -28
package/dist/cjs/browser.js
CHANGED
package/dist/cjs/browser.js.map
CHANGED
|
@@ -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(
|
|
2353
|
-
const
|
|
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(
|
|
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(
|
|
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
|
}
|
|
@@ -11170,12 +11241,18 @@ class Config {
|
|
|
11170
11241
|
}
|
|
11171
11242
|
|
|
11172
11243
|
class ConfigLoader {
|
|
11173
|
-
|
|
11244
|
+
/**
|
|
11245
|
+
* Create a new ConfigLoader.
|
|
11246
|
+
*
|
|
11247
|
+
* @param resolvers - Sorted list of resolvers to use (in order).
|
|
11248
|
+
* @param configData - Default configuration (which all configurations will inherit from).
|
|
11249
|
+
*/
|
|
11250
|
+
constructor(resolvers, configData) {
|
|
11174
11251
|
const defaults = Config.empty();
|
|
11175
11252
|
this.resolvers = resolvers;
|
|
11176
11253
|
this.globalConfig = defaults.merge(
|
|
11177
11254
|
this.resolvers,
|
|
11178
|
-
|
|
11255
|
+
configData ? this.loadFromObject(configData) : this.defaultConfig()
|
|
11179
11256
|
);
|
|
11180
11257
|
}
|
|
11181
11258
|
/**
|
|
@@ -12096,33 +12173,8 @@ class Engine {
|
|
|
12096
12173
|
}
|
|
12097
12174
|
dumpTree(source) {
|
|
12098
12175
|
const parser = this.instantiateParser();
|
|
12099
|
-
const
|
|
12100
|
-
|
|
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;
|
|
12176
|
+
const root = parser.parseHtml(source[0]);
|
|
12177
|
+
return dumpTree(root);
|
|
12126
12178
|
}
|
|
12127
12179
|
/**
|
|
12128
12180
|
* Get rule documentation.
|
|
@@ -12797,7 +12849,7 @@ class HtmlValidate {
|
|
|
12797
12849
|
}
|
|
12798
12850
|
|
|
12799
12851
|
const name = "html-validate";
|
|
12800
|
-
const version = "8.
|
|
12852
|
+
const version = "8.23.0";
|
|
12801
12853
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12802
12854
|
|
|
12803
12855
|
function definePlugin(plugin) {
|
|
@@ -12885,17 +12937,26 @@ const REPLACERS = [
|
|
|
12885
12937
|
[
|
|
12886
12938
|
// (a\ ) -> (a )
|
|
12887
12939
|
// (a ) -> (a)
|
|
12940
|
+
// (a ) -> (a)
|
|
12888
12941
|
// (a \ ) -> (a )
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12942
|
+
/((?:\\\\)*?)(\\?\s+)$/,
|
|
12943
|
+
(_, m1, m2) => m1 + (
|
|
12944
|
+
m2.indexOf('\\') === 0
|
|
12945
|
+
? SPACE
|
|
12946
|
+
: EMPTY
|
|
12947
|
+
)
|
|
12893
12948
|
],
|
|
12894
12949
|
|
|
12895
12950
|
// replace (\ ) with ' '
|
|
12951
|
+
// (\ ) -> ' '
|
|
12952
|
+
// (\\ ) -> '\\ '
|
|
12953
|
+
// (\\\ ) -> '\\ '
|
|
12896
12954
|
[
|
|
12897
|
-
|
|
12898
|
-
() =>
|
|
12955
|
+
/(\\+?)\s/g,
|
|
12956
|
+
(_, m1) => {
|
|
12957
|
+
const {length} = m1;
|
|
12958
|
+
return m1.slice(0, length - length % 2) + SPACE
|
|
12959
|
+
}
|
|
12899
12960
|
],
|
|
12900
12961
|
|
|
12901
12962
|
// Escape metacharacters
|
|
@@ -13123,7 +13184,8 @@ const makeRegex = (pattern, ignoreCase) => {
|
|
|
13123
13184
|
|
|
13124
13185
|
if (!source) {
|
|
13125
13186
|
source = REPLACERS.reduce(
|
|
13126
|
-
(prev,
|
|
13187
|
+
(prev, [matcher, replacer]) =>
|
|
13188
|
+
prev.replace(matcher, replacer.bind(pattern)),
|
|
13127
13189
|
pattern
|
|
13128
13190
|
);
|
|
13129
13191
|
regexCache[pattern] = source;
|
|
@@ -13489,6 +13551,81 @@ const defaults = {
|
|
|
13489
13551
|
showSummary: true,
|
|
13490
13552
|
showSelector: false
|
|
13491
13553
|
};
|
|
13554
|
+
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
|
13555
|
+
function getMarkerLines(loc, source) {
|
|
13556
|
+
const startLoc = {
|
|
13557
|
+
...loc.start
|
|
13558
|
+
};
|
|
13559
|
+
const endLoc = {
|
|
13560
|
+
...startLoc,
|
|
13561
|
+
...loc.end
|
|
13562
|
+
};
|
|
13563
|
+
const linesAbove = 2;
|
|
13564
|
+
const linesBelow = 3;
|
|
13565
|
+
const startLine = startLoc.line;
|
|
13566
|
+
const startColumn = startLoc.column;
|
|
13567
|
+
const endLine = endLoc.line;
|
|
13568
|
+
const endColumn = endLoc.column;
|
|
13569
|
+
const start = Math.max(startLine - (linesAbove + 1), 0);
|
|
13570
|
+
const end = Math.min(source.length, endLine + linesBelow);
|
|
13571
|
+
const lineDiff = endLine - startLine;
|
|
13572
|
+
const markerLines = {};
|
|
13573
|
+
if (lineDiff) {
|
|
13574
|
+
for (let i = 0; i <= lineDiff; i++) {
|
|
13575
|
+
const lineNumber = i + startLine;
|
|
13576
|
+
if (!startColumn) {
|
|
13577
|
+
markerLines[lineNumber] = true;
|
|
13578
|
+
} else if (i === 0) {
|
|
13579
|
+
const sourceLength = source[lineNumber - 1].length;
|
|
13580
|
+
markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
|
|
13581
|
+
} else if (i === lineDiff) {
|
|
13582
|
+
markerLines[lineNumber] = [0, endColumn];
|
|
13583
|
+
} else {
|
|
13584
|
+
const sourceLength = source[lineNumber - i].length;
|
|
13585
|
+
markerLines[lineNumber] = [0, sourceLength];
|
|
13586
|
+
}
|
|
13587
|
+
}
|
|
13588
|
+
} else {
|
|
13589
|
+
if (startColumn === endColumn) {
|
|
13590
|
+
if (startColumn) {
|
|
13591
|
+
markerLines[startLine] = [startColumn, 0];
|
|
13592
|
+
} else {
|
|
13593
|
+
markerLines[startLine] = true;
|
|
13594
|
+
}
|
|
13595
|
+
} else {
|
|
13596
|
+
markerLines[startLine] = [startColumn, endColumn - startColumn];
|
|
13597
|
+
}
|
|
13598
|
+
}
|
|
13599
|
+
return { start, end, markerLines };
|
|
13600
|
+
}
|
|
13601
|
+
function codeFrameColumns(rawLines, loc) {
|
|
13602
|
+
const lines = rawLines.split(NEWLINE);
|
|
13603
|
+
const { start, end, markerLines } = getMarkerLines(loc, lines);
|
|
13604
|
+
const numberMaxWidth = String(end).length;
|
|
13605
|
+
return rawLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
|
|
13606
|
+
const number = start + 1 + index;
|
|
13607
|
+
const paddedNumber = ` ${String(number)}`.slice(-numberMaxWidth);
|
|
13608
|
+
const gutter = ` ${paddedNumber} |`;
|
|
13609
|
+
const hasMarker = markerLines[number];
|
|
13610
|
+
if (hasMarker) {
|
|
13611
|
+
let markerLine = "";
|
|
13612
|
+
if (Array.isArray(hasMarker)) {
|
|
13613
|
+
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
|
|
13614
|
+
const numberOfMarkers = hasMarker[1] || 1;
|
|
13615
|
+
markerLine = [
|
|
13616
|
+
"\n ",
|
|
13617
|
+
gutter.replace(/\d/g, " "),
|
|
13618
|
+
" ",
|
|
13619
|
+
markerSpacing,
|
|
13620
|
+
"^".repeat(numberOfMarkers)
|
|
13621
|
+
].join("");
|
|
13622
|
+
}
|
|
13623
|
+
return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
|
13624
|
+
} else {
|
|
13625
|
+
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
13626
|
+
}
|
|
13627
|
+
}).join("\n");
|
|
13628
|
+
}
|
|
13492
13629
|
function pluralize(word, count) {
|
|
13493
13630
|
return count === 1 ? word : `${word}s`;
|
|
13494
13631
|
}
|
|
@@ -13531,16 +13668,11 @@ function formatMessage(message, parentResult, options) {
|
|
|
13531
13668
|
].filter(String).join(" ");
|
|
13532
13669
|
const result = [firstLine];
|
|
13533
13670
|
if (sourceCode) {
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
end: getEndLocation(message, sourceCode)
|
|
13540
|
-
},
|
|
13541
|
-
{ highlightCode: false }
|
|
13542
|
-
)
|
|
13543
|
-
);
|
|
13671
|
+
const output = codeFrameColumns(sourceCode, {
|
|
13672
|
+
start: getStartLocation(message),
|
|
13673
|
+
end: getEndLocation(message, sourceCode)
|
|
13674
|
+
});
|
|
13675
|
+
result.push(output);
|
|
13544
13676
|
}
|
|
13545
13677
|
if (options.showSelector) {
|
|
13546
13678
|
result.push(`${kleur__default.default.bold("Selector:")} ${message.selector ?? "-"}`);
|