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/esm/core.js
CHANGED
|
@@ -1066,6 +1066,7 @@ const MetaCopyableProperty = [
|
|
|
1066
1066
|
"labelable",
|
|
1067
1067
|
"submitButton",
|
|
1068
1068
|
"attributes",
|
|
1069
|
+
"patternAttributes",
|
|
1069
1070
|
"aria",
|
|
1070
1071
|
"permittedContent",
|
|
1071
1072
|
"permittedDescendants",
|
|
@@ -1078,6 +1079,54 @@ function setMetaProperty(dst, key, value) {
|
|
|
1078
1079
|
dst[key] = value;
|
|
1079
1080
|
}
|
|
1080
1081
|
|
|
1082
|
+
const SYNTAX_CHARACTERS = /[$()*+.?[\\\]^{|}]/;
|
|
1083
|
+
const CONTROL_ESCAPES = /* @__PURE__ */ new Map([
|
|
1084
|
+
[" ", "t"],
|
|
1085
|
+
["\n", "n"],
|
|
1086
|
+
["\v", "v"],
|
|
1087
|
+
["\f", "f"],
|
|
1088
|
+
["\r", "r"]
|
|
1089
|
+
]);
|
|
1090
|
+
const OTHER_PUNCTUATORS = /^[!"#%&',:;<=>@`~-]$/;
|
|
1091
|
+
const WHITE_SPACE = /^[\t\v\f\uFEFF\p{Zs}]$/u;
|
|
1092
|
+
const LINE_TERMINATOR = /^[\n\r\u2028\u2029]$/;
|
|
1093
|
+
const SURROGATE = /^[\uD800-\uDFFF]$/;
|
|
1094
|
+
function isDecimalDigitOrASCIILetter(ch) {
|
|
1095
|
+
return /^[\dA-Za-z]$/.test(ch);
|
|
1096
|
+
}
|
|
1097
|
+
function needEscape(ch) {
|
|
1098
|
+
return OTHER_PUNCTUATORS.test(ch) || WHITE_SPACE.test(ch) || LINE_TERMINATOR.test(ch) || SURROGATE.test(ch);
|
|
1099
|
+
}
|
|
1100
|
+
function unicodeEscape(ch) {
|
|
1101
|
+
return `\\u${ch.codePointAt(0).toString(16).padStart(4, "0")}`;
|
|
1102
|
+
}
|
|
1103
|
+
function encodeForRegExpEscape(ch) {
|
|
1104
|
+
if (SYNTAX_CHARACTERS.test(ch) || ch === "/") {
|
|
1105
|
+
return `\\${ch}`;
|
|
1106
|
+
}
|
|
1107
|
+
if (CONTROL_ESCAPES.has(ch)) {
|
|
1108
|
+
return `\\${CONTROL_ESCAPES.get(ch)}`;
|
|
1109
|
+
}
|
|
1110
|
+
if (needEscape(ch)) {
|
|
1111
|
+
if (/[\u0000-\u00FF]/.test(ch)) {
|
|
1112
|
+
return `\\x${ch.codePointAt(0).toString(16).padStart(2, "0")}`;
|
|
1113
|
+
}
|
|
1114
|
+
return ch.split("").map((c) => unicodeEscape(c)).join("");
|
|
1115
|
+
}
|
|
1116
|
+
return ch;
|
|
1117
|
+
}
|
|
1118
|
+
function regexpEscape(str) {
|
|
1119
|
+
let escaped = "";
|
|
1120
|
+
for (const c of str) {
|
|
1121
|
+
if (escaped === "" && isDecimalDigitOrASCIILetter(c)) {
|
|
1122
|
+
escaped += `\\x${c.codePointAt(0).toString(16).padStart(2, "0")}`;
|
|
1123
|
+
} else {
|
|
1124
|
+
escaped += encodeForRegExpEscape(c);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return escaped;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1081
1130
|
function isSet(value) {
|
|
1082
1131
|
return value !== void 0;
|
|
1083
1132
|
}
|
|
@@ -1115,18 +1164,35 @@ function migrateSingleAttribute(src, key) {
|
|
|
1115
1164
|
return stripUndefined({ ...result, ...attr });
|
|
1116
1165
|
}
|
|
1117
1166
|
}
|
|
1167
|
+
function isPatternAttribute$1(key) {
|
|
1168
|
+
return key.includes("*");
|
|
1169
|
+
}
|
|
1170
|
+
function patternToRegex(pattern) {
|
|
1171
|
+
const escaped = pattern.split("*").map(regexpEscape).join(".+");
|
|
1172
|
+
return new RegExp(`^${escaped}$`, "i");
|
|
1173
|
+
}
|
|
1118
1174
|
function migrateAttributes(src) {
|
|
1119
1175
|
const keys = [
|
|
1120
1176
|
...Object.keys(src.attributes ?? {}),
|
|
1121
1177
|
...src.requiredAttributes ?? [],
|
|
1122
1178
|
...src.deprecatedAttributes ?? []
|
|
1123
|
-
|
|
1124
|
-
].toSorted();
|
|
1179
|
+
].filter((key) => !isPatternAttribute$1(key)).toSorted();
|
|
1125
1180
|
const entries = keys.map((key) => {
|
|
1126
1181
|
return [key, migrateSingleAttribute(src, key)];
|
|
1127
1182
|
});
|
|
1128
1183
|
return Object.fromEntries(entries);
|
|
1129
1184
|
}
|
|
1185
|
+
function migratePatternAttributes(src) {
|
|
1186
|
+
const attrs = src.attributes ?? {};
|
|
1187
|
+
return Object.entries(attrs).filter(([key]) => isPatternAttribute$1(key)).map(([pattern]) => {
|
|
1188
|
+
const { delete: deleted, ...attr } = migrateSingleAttribute(src, pattern);
|
|
1189
|
+
const regexp = patternToRegex(pattern);
|
|
1190
|
+
if (deleted) {
|
|
1191
|
+
return { pattern, regexp, delete: true };
|
|
1192
|
+
}
|
|
1193
|
+
return { ...attr, pattern, regexp };
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1130
1196
|
function normalizeAriaImplicitRole(value) {
|
|
1131
1197
|
if (!value) {
|
|
1132
1198
|
return () => null;
|
|
@@ -1151,6 +1217,7 @@ function migrateElement(src) {
|
|
|
1151
1217
|
...src,
|
|
1152
1218
|
formAssociated: void 0,
|
|
1153
1219
|
attributes: migrateAttributes(src),
|
|
1220
|
+
patternAttributes: migratePatternAttributes(src),
|
|
1154
1221
|
textContent: src.textContent,
|
|
1155
1222
|
focusable: src.focusable ?? false,
|
|
1156
1223
|
implicitRole,
|
|
@@ -1380,6 +1447,18 @@ class MetaTable {
|
|
|
1380
1447
|
}
|
|
1381
1448
|
}
|
|
1382
1449
|
merged.attributes = mergedAttrs;
|
|
1450
|
+
const mergedPatterns = [
|
|
1451
|
+
...b.patternAttributes,
|
|
1452
|
+
...a.patternAttributes ?? []
|
|
1453
|
+
];
|
|
1454
|
+
const seenPatterns = /* @__PURE__ */ new Set();
|
|
1455
|
+
merged.patternAttributes = mergedPatterns.filter((entry) => {
|
|
1456
|
+
if (seenPatterns.has(entry.pattern)) {
|
|
1457
|
+
return false;
|
|
1458
|
+
}
|
|
1459
|
+
seenPatterns.add(entry.pattern);
|
|
1460
|
+
return !entry.delete;
|
|
1461
|
+
});
|
|
1383
1462
|
if (a.aria) {
|
|
1384
1463
|
merged.aria = { ...a.aria, ...b.aria };
|
|
1385
1464
|
}
|
|
@@ -3457,6 +3536,10 @@ function isKeywordIgnored(options, keyword, matcher = (list, it) => list.include
|
|
|
3457
3536
|
return false;
|
|
3458
3537
|
}
|
|
3459
3538
|
|
|
3539
|
+
function isPatternAttribute(attrName, dynamicAttributes) {
|
|
3540
|
+
return dynamicAttributes.some((entry) => entry.regexp.test(attrName));
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3460
3543
|
const ARIA_HIDDEN_CACHE = Symbol(isAriaHidden.name);
|
|
3461
3544
|
const HTML_HIDDEN_CACHE = Symbol(isHTMLHidden.name);
|
|
3462
3545
|
const INERT_CACHE = Symbol(isInert.name);
|
|
@@ -8959,18 +9042,7 @@ class NoTrailingWhitespace extends Rule {
|
|
|
8959
9042
|
}
|
|
8960
9043
|
}
|
|
8961
9044
|
|
|
8962
|
-
const skipPatterns = [
|
|
8963
|
-
/^data-/i,
|
|
8964
|
-
/^aria-/i,
|
|
8965
|
-
/^on[a-z]/i,
|
|
8966
|
-
/^xml(ns)?:/i,
|
|
8967
|
-
/^:/,
|
|
8968
|
-
/^@/,
|
|
8969
|
-
/^ng-/i,
|
|
8970
|
-
/^v-/i,
|
|
8971
|
-
/^x-/i,
|
|
8972
|
-
/^\[/
|
|
8973
|
-
];
|
|
9045
|
+
const skipPatterns = [/^:/, /^@/, /^ng-/i, /^v-/i, /^x-/i, /^\[/, /^#/];
|
|
8974
9046
|
function isKnownDynamicAttr(attr) {
|
|
8975
9047
|
return skipPatterns.some((pattern) => pattern.test(attr));
|
|
8976
9048
|
}
|
|
@@ -8992,6 +9064,9 @@ class NoUnknownAttributes extends Rule {
|
|
|
8992
9064
|
if (attr in meta.attributes) {
|
|
8993
9065
|
return;
|
|
8994
9066
|
}
|
|
9067
|
+
if (isPatternAttribute(attr, meta.patternAttributes)) {
|
|
9068
|
+
return;
|
|
9069
|
+
}
|
|
8995
9070
|
if (isKnownDynamicAttr(attr)) {
|
|
8996
9071
|
return;
|
|
8997
9072
|
}
|
|
@@ -12630,7 +12705,7 @@ class EventHandler {
|
|
|
12630
12705
|
}
|
|
12631
12706
|
|
|
12632
12707
|
const name = "html-validate";
|
|
12633
|
-
const version = "11.
|
|
12708
|
+
const version = "11.3.0";
|
|
12634
12709
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12635
12710
|
|
|
12636
12711
|
function freeze(src) {
|