html-validate 11.2.0 → 11.3.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 +90 -15
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +16 -2
- package/dist/cjs/elements.js.map +1 -1
- package/dist/esm/core.js +90 -15
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/elements.js +16 -2
- package/dist/esm/elements.js.map +1 -1
- package/dist/types/browser.d.ts +13 -0
- package/dist/types/index.d.ts +13 -0
- package/package.json +1 -1
package/dist/cjs/core.js
CHANGED
|
@@ -1075,6 +1075,7 @@ const MetaCopyableProperty = [
|
|
|
1075
1075
|
"labelable",
|
|
1076
1076
|
"submitButton",
|
|
1077
1077
|
"attributes",
|
|
1078
|
+
"patternAttributes",
|
|
1078
1079
|
"aria",
|
|
1079
1080
|
"permittedContent",
|
|
1080
1081
|
"permittedDescendants",
|
|
@@ -1087,6 +1088,54 @@ function setMetaProperty(dst, key, value) {
|
|
|
1087
1088
|
dst[key] = value;
|
|
1088
1089
|
}
|
|
1089
1090
|
|
|
1091
|
+
const SYNTAX_CHARACTERS = /[$()*+.?[\\\]^{|}]/;
|
|
1092
|
+
const CONTROL_ESCAPES = /* @__PURE__ */ new Map([
|
|
1093
|
+
[" ", "t"],
|
|
1094
|
+
["\n", "n"],
|
|
1095
|
+
["\v", "v"],
|
|
1096
|
+
["\f", "f"],
|
|
1097
|
+
["\r", "r"]
|
|
1098
|
+
]);
|
|
1099
|
+
const OTHER_PUNCTUATORS = /^[!"#%&',:;<=>@`~-]$/;
|
|
1100
|
+
const WHITE_SPACE = /^[\t\v\f\uFEFF\p{Zs}]$/u;
|
|
1101
|
+
const LINE_TERMINATOR = /^[\n\r\u2028\u2029]$/;
|
|
1102
|
+
const SURROGATE = /^[\uD800-\uDFFF]$/;
|
|
1103
|
+
function isDecimalDigitOrASCIILetter(ch) {
|
|
1104
|
+
return /^[\dA-Za-z]$/.test(ch);
|
|
1105
|
+
}
|
|
1106
|
+
function needEscape(ch) {
|
|
1107
|
+
return OTHER_PUNCTUATORS.test(ch) || WHITE_SPACE.test(ch) || LINE_TERMINATOR.test(ch) || SURROGATE.test(ch);
|
|
1108
|
+
}
|
|
1109
|
+
function unicodeEscape(ch) {
|
|
1110
|
+
return `\\u${ch.codePointAt(0).toString(16).padStart(4, "0")}`;
|
|
1111
|
+
}
|
|
1112
|
+
function encodeForRegExpEscape(ch) {
|
|
1113
|
+
if (SYNTAX_CHARACTERS.test(ch) || ch === "/") {
|
|
1114
|
+
return `\\${ch}`;
|
|
1115
|
+
}
|
|
1116
|
+
if (CONTROL_ESCAPES.has(ch)) {
|
|
1117
|
+
return `\\${CONTROL_ESCAPES.get(ch)}`;
|
|
1118
|
+
}
|
|
1119
|
+
if (needEscape(ch)) {
|
|
1120
|
+
if (/[\u0000-\u00FF]/.test(ch)) {
|
|
1121
|
+
return `\\x${ch.codePointAt(0).toString(16).padStart(2, "0")}`;
|
|
1122
|
+
}
|
|
1123
|
+
return ch.split("").map((c) => unicodeEscape(c)).join("");
|
|
1124
|
+
}
|
|
1125
|
+
return ch;
|
|
1126
|
+
}
|
|
1127
|
+
function regexpEscape(str) {
|
|
1128
|
+
let escaped = "";
|
|
1129
|
+
for (const c of str) {
|
|
1130
|
+
if (escaped === "" && isDecimalDigitOrASCIILetter(c)) {
|
|
1131
|
+
escaped += `\\x${c.codePointAt(0).toString(16).padStart(2, "0")}`;
|
|
1132
|
+
} else {
|
|
1133
|
+
escaped += encodeForRegExpEscape(c);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return escaped;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1090
1139
|
function isSet(value) {
|
|
1091
1140
|
return value !== void 0;
|
|
1092
1141
|
}
|
|
@@ -1124,18 +1173,35 @@ function migrateSingleAttribute(src, key) {
|
|
|
1124
1173
|
return stripUndefined({ ...result, ...attr });
|
|
1125
1174
|
}
|
|
1126
1175
|
}
|
|
1176
|
+
function isPatternAttribute$1(key) {
|
|
1177
|
+
return key.includes("*");
|
|
1178
|
+
}
|
|
1179
|
+
function patternToRegex(pattern) {
|
|
1180
|
+
const escaped = pattern.split("*").map(regexpEscape).join(".+");
|
|
1181
|
+
return new RegExp(`^${escaped}$`, "i");
|
|
1182
|
+
}
|
|
1127
1183
|
function migrateAttributes(src) {
|
|
1128
1184
|
const keys = [
|
|
1129
1185
|
...Object.keys(src.attributes ?? {}),
|
|
1130
1186
|
...src.requiredAttributes ?? [],
|
|
1131
1187
|
...src.deprecatedAttributes ?? []
|
|
1132
|
-
|
|
1133
|
-
].toSorted();
|
|
1188
|
+
].filter((key) => !isPatternAttribute$1(key)).toSorted();
|
|
1134
1189
|
const entries = keys.map((key) => {
|
|
1135
1190
|
return [key, migrateSingleAttribute(src, key)];
|
|
1136
1191
|
});
|
|
1137
1192
|
return Object.fromEntries(entries);
|
|
1138
1193
|
}
|
|
1194
|
+
function migratePatternAttributes(src) {
|
|
1195
|
+
const attrs = src.attributes ?? {};
|
|
1196
|
+
return Object.entries(attrs).filter(([key]) => isPatternAttribute$1(key)).map(([pattern]) => {
|
|
1197
|
+
const { delete: deleted, ...attr } = migrateSingleAttribute(src, pattern);
|
|
1198
|
+
const regexp = patternToRegex(pattern);
|
|
1199
|
+
if (deleted) {
|
|
1200
|
+
return { pattern, regexp, delete: true };
|
|
1201
|
+
}
|
|
1202
|
+
return { ...attr, pattern, regexp };
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1139
1205
|
function normalizeAriaImplicitRole(value) {
|
|
1140
1206
|
if (!value) {
|
|
1141
1207
|
return () => null;
|
|
@@ -1160,6 +1226,7 @@ function migrateElement(src) {
|
|
|
1160
1226
|
...src,
|
|
1161
1227
|
formAssociated: void 0,
|
|
1162
1228
|
attributes: migrateAttributes(src),
|
|
1229
|
+
patternAttributes: migratePatternAttributes(src),
|
|
1163
1230
|
textContent: src.textContent,
|
|
1164
1231
|
focusable: src.focusable ?? false,
|
|
1165
1232
|
implicitRole,
|
|
@@ -1389,6 +1456,18 @@ class MetaTable {
|
|
|
1389
1456
|
}
|
|
1390
1457
|
}
|
|
1391
1458
|
merged.attributes = mergedAttrs;
|
|
1459
|
+
const mergedPatterns = [
|
|
1460
|
+
...b.patternAttributes,
|
|
1461
|
+
...a.patternAttributes ?? []
|
|
1462
|
+
];
|
|
1463
|
+
const seenPatterns = /* @__PURE__ */ new Set();
|
|
1464
|
+
merged.patternAttributes = mergedPatterns.filter((entry) => {
|
|
1465
|
+
if (seenPatterns.has(entry.pattern)) {
|
|
1466
|
+
return false;
|
|
1467
|
+
}
|
|
1468
|
+
seenPatterns.add(entry.pattern);
|
|
1469
|
+
return !entry.delete;
|
|
1470
|
+
});
|
|
1392
1471
|
if (a.aria) {
|
|
1393
1472
|
merged.aria = { ...a.aria, ...b.aria };
|
|
1394
1473
|
}
|
|
@@ -3466,6 +3545,10 @@ function isKeywordIgnored(options, keyword, matcher = (list, it) => list.include
|
|
|
3466
3545
|
return false;
|
|
3467
3546
|
}
|
|
3468
3547
|
|
|
3548
|
+
function isPatternAttribute(attrName, dynamicAttributes) {
|
|
3549
|
+
return dynamicAttributes.some((entry) => entry.regexp.test(attrName));
|
|
3550
|
+
}
|
|
3551
|
+
|
|
3469
3552
|
const ARIA_HIDDEN_CACHE = Symbol(isAriaHidden.name);
|
|
3470
3553
|
const HTML_HIDDEN_CACHE = Symbol(isHTMLHidden.name);
|
|
3471
3554
|
const INERT_CACHE = Symbol(isInert.name);
|
|
@@ -8968,18 +9051,7 @@ class NoTrailingWhitespace extends Rule {
|
|
|
8968
9051
|
}
|
|
8969
9052
|
}
|
|
8970
9053
|
|
|
8971
|
-
const skipPatterns = [
|
|
8972
|
-
/^data-/i,
|
|
8973
|
-
/^aria-/i,
|
|
8974
|
-
/^on[a-z]/i,
|
|
8975
|
-
/^xml(ns)?:/i,
|
|
8976
|
-
/^:/,
|
|
8977
|
-
/^@/,
|
|
8978
|
-
/^ng-/i,
|
|
8979
|
-
/^v-/i,
|
|
8980
|
-
/^x-/i,
|
|
8981
|
-
/^\[/
|
|
8982
|
-
];
|
|
9054
|
+
const skipPatterns = [/^:/, /^@/, /^ng-/i, /^v-/i, /^x-/i, /^\[/, /^#/];
|
|
8983
9055
|
function isKnownDynamicAttr(attr) {
|
|
8984
9056
|
return skipPatterns.some((pattern) => pattern.test(attr));
|
|
8985
9057
|
}
|
|
@@ -9001,6 +9073,9 @@ class NoUnknownAttributes extends Rule {
|
|
|
9001
9073
|
if (attr in meta.attributes) {
|
|
9002
9074
|
return;
|
|
9003
9075
|
}
|
|
9076
|
+
if (isPatternAttribute(attr, meta.patternAttributes)) {
|
|
9077
|
+
return;
|
|
9078
|
+
}
|
|
9004
9079
|
if (isKnownDynamicAttr(attr)) {
|
|
9005
9080
|
return;
|
|
9006
9081
|
}
|
|
@@ -12639,7 +12714,7 @@ class EventHandler {
|
|
|
12639
12714
|
}
|
|
12640
12715
|
|
|
12641
12716
|
const name = "html-validate";
|
|
12642
|
-
const version = "11.
|
|
12717
|
+
const version = "11.3.0";
|
|
12643
12718
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12644
12719
|
|
|
12645
12720
|
function freeze(src) {
|