praxis-kit 6.2.3 → 6.6.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/_shared/diagnostics.d.ts +4 -0
- package/dist/_shared/diagnostics.js +4 -0
- package/dist/{chunk-H3D2JA3J.js → chunk-OCG5VM4H.js} +519 -326
- package/dist/contract/index.d.ts +11 -0
- package/dist/contract/index.js +2 -0
- package/dist/guards/index.d.ts +11 -2
- package/dist/html/index.d.ts +98 -0
- package/dist/html/index.js +860 -0
- package/dist/lit/index.d.ts +11 -0
- package/dist/lit/index.js +519 -326
- package/dist/preact/index.d.ts +20 -0
- package/dist/preact/index.js +519 -326
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/dist/react/legacy.d.ts +2 -2
- package/dist/react/legacy.js +1 -1
- package/dist/{react-options-DQTX4YS_.d.ts → react-options-BUBVohU6.d.ts} +50 -33
- package/dist/solid/index.d.ts +20 -0
- package/dist/solid/index.js +519 -326
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.js +519 -326
- package/dist/vite-plugin/index.d.ts +4 -0
- package/dist/vue/index.d.ts +11 -0
- package/dist/vue/index.js +519 -326
- package/dist/web/index.d.ts +11 -0
- package/dist/web/index.js +519 -326
- package/package.json +12 -5
package/dist/svelte/index.js
CHANGED
|
@@ -25,6 +25,9 @@ function isNull(value) {
|
|
|
25
25
|
function isNonNull(value) {
|
|
26
26
|
return value != null;
|
|
27
27
|
}
|
|
28
|
+
function isNullish(value) {
|
|
29
|
+
return isNull(value) || value === void 0;
|
|
30
|
+
}
|
|
28
31
|
|
|
29
32
|
// ../../lib/primitive/src/utils/type-guards.ts
|
|
30
33
|
function isObject(value, excludeArrays = false) {
|
|
@@ -526,20 +529,29 @@ function isAriaAttributeValidForRole(attr, role) {
|
|
|
526
529
|
}
|
|
527
530
|
|
|
528
531
|
// ../../lib/primitive/src/guards/aria/is-aria-role.ts
|
|
532
|
+
function lookupImplicitRole(tag) {
|
|
533
|
+
return IMPLICIT_ROLE_RECORD[tag];
|
|
534
|
+
}
|
|
529
535
|
function isStrongImplicitRole(tag) {
|
|
530
|
-
|
|
531
|
-
return STRONG_ROLES_SET.has(
|
|
536
|
+
const role = lookupImplicitRole(tag);
|
|
537
|
+
return !isNullish(role) && STRONG_ROLES_SET.has(role);
|
|
532
538
|
}
|
|
533
|
-
function
|
|
534
|
-
|
|
535
|
-
return STANDALONE_ROLES_SET.has(
|
|
539
|
+
function hasStandaloneRole(tag) {
|
|
540
|
+
const role = lookupImplicitRole(tag);
|
|
541
|
+
return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
|
|
536
542
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
return
|
|
543
|
+
var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
|
|
544
|
+
function getInputImplicitRole(type, list) {
|
|
545
|
+
if (!isString(type)) return void 0;
|
|
546
|
+
const role = INPUT_TYPE_ROLE_MAP[type];
|
|
547
|
+
if (!role) return void 0;
|
|
548
|
+
if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
|
|
549
|
+
return "combobox";
|
|
550
|
+
}
|
|
551
|
+
return role;
|
|
540
552
|
}
|
|
541
553
|
function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
|
|
542
|
-
const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
|
|
554
|
+
const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
|
|
543
555
|
if (!isNamed) return void 0;
|
|
544
556
|
if (tag === "section") return "region";
|
|
545
557
|
if (tag === "form") return "form";
|
|
@@ -585,7 +597,7 @@ function isTag(...args) {
|
|
|
585
597
|
// ../../lib/contract/src/aria/aria-role-policy.ts
|
|
586
598
|
function getImplicitRole(tag, props) {
|
|
587
599
|
if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
|
|
588
|
-
if (tag === "input") return getInputImplicitRole(props?.type);
|
|
600
|
+
if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
|
|
589
601
|
if (tag === "img") return props?.alt === "" ? "none" : "img";
|
|
590
602
|
if (tag === "section" || tag === "form") {
|
|
591
603
|
return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
|
|
@@ -868,7 +880,11 @@ var ATTRIBUTE_IGNORED_CODES = {
|
|
|
868
880
|
max: DiagnosticCode3.HtmlInputMaxIgnoredForType,
|
|
869
881
|
step: DiagnosticCode3.HtmlInputStepIgnoredForType,
|
|
870
882
|
accept: DiagnosticCode3.HtmlInputAcceptIgnoredForType,
|
|
871
|
-
capture: DiagnosticCode3.HtmlInputCaptureIgnoredForType
|
|
883
|
+
capture: DiagnosticCode3.HtmlInputCaptureIgnoredForType,
|
|
884
|
+
size: DiagnosticCode3.HtmlInputSizeIgnoredForType,
|
|
885
|
+
alt: DiagnosticCode3.HtmlInputAltIgnoredForType,
|
|
886
|
+
height: DiagnosticCode3.HtmlInputHeightIgnoredForType,
|
|
887
|
+
width: DiagnosticCode3.HtmlInputWidthIgnoredForType
|
|
872
888
|
};
|
|
873
889
|
var HtmlDiagnostics = {
|
|
874
890
|
emptyRole(tag) {
|
|
@@ -1102,8 +1118,132 @@ var InvariantBase = class {
|
|
|
1102
1118
|
}
|
|
1103
1119
|
};
|
|
1104
1120
|
|
|
1105
|
-
// ../../lib/contract/src/aria/
|
|
1121
|
+
// ../../lib/contract/src/aria/spec/roles/required-properties.ts
|
|
1122
|
+
var REQUIRED_ARIA_PROPERTIES = {
|
|
1123
|
+
combobox: ["aria-expanded"],
|
|
1124
|
+
option: ["aria-selected"],
|
|
1125
|
+
slider: ["aria-valuenow"],
|
|
1126
|
+
scrollbar: ["aria-controls", "aria-valuenow"],
|
|
1127
|
+
spinbutton: ["aria-valuenow"]
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
// ../../lib/contract/src/aria/spec/roles/name-required.ts
|
|
1131
|
+
var NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1132
|
+
|
|
1133
|
+
// ../../lib/contract/src/aria/spec/validators/required-properties-validator.ts
|
|
1106
1134
|
var NO_VIOLATIONS = [{ valid: true }];
|
|
1135
|
+
function requiredAttributeByRole(roles, attribute) {
|
|
1136
|
+
return Object.fromEntries([...roles].map((role) => [role, [attribute]]));
|
|
1137
|
+
}
|
|
1138
|
+
function checkRequiredAttributes(requirement, { props, effectiveRole }) {
|
|
1139
|
+
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1140
|
+
const requiredAttributes = requirement.attributesByRole[effectiveRole];
|
|
1141
|
+
if (!requiredAttributes) return NO_VIOLATIONS;
|
|
1142
|
+
const results = [];
|
|
1143
|
+
for (const attribute of requiredAttributes) {
|
|
1144
|
+
if (attribute in props) continue;
|
|
1145
|
+
results.push({
|
|
1146
|
+
valid: false,
|
|
1147
|
+
fixable: false,
|
|
1148
|
+
severity: "warning",
|
|
1149
|
+
attribute,
|
|
1150
|
+
diagnostic: requirement.diagnosticFor(attribute, effectiveRole)
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
return results;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
// ../../lib/contract/src/aria/spec/roles/live-region.ts
|
|
1157
|
+
var LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1158
|
+
["alert", "assertive"],
|
|
1159
|
+
["status", "polite"],
|
|
1160
|
+
["log", "polite"],
|
|
1161
|
+
["timer", "off"]
|
|
1162
|
+
]);
|
|
1163
|
+
var ATOMIC_REQUIREMENTS = requiredAttributeByRole(LIVE_REGION_ROLES.keys(), "aria-atomic");
|
|
1164
|
+
|
|
1165
|
+
// ../../lib/contract/src/aria/spec/attributes/aria-value-types.ts
|
|
1166
|
+
var ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1167
|
+
// Boolean (true | false)
|
|
1168
|
+
["aria-atomic", { kind: "boolean" }],
|
|
1169
|
+
["aria-busy", { kind: "boolean" }],
|
|
1170
|
+
["aria-disabled", { kind: "boolean" }],
|
|
1171
|
+
["aria-expanded", { kind: "boolean" }],
|
|
1172
|
+
["aria-hidden", { kind: "boolean" }],
|
|
1173
|
+
["aria-modal", { kind: "boolean" }],
|
|
1174
|
+
["aria-multiline", { kind: "boolean" }],
|
|
1175
|
+
["aria-multiselectable", { kind: "boolean" }],
|
|
1176
|
+
["aria-readonly", { kind: "boolean" }],
|
|
1177
|
+
["aria-required", { kind: "boolean" }],
|
|
1178
|
+
["aria-selected", { kind: "boolean" }],
|
|
1179
|
+
// Tristate (true | false | mixed)
|
|
1180
|
+
["aria-checked", { kind: "tristate" }],
|
|
1181
|
+
["aria-pressed", { kind: "tristate" }],
|
|
1182
|
+
// Numeric (any finite number)
|
|
1183
|
+
["aria-valuenow", { kind: "number" }],
|
|
1184
|
+
["aria-valuemin", { kind: "number" }],
|
|
1185
|
+
["aria-valuemax", { kind: "number" }],
|
|
1186
|
+
// Integer with optional range
|
|
1187
|
+
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1188
|
+
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1189
|
+
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1190
|
+
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1191
|
+
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1192
|
+
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1193
|
+
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1194
|
+
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1195
|
+
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1196
|
+
// Enum (specific allowed tokens)
|
|
1197
|
+
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1198
|
+
[
|
|
1199
|
+
"aria-current",
|
|
1200
|
+
{
|
|
1201
|
+
kind: "enum",
|
|
1202
|
+
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1203
|
+
}
|
|
1204
|
+
],
|
|
1205
|
+
[
|
|
1206
|
+
"aria-haspopup",
|
|
1207
|
+
{
|
|
1208
|
+
kind: "enum",
|
|
1209
|
+
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1210
|
+
}
|
|
1211
|
+
],
|
|
1212
|
+
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1213
|
+
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1214
|
+
["aria-orientation", { kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }],
|
|
1215
|
+
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1216
|
+
]);
|
|
1217
|
+
|
|
1218
|
+
// ../../lib/contract/src/aria/spec/attributes/aria-relevant-tokens.ts
|
|
1219
|
+
var VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set([
|
|
1220
|
+
"additions",
|
|
1221
|
+
"removals",
|
|
1222
|
+
"text",
|
|
1223
|
+
"all"
|
|
1224
|
+
]);
|
|
1225
|
+
|
|
1226
|
+
// ../../lib/contract/src/aria/spec/elements/heading-implicit-levels.ts
|
|
1227
|
+
var HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1228
|
+
["h1", 1],
|
|
1229
|
+
["h2", 2],
|
|
1230
|
+
["h3", 3],
|
|
1231
|
+
["h4", 4],
|
|
1232
|
+
["h5", 5],
|
|
1233
|
+
["h6", 6]
|
|
1234
|
+
]);
|
|
1235
|
+
|
|
1236
|
+
// ../../lib/contract/src/aria/spec/elements/interactive-tags.ts
|
|
1237
|
+
var INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1238
|
+
"a",
|
|
1239
|
+
"button",
|
|
1240
|
+
"input",
|
|
1241
|
+
"select",
|
|
1242
|
+
"textarea"
|
|
1243
|
+
]);
|
|
1244
|
+
|
|
1245
|
+
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
1246
|
+
var NO_VIOLATIONS2 = [{ valid: true }];
|
|
1107
1247
|
function isIntrinsicTag(tag) {
|
|
1108
1248
|
return isString(tag);
|
|
1109
1249
|
}
|
|
@@ -1146,7 +1286,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1146
1286
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
1147
1287
|
const implicitRole = getImplicitRole(tag, props);
|
|
1148
1288
|
const hasRole = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
|
|
1149
|
-
if (!hasRole) return { proceed: false, result: { props, violations: [] } };
|
|
1150
1289
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
1151
1290
|
const workingProps = normalized.normalized ? normalized.result.props : props;
|
|
1152
1291
|
const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
|
|
@@ -1156,6 +1295,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1156
1295
|
tag,
|
|
1157
1296
|
implicitRole,
|
|
1158
1297
|
effectiveRole,
|
|
1298
|
+
hasRole,
|
|
1159
1299
|
props: workingProps,
|
|
1160
1300
|
preExistingViolations,
|
|
1161
1301
|
context: { tag, props: workingProps, implicitRole, effectiveRole }
|
|
@@ -1165,6 +1305,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1165
1305
|
const violations = [];
|
|
1166
1306
|
const fixes = [];
|
|
1167
1307
|
iterate.forEach(rules, (rule) => {
|
|
1308
|
+
if (isNonNull(rule.tags) && !rule.tags.includes(context.tag)) return;
|
|
1168
1309
|
iterate.forEach(rule(context), (result) => {
|
|
1169
1310
|
if (result.valid) return;
|
|
1170
1311
|
const {
|
|
@@ -1190,7 +1331,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1190
1331
|
return { violations, fixes };
|
|
1191
1332
|
}
|
|
1192
1333
|
static #getRules(context) {
|
|
1193
|
-
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) &&
|
|
1334
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) && LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1194
1335
|
return _AriaPolicyEngine.#pipeline;
|
|
1195
1336
|
}
|
|
1196
1337
|
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
@@ -1198,6 +1339,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1198
1339
|
static evaluate(tag, props) {
|
|
1199
1340
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
1200
1341
|
if (!derived.proceed) return derived.result;
|
|
1342
|
+
if (!derived.hasRole)
|
|
1343
|
+
return { props: derived.props, violations: [...derived.preExistingViolations] };
|
|
1201
1344
|
const {
|
|
1202
1345
|
tag: narrowedTag,
|
|
1203
1346
|
implicitRole,
|
|
@@ -1222,10 +1365,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1222
1365
|
props: workingProps,
|
|
1223
1366
|
preExistingViolations
|
|
1224
1367
|
} = derived;
|
|
1225
|
-
const
|
|
1226
|
-
|
|
1227
|
-
context
|
|
1228
|
-
);
|
|
1368
|
+
const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
|
|
1369
|
+
const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
|
|
1229
1370
|
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
|
|
1230
1371
|
return { props: next, violations: [...preExistingViolations, ...violations] };
|
|
1231
1372
|
}
|
|
@@ -1392,7 +1533,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1392
1533
|
implicitRole
|
|
1393
1534
|
}) {
|
|
1394
1535
|
const role = props.role;
|
|
1395
|
-
if (!implicitRole || !role || role === implicitRole) return
|
|
1536
|
+
if (!implicitRole || !role || role === implicitRole) return NO_VIOLATIONS2;
|
|
1396
1537
|
if (isStrongImplicitRole(tag) && role === "region") {
|
|
1397
1538
|
const diagnostic = HtmlDiagnostics.implicitRoleOverride(tag, implicitRole, role);
|
|
1398
1539
|
return [
|
|
@@ -1405,11 +1546,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1405
1546
|
}
|
|
1406
1547
|
];
|
|
1407
1548
|
}
|
|
1408
|
-
return
|
|
1549
|
+
return NO_VIOLATIONS2;
|
|
1409
1550
|
}
|
|
1410
1551
|
static #checkRedundantRole({ tag, props, implicitRole }) {
|
|
1411
1552
|
const role = props.role;
|
|
1412
|
-
if (!implicitRole || !role || role !== implicitRole) return
|
|
1553
|
+
if (!implicitRole || !role || role !== implicitRole) return NO_VIOLATIONS2;
|
|
1413
1554
|
const diagnostic = HtmlDiagnostics.implicitRoleRedundant(tag, implicitRole);
|
|
1414
1555
|
return [
|
|
1415
1556
|
{
|
|
@@ -1423,8 +1564,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1423
1564
|
}
|
|
1424
1565
|
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1425
1566
|
const role = props.role;
|
|
1426
|
-
if (role !== "region") return
|
|
1427
|
-
if (!
|
|
1567
|
+
if (role !== "region") return NO_VIOLATIONS2;
|
|
1568
|
+
if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
|
|
1428
1569
|
const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
|
|
1429
1570
|
return [
|
|
1430
1571
|
{
|
|
@@ -1441,7 +1582,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1441
1582
|
props,
|
|
1442
1583
|
effectiveRole
|
|
1443
1584
|
}) {
|
|
1444
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1585
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1445
1586
|
const results = [];
|
|
1446
1587
|
iterate.forEachEntry(props, (key) => {
|
|
1447
1588
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1459,62 +1600,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1459
1600
|
return results;
|
|
1460
1601
|
}
|
|
1461
1602
|
// ─── ARIA attribute value validation ──────────────────────────────────────
|
|
1462
|
-
// Accepted value shapes for typed ARIA attributes.
|
|
1463
|
-
// Attributes not in this map are unconstrained (arbitrary string values permitted).
|
|
1464
|
-
static #ARIA_VALUE_TYPES = /* @__PURE__ */ new Map([
|
|
1465
|
-
// Boolean (true | false)
|
|
1466
|
-
["aria-atomic", { kind: "boolean" }],
|
|
1467
|
-
["aria-busy", { kind: "boolean" }],
|
|
1468
|
-
["aria-disabled", { kind: "boolean" }],
|
|
1469
|
-
["aria-expanded", { kind: "boolean" }],
|
|
1470
|
-
["aria-hidden", { kind: "boolean" }],
|
|
1471
|
-
["aria-modal", { kind: "boolean" }],
|
|
1472
|
-
["aria-multiline", { kind: "boolean" }],
|
|
1473
|
-
["aria-multiselectable", { kind: "boolean" }],
|
|
1474
|
-
["aria-readonly", { kind: "boolean" }],
|
|
1475
|
-
["aria-required", { kind: "boolean" }],
|
|
1476
|
-
["aria-selected", { kind: "boolean" }],
|
|
1477
|
-
// Tristate (true | false | mixed)
|
|
1478
|
-
["aria-checked", { kind: "tristate" }],
|
|
1479
|
-
["aria-pressed", { kind: "tristate" }],
|
|
1480
|
-
// Numeric (any finite number)
|
|
1481
|
-
["aria-valuenow", { kind: "number" }],
|
|
1482
|
-
["aria-valuemin", { kind: "number" }],
|
|
1483
|
-
["aria-valuemax", { kind: "number" }],
|
|
1484
|
-
// Integer with optional range
|
|
1485
|
-
["aria-level", { kind: "integer", min: 1, max: 6 }],
|
|
1486
|
-
["aria-posinset", { kind: "integer", min: 1 }],
|
|
1487
|
-
["aria-setsize", { kind: "integer", min: -1 }],
|
|
1488
|
-
["aria-rowcount", { kind: "integer", min: -1 }],
|
|
1489
|
-
["aria-colcount", { kind: "integer", min: -1 }],
|
|
1490
|
-
["aria-rowindex", { kind: "integer", min: 1 }],
|
|
1491
|
-
["aria-colindex", { kind: "integer", min: 1 }],
|
|
1492
|
-
["aria-rowspan", { kind: "integer", min: 0 }],
|
|
1493
|
-
["aria-colspan", { kind: "integer", min: 0 }],
|
|
1494
|
-
// Enum (specific allowed tokens)
|
|
1495
|
-
["aria-autocomplete", { kind: "enum", values: /* @__PURE__ */ new Set(["inline", "list", "both", "none"]) }],
|
|
1496
|
-
[
|
|
1497
|
-
"aria-current",
|
|
1498
|
-
{
|
|
1499
|
-
kind: "enum",
|
|
1500
|
-
values: /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"])
|
|
1501
|
-
}
|
|
1502
|
-
],
|
|
1503
|
-
[
|
|
1504
|
-
"aria-haspopup",
|
|
1505
|
-
{
|
|
1506
|
-
kind: "enum",
|
|
1507
|
-
values: /* @__PURE__ */ new Set(["false", "true", "menu", "listbox", "tree", "grid", "dialog"])
|
|
1508
|
-
}
|
|
1509
|
-
],
|
|
1510
|
-
["aria-invalid", { kind: "enum", values: /* @__PURE__ */ new Set(["grammar", "false", "spelling", "true"]) }],
|
|
1511
|
-
["aria-live", { kind: "enum", values: /* @__PURE__ */ new Set(["assertive", "off", "polite"]) }],
|
|
1512
|
-
[
|
|
1513
|
-
"aria-orientation",
|
|
1514
|
-
{ kind: "enum", values: /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]) }
|
|
1515
|
-
],
|
|
1516
|
-
["aria-sort", { kind: "enum", values: /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"]) }]
|
|
1517
|
-
]);
|
|
1518
1603
|
static #isValidAriaValue(value, type) {
|
|
1519
1604
|
switch (type.kind) {
|
|
1520
1605
|
case "boolean":
|
|
@@ -1559,11 +1644,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1559
1644
|
}
|
|
1560
1645
|
}
|
|
1561
1646
|
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1562
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1647
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1563
1648
|
const results = [];
|
|
1564
1649
|
iterate.forEachEntry(props, (key, value) => {
|
|
1565
1650
|
if (!key.startsWith("aria-")) return;
|
|
1566
|
-
const type =
|
|
1651
|
+
const type = ARIA_VALUE_TYPES.get(key);
|
|
1567
1652
|
if (!isNonNull(type)) return;
|
|
1568
1653
|
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1569
1654
|
results.push({
|
|
@@ -1582,26 +1667,18 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1582
1667
|
return results;
|
|
1583
1668
|
}
|
|
1584
1669
|
// ─── Heading implicit level ────────────────────────────────────────────────
|
|
1585
|
-
static #HEADING_IMPLICIT_LEVELS = /* @__PURE__ */ new Map([
|
|
1586
|
-
["h1", 1],
|
|
1587
|
-
["h2", 2],
|
|
1588
|
-
["h3", 3],
|
|
1589
|
-
["h4", 4],
|
|
1590
|
-
["h5", 5],
|
|
1591
|
-
["h6", 6]
|
|
1592
|
-
]);
|
|
1593
1670
|
static #checkRedundantAriaLevel({
|
|
1594
1671
|
tag,
|
|
1595
1672
|
props,
|
|
1596
1673
|
effectiveRole
|
|
1597
1674
|
}) {
|
|
1598
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1599
|
-
const implicitLevel =
|
|
1600
|
-
if (!isNonNull(implicitLevel)) return
|
|
1675
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS2;
|
|
1676
|
+
const implicitLevel = HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1677
|
+
if (!isNonNull(implicitLevel)) return NO_VIOLATIONS2;
|
|
1601
1678
|
const raw = props["aria-level"];
|
|
1602
|
-
if (!isNonNull(raw)) return
|
|
1679
|
+
if (!isNonNull(raw)) return NO_VIOLATIONS2;
|
|
1603
1680
|
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1604
|
-
if (!Number.isFinite(n) || n !== implicitLevel) return
|
|
1681
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return NO_VIOLATIONS2;
|
|
1605
1682
|
return [
|
|
1606
1683
|
{
|
|
1607
1684
|
valid: false,
|
|
@@ -1614,20 +1691,14 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1614
1691
|
];
|
|
1615
1692
|
}
|
|
1616
1693
|
// ─── Name-required roles ───────────────────────────────────────────────────
|
|
1617
|
-
// Roles that always require an accessible name per WAI-ARIA APG.
|
|
1618
|
-
// Dialog and landmark names are enforced via contracts (ariaContract) rather than
|
|
1619
|
-
// the built-in pipeline so consumers can opt in; img is built in because role=img
|
|
1620
|
-
// on any element (including bare <img>) is definitionally useless without a name.
|
|
1621
|
-
static #NAME_REQUIRED_ROLES = /* @__PURE__ */ new Set(["img"]);
|
|
1622
1694
|
static #checkNameRequiredRoles({
|
|
1623
1695
|
tag,
|
|
1624
1696
|
props,
|
|
1625
1697
|
effectiveRole
|
|
1626
1698
|
}) {
|
|
1627
|
-
if (!effectiveRole || !
|
|
1628
|
-
|
|
1629
|
-
if ("
|
|
1630
|
-
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS;
|
|
1699
|
+
if (!effectiveRole || !NAME_REQUIRED_ROLES.has(effectiveRole)) return NO_VIOLATIONS2;
|
|
1700
|
+
if ("aria-label" in props || "aria-labelledby" in props) return NO_VIOLATIONS2;
|
|
1701
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS2;
|
|
1631
1702
|
return [
|
|
1632
1703
|
{
|
|
1633
1704
|
valid: false,
|
|
@@ -1637,51 +1708,21 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1637
1708
|
}
|
|
1638
1709
|
];
|
|
1639
1710
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
["scrollbar", ["aria-controls", "aria-valuenow"]],
|
|
1647
|
-
["spinbutton", ["aria-valuenow"]]
|
|
1648
|
-
]);
|
|
1649
|
-
static #checkRequiredAriaProperties({
|
|
1650
|
-
props,
|
|
1651
|
-
effectiveRole
|
|
1652
|
-
}) {
|
|
1653
|
-
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1654
|
-
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1655
|
-
if (!isNonNull(required)) return NO_VIOLATIONS;
|
|
1656
|
-
const results = [];
|
|
1657
|
-
iterate.forEach(required, (attr) => {
|
|
1658
|
-
if (attr in props) return;
|
|
1659
|
-
results.push({
|
|
1660
|
-
valid: false,
|
|
1661
|
-
fixable: false,
|
|
1662
|
-
severity: "warning",
|
|
1663
|
-
attribute: attr,
|
|
1664
|
-
diagnostic: AriaDiagnostics.requiredProperty(attr, effectiveRole)
|
|
1665
|
-
});
|
|
1666
|
-
});
|
|
1667
|
-
return results;
|
|
1711
|
+
static #requiredAriaPropertiesRule = {
|
|
1712
|
+
attributesByRole: REQUIRED_ARIA_PROPERTIES,
|
|
1713
|
+
diagnosticFor: (attribute, role) => AriaDiagnostics.requiredProperty(attribute, role)
|
|
1714
|
+
};
|
|
1715
|
+
static #checkRequiredAriaProperties(context) {
|
|
1716
|
+
return checkRequiredAttributes(_AriaPolicyEngine.#requiredAriaPropertiesRule, context);
|
|
1668
1717
|
}
|
|
1669
|
-
// Natively interactive HTML elements — always keyboard-reachable unless explicitly disabled.
|
|
1670
|
-
static #INTERACTIVE_TAGS = /* @__PURE__ */ new Set([
|
|
1671
|
-
"a",
|
|
1672
|
-
"button",
|
|
1673
|
-
"input",
|
|
1674
|
-
"select",
|
|
1675
|
-
"textarea"
|
|
1676
|
-
]);
|
|
1677
1718
|
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1678
1719
|
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1679
|
-
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return
|
|
1680
|
-
const isInteractive =
|
|
1720
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return NO_VIOLATIONS2;
|
|
1721
|
+
const isInteractive = INTERACTIVE_TAGS.has(tag);
|
|
1681
1722
|
if (!isInteractive) {
|
|
1682
1723
|
const tabindex = props.tabindex;
|
|
1683
1724
|
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1684
|
-
if (!Number.isFinite(n) || n < 0) return
|
|
1725
|
+
if (!Number.isFinite(n) || n < 0) return NO_VIOLATIONS2;
|
|
1685
1726
|
}
|
|
1686
1727
|
return [
|
|
1687
1728
|
{
|
|
@@ -1700,7 +1741,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1700
1741
|
props,
|
|
1701
1742
|
effectiveRole
|
|
1702
1743
|
}) {
|
|
1703
|
-
if (effectiveRole !== "none" && effectiveRole !== "presentation") return
|
|
1744
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return NO_VIOLATIONS2;
|
|
1704
1745
|
const results = [];
|
|
1705
1746
|
iterate.forEachEntry(props, (key) => {
|
|
1706
1747
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1716,18 +1757,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1716
1757
|
});
|
|
1717
1758
|
return results;
|
|
1718
1759
|
}
|
|
1719
|
-
// WAI-ARIA live region roles and their implied aria-live politeness values.
|
|
1720
|
-
static #LIVE_REGION_ROLES = /* @__PURE__ */ new Map([
|
|
1721
|
-
["alert", "assertive"],
|
|
1722
|
-
["status", "polite"],
|
|
1723
|
-
["log", "polite"],
|
|
1724
|
-
["timer", "off"]
|
|
1725
|
-
]);
|
|
1726
1760
|
static #checkMissingLiveRegion({ effectiveRole, props }) {
|
|
1727
|
-
if (!effectiveRole) return
|
|
1728
|
-
const impliedLive =
|
|
1729
|
-
if (!impliedLive) return
|
|
1730
|
-
if ("aria-live" in props) return
|
|
1761
|
+
if (!effectiveRole) return NO_VIOLATIONS2;
|
|
1762
|
+
const impliedLive = LIVE_REGION_ROLES.get(effectiveRole);
|
|
1763
|
+
if (!impliedLive) return NO_VIOLATIONS2;
|
|
1764
|
+
if ("aria-live" in props) return NO_VIOLATIONS2;
|
|
1731
1765
|
const injectLive = {
|
|
1732
1766
|
kind: `injectLive:${effectiveRole}`,
|
|
1733
1767
|
apply: (ctx) => ({
|
|
@@ -1746,20 +1780,13 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1746
1780
|
}
|
|
1747
1781
|
];
|
|
1748
1782
|
}
|
|
1749
|
-
static #
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
valid: false,
|
|
1756
|
-
fixable: false,
|
|
1757
|
-
severity: "warning",
|
|
1758
|
-
diagnostic: AriaDiagnostics.missingAtomic(effectiveRole)
|
|
1759
|
-
}
|
|
1760
|
-
];
|
|
1783
|
+
static #missingAtomicRule = {
|
|
1784
|
+
attributesByRole: ATOMIC_REQUIREMENTS,
|
|
1785
|
+
diagnosticFor: (_attribute, role) => AriaDiagnostics.missingAtomic(role)
|
|
1786
|
+
};
|
|
1787
|
+
static #checkMissingAtomic(context) {
|
|
1788
|
+
return checkRequiredAttributes(_AriaPolicyEngine.#missingAtomicRule, context);
|
|
1761
1789
|
}
|
|
1762
|
-
static #VALID_RELEVANT_TOKENS = /* @__PURE__ */ new Set(["additions", "removals", "text", "all"]);
|
|
1763
1790
|
// Custom fix rules passed via `options.rules` must be pure functions of (tag, props) — the cache
|
|
1764
1791
|
// replays stored fixes against new prop objects, so fixes that close over external state will
|
|
1765
1792
|
// produce inconsistent results on cache hits.
|
|
@@ -1773,10 +1800,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1773
1800
|
};
|
|
1774
1801
|
static #checkInvalidAriaRelevant({ props }) {
|
|
1775
1802
|
const relevant = props["aria-relevant"];
|
|
1776
|
-
if (relevant === void 0) return
|
|
1777
|
-
if (typeof relevant !== "string") return
|
|
1803
|
+
if (relevant === void 0) return NO_VIOLATIONS2;
|
|
1804
|
+
if (typeof relevant !== "string") return NO_VIOLATIONS2;
|
|
1778
1805
|
const tokens = relevant.trim().split(/\s+/);
|
|
1779
|
-
const invalid = tokens.filter((t) => !
|
|
1806
|
+
const invalid = tokens.filter((t) => !VALID_RELEVANT_TOKENS.has(t));
|
|
1780
1807
|
if (invalid.length > 0) {
|
|
1781
1808
|
return [
|
|
1782
1809
|
{
|
|
@@ -1801,7 +1828,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1801
1828
|
}
|
|
1802
1829
|
];
|
|
1803
1830
|
}
|
|
1804
|
-
return
|
|
1831
|
+
return NO_VIOLATIONS2;
|
|
1805
1832
|
}
|
|
1806
1833
|
};
|
|
1807
1834
|
|
|
@@ -2121,7 +2148,59 @@ var readonlyProps = ({
|
|
|
2121
2148
|
// ../core/src/html/evaluators.ts
|
|
2122
2149
|
import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
|
|
2123
2150
|
|
|
2124
|
-
// ../core/src/html/input
|
|
2151
|
+
// ../core/src/html/spec/vocabulary/input.ts
|
|
2152
|
+
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2153
|
+
var NUMERIC_INPUT_TYPES = [
|
|
2154
|
+
"number",
|
|
2155
|
+
"range",
|
|
2156
|
+
"date",
|
|
2157
|
+
"month",
|
|
2158
|
+
"week",
|
|
2159
|
+
"time",
|
|
2160
|
+
"datetime-local"
|
|
2161
|
+
];
|
|
2162
|
+
var HTML_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
2163
|
+
...TEXT_INPUT_TYPES,
|
|
2164
|
+
...NUMERIC_INPUT_TYPES,
|
|
2165
|
+
"checkbox",
|
|
2166
|
+
"radio",
|
|
2167
|
+
"file",
|
|
2168
|
+
"color",
|
|
2169
|
+
"hidden",
|
|
2170
|
+
"button",
|
|
2171
|
+
"submit",
|
|
2172
|
+
"reset",
|
|
2173
|
+
"image"
|
|
2174
|
+
]);
|
|
2175
|
+
|
|
2176
|
+
// ../core/src/html/spec/attributes/input.ts
|
|
2177
|
+
var INPUT_ATTRIBUTE_TYPE_POLICIES = [
|
|
2178
|
+
{ attribute: "checked", allowedTypes: ["checkbox", "radio"] },
|
|
2179
|
+
{ attribute: "multiple", allowedTypes: ["email", "file"] },
|
|
2180
|
+
{ attribute: "maxLength", allowedTypes: TEXT_INPUT_TYPES },
|
|
2181
|
+
{ attribute: "minLength", allowedTypes: TEXT_INPUT_TYPES },
|
|
2182
|
+
{ attribute: "pattern", allowedTypes: TEXT_INPUT_TYPES },
|
|
2183
|
+
{ attribute: "min", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2184
|
+
{ attribute: "max", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2185
|
+
{ attribute: "step", allowedTypes: NUMERIC_INPUT_TYPES },
|
|
2186
|
+
{ attribute: "accept", allowedTypes: ["file"] },
|
|
2187
|
+
{ attribute: "capture", allowedTypes: ["file"] },
|
|
2188
|
+
{ attribute: "size", allowedTypes: TEXT_INPUT_TYPES },
|
|
2189
|
+
{ attribute: "alt", allowedTypes: ["image"] },
|
|
2190
|
+
{ attribute: "height", allowedTypes: ["image"] },
|
|
2191
|
+
{ attribute: "width", allowedTypes: ["image"] }
|
|
2192
|
+
];
|
|
2193
|
+
|
|
2194
|
+
// ../core/src/html/spec/constraints/input.ts
|
|
2195
|
+
var REQUIRED_READONLY_CONFLICT = {
|
|
2196
|
+
props: ["required", "readOnly"],
|
|
2197
|
+
diagnostic: () => InputAccessibilityDiagnostics.requiredReadOnlyConflict()
|
|
2198
|
+
};
|
|
2199
|
+
var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
|
|
2200
|
+
REQUIRED_READONLY_CONFLICT
|
|
2201
|
+
];
|
|
2202
|
+
|
|
2203
|
+
// ../core/src/html/spec/validators/attribute-type-validator.ts
|
|
2125
2204
|
var DEFAULT_INPUT_TYPE = "text";
|
|
2126
2205
|
function omit(props, key) {
|
|
2127
2206
|
const next = { ...props };
|
|
@@ -2137,7 +2216,10 @@ function removeAttributeFix(attribute) {
|
|
|
2137
2216
|
}
|
|
2138
2217
|
};
|
|
2139
2218
|
}
|
|
2140
|
-
function
|
|
2219
|
+
function createInputAttributeTypeRule({
|
|
2220
|
+
attribute,
|
|
2221
|
+
allowedTypes
|
|
2222
|
+
}) {
|
|
2141
2223
|
const rule = ({ tag, props }) => {
|
|
2142
2224
|
if (tag !== "input" || !(attribute in props)) return [];
|
|
2143
2225
|
const type = typeof props.type === "string" ? props.type : DEFAULT_INPUT_TYPE;
|
|
@@ -2153,31 +2235,30 @@ function inputAttributeRequiresType(attribute, allowedTypes) {
|
|
|
2153
2235
|
}
|
|
2154
2236
|
];
|
|
2155
2237
|
};
|
|
2156
|
-
return Object.assign(rule, { readsProps: ["type", attribute] });
|
|
2238
|
+
return Object.assign(rule, { readsProps: ["type", attribute], tags: ["input"] });
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2241
|
+
// ../core/src/html/spec/validators/mutually-exclusive-validator.ts
|
|
2242
|
+
function createMutuallyExclusiveRule({
|
|
2243
|
+
props: conflictingProps,
|
|
2244
|
+
diagnostic: createDiagnostic
|
|
2245
|
+
}) {
|
|
2246
|
+
const [first, second] = conflictingProps;
|
|
2247
|
+
const rule = ({ tag, props }) => {
|
|
2248
|
+
if (tag !== "input" || !props[first] || !props[second]) return [];
|
|
2249
|
+
const diagnostic = createDiagnostic();
|
|
2250
|
+
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2251
|
+
};
|
|
2252
|
+
return Object.assign(rule, { readsProps: conflictingProps, tags: ["input"] });
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
// ../core/src/html/input-rules.ts
|
|
2256
|
+
var policyByAttribute = Object.fromEntries(
|
|
2257
|
+
INPUT_ATTRIBUTE_TYPE_POLICIES.map((policy) => [policy.attribute, policy])
|
|
2258
|
+
);
|
|
2259
|
+
function policyFor(attribute) {
|
|
2260
|
+
return policyByAttribute[attribute];
|
|
2157
2261
|
}
|
|
2158
|
-
var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
|
|
2159
|
-
var NUMERIC_INPUT_TYPES = [
|
|
2160
|
-
"number",
|
|
2161
|
-
"range",
|
|
2162
|
-
"date",
|
|
2163
|
-
"month",
|
|
2164
|
-
"week",
|
|
2165
|
-
"time",
|
|
2166
|
-
"datetime-local"
|
|
2167
|
-
];
|
|
2168
|
-
var HTML_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
2169
|
-
...TEXT_INPUT_TYPES,
|
|
2170
|
-
...NUMERIC_INPUT_TYPES,
|
|
2171
|
-
"checkbox",
|
|
2172
|
-
"radio",
|
|
2173
|
-
"file",
|
|
2174
|
-
"color",
|
|
2175
|
-
"hidden",
|
|
2176
|
-
"button",
|
|
2177
|
-
"submit",
|
|
2178
|
-
"reset",
|
|
2179
|
-
"image"
|
|
2180
|
-
]);
|
|
2181
2262
|
var supportedInputTypeRule = Object.assign(
|
|
2182
2263
|
({ tag, props }) => {
|
|
2183
2264
|
if (tag !== "input" || typeof props.type !== "string") return [];
|
|
@@ -2193,30 +2274,22 @@ var supportedInputTypeRule = Object.assign(
|
|
|
2193
2274
|
}
|
|
2194
2275
|
];
|
|
2195
2276
|
},
|
|
2196
|
-
{ readsProps: ["type"] }
|
|
2197
|
-
);
|
|
2198
|
-
var checkedRequiresCheckableTypeRule = inputAttributeRequiresType("checked", [
|
|
2199
|
-
"checkbox",
|
|
2200
|
-
"radio"
|
|
2201
|
-
]);
|
|
2202
|
-
var multipleRequiresSupportedTypeRule = inputAttributeRequiresType("multiple", [
|
|
2203
|
-
"email",
|
|
2204
|
-
"file"
|
|
2205
|
-
]);
|
|
2206
|
-
var maxLengthRequiresTextTypeRule = inputAttributeRequiresType(
|
|
2207
|
-
"maxLength",
|
|
2208
|
-
TEXT_INPUT_TYPES
|
|
2209
|
-
);
|
|
2210
|
-
var minLengthRequiresTextTypeRule = inputAttributeRequiresType(
|
|
2211
|
-
"minLength",
|
|
2212
|
-
TEXT_INPUT_TYPES
|
|
2277
|
+
{ readsProps: ["type"], tags: ["input"] }
|
|
2213
2278
|
);
|
|
2214
|
-
var
|
|
2215
|
-
var
|
|
2216
|
-
var
|
|
2217
|
-
var
|
|
2218
|
-
var
|
|
2219
|
-
var
|
|
2279
|
+
var checkedRequiresCheckableTypeRule = createInputAttributeTypeRule(policyFor("checked"));
|
|
2280
|
+
var multipleRequiresSupportedTypeRule = createInputAttributeTypeRule(policyFor("multiple"));
|
|
2281
|
+
var maxLengthRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("maxLength"));
|
|
2282
|
+
var minLengthRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("minLength"));
|
|
2283
|
+
var patternRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("pattern"));
|
|
2284
|
+
var minRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("min"));
|
|
2285
|
+
var maxRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("max"));
|
|
2286
|
+
var stepRequiresNumericTypeRule = createInputAttributeTypeRule(policyFor("step"));
|
|
2287
|
+
var acceptRequiresFileTypeRule = createInputAttributeTypeRule(policyFor("accept"));
|
|
2288
|
+
var captureRequiresFileTypeRule = createInputAttributeTypeRule(policyFor("capture"));
|
|
2289
|
+
var sizeRequiresTextTypeRule = createInputAttributeTypeRule(policyFor("size"));
|
|
2290
|
+
var altRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("alt"));
|
|
2291
|
+
var heightRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("height"));
|
|
2292
|
+
var widthRequiresImageTypeRule = createInputAttributeTypeRule(policyFor("width"));
|
|
2220
2293
|
var inputAccessibleNameRule = Object.assign(
|
|
2221
2294
|
({ tag, props }) => {
|
|
2222
2295
|
if (tag !== "input" || props.type === "hidden") return [];
|
|
@@ -2225,7 +2298,10 @@ var inputAccessibleNameRule = Object.assign(
|
|
|
2225
2298
|
const diagnostic = hasPlaceholder ? InputAccessibilityDiagnostics.placeholderIsNotLabel() : InputAccessibilityDiagnostics.missingAccessibleName();
|
|
2226
2299
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2227
2300
|
},
|
|
2228
|
-
{
|
|
2301
|
+
{
|
|
2302
|
+
readsProps: ["type", "aria-label", "aria-labelledby", "placeholder"],
|
|
2303
|
+
tags: ["input"]
|
|
2304
|
+
}
|
|
2229
2305
|
);
|
|
2230
2306
|
var PASSWORD_AUTOCOMPLETE_VALUES = ["current-password", "new-password"];
|
|
2231
2307
|
var passwordAutocompleteRule = Object.assign(
|
|
@@ -2237,16 +2313,9 @@ var passwordAutocompleteRule = Object.assign(
|
|
|
2237
2313
|
const diagnostic = InputAccessibilityDiagnostics.passwordMissingAutocomplete();
|
|
2238
2314
|
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2239
2315
|
},
|
|
2240
|
-
{ readsProps: ["type", "autoComplete"] }
|
|
2241
|
-
);
|
|
2242
|
-
var requiredReadOnlyConflictRule = Object.assign(
|
|
2243
|
-
({ tag, props }) => {
|
|
2244
|
-
if (tag !== "input" || !props.required || !props.readOnly) return [];
|
|
2245
|
-
const diagnostic = InputAccessibilityDiagnostics.requiredReadOnlyConflict();
|
|
2246
|
-
return [{ valid: false, fixable: false, severity: diagnostic.severity, diagnostic }];
|
|
2247
|
-
},
|
|
2248
|
-
{ readsProps: ["required", "readOnly"] }
|
|
2316
|
+
{ readsProps: ["type", "autoComplete"], tags: ["input"] }
|
|
2249
2317
|
);
|
|
2318
|
+
var requiredReadOnlyConflictRule = createMutuallyExclusiveRule(REQUIRED_READONLY_CONFLICT);
|
|
2250
2319
|
var INPUT_RULES = [
|
|
2251
2320
|
supportedInputTypeRule,
|
|
2252
2321
|
checkedRequiresCheckableTypeRule,
|
|
@@ -2259,11 +2328,132 @@ var INPUT_RULES = [
|
|
|
2259
2328
|
stepRequiresNumericTypeRule,
|
|
2260
2329
|
acceptRequiresFileTypeRule,
|
|
2261
2330
|
captureRequiresFileTypeRule,
|
|
2331
|
+
sizeRequiresTextTypeRule,
|
|
2332
|
+
altRequiresImageTypeRule,
|
|
2333
|
+
heightRequiresImageTypeRule,
|
|
2334
|
+
widthRequiresImageTypeRule,
|
|
2262
2335
|
inputAccessibleNameRule,
|
|
2263
2336
|
passwordAutocompleteRule,
|
|
2264
2337
|
requiredReadOnlyConflictRule
|
|
2265
2338
|
];
|
|
2266
2339
|
|
|
2340
|
+
// ../core/src/html/spec/types.ts
|
|
2341
|
+
function definePropRolePolicy(prop, map2, fallback) {
|
|
2342
|
+
return { kind: "byProp", prop, map: map2, fallback };
|
|
2343
|
+
}
|
|
2344
|
+
function resolveAllowedRoles(spec, props) {
|
|
2345
|
+
const policy = spec.allowedRoles;
|
|
2346
|
+
if (!policy) return void 0;
|
|
2347
|
+
switch (policy.kind) {
|
|
2348
|
+
case "fixed":
|
|
2349
|
+
return policy.roles;
|
|
2350
|
+
case "byProp": {
|
|
2351
|
+
const value = typeof props[policy.prop] === "string" ? props[policy.prop] : policy.fallback;
|
|
2352
|
+
return policy.map[value];
|
|
2353
|
+
}
|
|
2354
|
+
case "dynamic":
|
|
2355
|
+
return policy.resolve({ props });
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
// ../core/src/html/spec/roles/input.ts
|
|
2360
|
+
var ALLOWED_INPUT_ROLES = {
|
|
2361
|
+
checkbox: ["menuitemcheckbox", "option", "switch", "button"],
|
|
2362
|
+
radio: ["menuitemradio"],
|
|
2363
|
+
range: [],
|
|
2364
|
+
number: [],
|
|
2365
|
+
search: ["combobox"],
|
|
2366
|
+
text: ["combobox", "searchbox", "spinbutton"],
|
|
2367
|
+
email: ["combobox"],
|
|
2368
|
+
tel: ["combobox"],
|
|
2369
|
+
url: ["combobox"],
|
|
2370
|
+
button: [
|
|
2371
|
+
"link",
|
|
2372
|
+
"menuitem",
|
|
2373
|
+
"menuitemcheckbox",
|
|
2374
|
+
"menuitemradio",
|
|
2375
|
+
"option",
|
|
2376
|
+
"radio",
|
|
2377
|
+
"switch",
|
|
2378
|
+
"tab"
|
|
2379
|
+
],
|
|
2380
|
+
submit: [
|
|
2381
|
+
"link",
|
|
2382
|
+
"menuitem",
|
|
2383
|
+
"menuitemcheckbox",
|
|
2384
|
+
"menuitemradio",
|
|
2385
|
+
"option",
|
|
2386
|
+
"radio",
|
|
2387
|
+
"switch",
|
|
2388
|
+
"tab"
|
|
2389
|
+
],
|
|
2390
|
+
reset: [
|
|
2391
|
+
"link",
|
|
2392
|
+
"menuitem",
|
|
2393
|
+
"menuitemcheckbox",
|
|
2394
|
+
"menuitemradio",
|
|
2395
|
+
"option",
|
|
2396
|
+
"radio",
|
|
2397
|
+
"switch",
|
|
2398
|
+
"tab"
|
|
2399
|
+
],
|
|
2400
|
+
image: [
|
|
2401
|
+
"link",
|
|
2402
|
+
"menuitem",
|
|
2403
|
+
"menuitemcheckbox",
|
|
2404
|
+
"menuitemradio",
|
|
2405
|
+
"option",
|
|
2406
|
+
"radio",
|
|
2407
|
+
"switch",
|
|
2408
|
+
"tab"
|
|
2409
|
+
],
|
|
2410
|
+
hidden: []
|
|
2411
|
+
};
|
|
2412
|
+
|
|
2413
|
+
// ../core/src/html/spec/elements/input.ts
|
|
2414
|
+
var inputElementSpec = {
|
|
2415
|
+
tag: "input",
|
|
2416
|
+
allowedRoles: definePropRolePolicy("type", ALLOWED_INPUT_ROLES, "text"),
|
|
2417
|
+
attributes: INPUT_ATTRIBUTE_TYPE_POLICIES,
|
|
2418
|
+
mutuallyExclusive: INPUT_MUTUALLY_EXCLUSIVE_POLICIES
|
|
2419
|
+
};
|
|
2420
|
+
|
|
2421
|
+
// ../core/src/html/spec/roles/img.ts
|
|
2422
|
+
var IMG_NAMED_ROLES = [
|
|
2423
|
+
"button",
|
|
2424
|
+
"checkbox",
|
|
2425
|
+
"link",
|
|
2426
|
+
"menuitem",
|
|
2427
|
+
"menuitemcheckbox",
|
|
2428
|
+
"menuitemradio",
|
|
2429
|
+
"option",
|
|
2430
|
+
"progressbar",
|
|
2431
|
+
"scrollbar",
|
|
2432
|
+
"separator",
|
|
2433
|
+
"slider",
|
|
2434
|
+
"switch",
|
|
2435
|
+
"tab",
|
|
2436
|
+
"treeitem"
|
|
2437
|
+
];
|
|
2438
|
+
|
|
2439
|
+
// ../core/src/html/spec/elements/img.ts
|
|
2440
|
+
var imgElementSpec = {
|
|
2441
|
+
tag: "img",
|
|
2442
|
+
allowedRoles: {
|
|
2443
|
+
kind: "dynamic",
|
|
2444
|
+
resolve: ({ props }) => props.alt === "" ? [] : IMG_NAMED_ROLES
|
|
2445
|
+
}
|
|
2446
|
+
};
|
|
2447
|
+
|
|
2448
|
+
// ../core/src/html/spec/roles/table.ts
|
|
2449
|
+
var ALLOWED_TABLE_ROLES = ["grid", "treegrid"];
|
|
2450
|
+
|
|
2451
|
+
// ../core/src/html/spec/elements/table.ts
|
|
2452
|
+
var tableElementSpec = {
|
|
2453
|
+
tag: "table",
|
|
2454
|
+
allowedRoles: { kind: "fixed", roles: ALLOWED_TABLE_ROLES }
|
|
2455
|
+
};
|
|
2456
|
+
|
|
2267
2457
|
// ../core/src/html/role-restrictions.ts
|
|
2268
2458
|
var ALLOWED_ROLES = {
|
|
2269
2459
|
article: ["application", "document", "feed", "main", "none", "presentation", "region"],
|
|
@@ -2336,86 +2526,17 @@ var ALLOWED_ROLES = {
|
|
|
2336
2526
|
"tab",
|
|
2337
2527
|
"treeitem"
|
|
2338
2528
|
],
|
|
2339
|
-
table: ["grid", "treegrid"],
|
|
2340
2529
|
dialog: ["alertdialog"],
|
|
2341
2530
|
fieldset: ["none", "presentation", "radiogroup"]
|
|
2342
2531
|
};
|
|
2343
|
-
var
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
"menuitem",
|
|
2348
|
-
"menuitemcheckbox",
|
|
2349
|
-
"menuitemradio",
|
|
2350
|
-
"option",
|
|
2351
|
-
"progressbar",
|
|
2352
|
-
"scrollbar",
|
|
2353
|
-
"separator",
|
|
2354
|
-
"slider",
|
|
2355
|
-
"switch",
|
|
2356
|
-
"tab",
|
|
2357
|
-
"treeitem"
|
|
2358
|
-
];
|
|
2359
|
-
var ALLOWED_INPUT_ROLES = {
|
|
2360
|
-
checkbox: ["menuitemcheckbox", "option", "switch", "button"],
|
|
2361
|
-
radio: ["menuitemradio"],
|
|
2362
|
-
range: [],
|
|
2363
|
-
number: [],
|
|
2364
|
-
search: ["combobox"],
|
|
2365
|
-
text: ["combobox", "searchbox", "spinbutton"],
|
|
2366
|
-
email: ["combobox"],
|
|
2367
|
-
tel: ["combobox"],
|
|
2368
|
-
url: ["combobox"],
|
|
2369
|
-
button: [
|
|
2370
|
-
"link",
|
|
2371
|
-
"menuitem",
|
|
2372
|
-
"menuitemcheckbox",
|
|
2373
|
-
"menuitemradio",
|
|
2374
|
-
"option",
|
|
2375
|
-
"radio",
|
|
2376
|
-
"switch",
|
|
2377
|
-
"tab"
|
|
2378
|
-
],
|
|
2379
|
-
submit: [
|
|
2380
|
-
"link",
|
|
2381
|
-
"menuitem",
|
|
2382
|
-
"menuitemcheckbox",
|
|
2383
|
-
"menuitemradio",
|
|
2384
|
-
"option",
|
|
2385
|
-
"radio",
|
|
2386
|
-
"switch",
|
|
2387
|
-
"tab"
|
|
2388
|
-
],
|
|
2389
|
-
reset: [
|
|
2390
|
-
"link",
|
|
2391
|
-
"menuitem",
|
|
2392
|
-
"menuitemcheckbox",
|
|
2393
|
-
"menuitemradio",
|
|
2394
|
-
"option",
|
|
2395
|
-
"radio",
|
|
2396
|
-
"switch",
|
|
2397
|
-
"tab"
|
|
2398
|
-
],
|
|
2399
|
-
image: [
|
|
2400
|
-
"link",
|
|
2401
|
-
"menuitem",
|
|
2402
|
-
"menuitemcheckbox",
|
|
2403
|
-
"menuitemradio",
|
|
2404
|
-
"option",
|
|
2405
|
-
"radio",
|
|
2406
|
-
"switch",
|
|
2407
|
-
"tab"
|
|
2408
|
-
],
|
|
2409
|
-
hidden: []
|
|
2532
|
+
var ELEMENT_SPECS = {
|
|
2533
|
+
input: inputElementSpec,
|
|
2534
|
+
img: imgElementSpec,
|
|
2535
|
+
table: tableElementSpec
|
|
2410
2536
|
};
|
|
2411
2537
|
function getAllowedRoles(tag, props) {
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
return ALLOWED_INPUT_ROLES[type];
|
|
2415
|
-
}
|
|
2416
|
-
if (tag === "img") {
|
|
2417
|
-
return props.alt === "" ? [] : IMG_NAMED_ROLES;
|
|
2418
|
-
}
|
|
2538
|
+
const spec = ELEMENT_SPECS[tag];
|
|
2539
|
+
if (spec) return resolveAllowedRoles(spec, props);
|
|
2419
2540
|
return ALLOWED_ROLES[tag];
|
|
2420
2541
|
}
|
|
2421
2542
|
var removeRoleFix = {
|
|
@@ -2456,21 +2577,24 @@ var removeLandmarkRoleOverride = {
|
|
|
2456
2577
|
return { applied: true, next: rest, previous: props };
|
|
2457
2578
|
}
|
|
2458
2579
|
};
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2580
|
+
var landmarkRoleRule = Object.assign(
|
|
2581
|
+
({ tag, props, implicitRole }) => {
|
|
2582
|
+
if (!LANDMARK_TAG_SET.has(tag) || !implicitRole) return [];
|
|
2583
|
+
const role = props.role;
|
|
2584
|
+
if (!role || role === implicitRole) return [];
|
|
2585
|
+
const diagnostic = HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role);
|
|
2586
|
+
return [
|
|
2587
|
+
{
|
|
2588
|
+
valid: false,
|
|
2589
|
+
fixable: true,
|
|
2590
|
+
severity: diagnostic.severity,
|
|
2591
|
+
fix: removeLandmarkRoleOverride,
|
|
2592
|
+
diagnostic
|
|
2593
|
+
}
|
|
2594
|
+
];
|
|
2595
|
+
},
|
|
2596
|
+
{ tags: [...LANDMARK_TAG_SET] }
|
|
2597
|
+
);
|
|
2474
2598
|
function requireAccessibleName({ tag, props }) {
|
|
2475
2599
|
if ("aria-label" in props || "aria-labelledby" in props) return [];
|
|
2476
2600
|
return [
|
|
@@ -2483,10 +2607,13 @@ function requireAccessibleName({ tag, props }) {
|
|
|
2483
2607
|
];
|
|
2484
2608
|
}
|
|
2485
2609
|
var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2610
|
+
var landmarkNameAdvisory = Object.assign(
|
|
2611
|
+
(ctx) => {
|
|
2612
|
+
if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
|
|
2613
|
+
return requireAccessibleName(ctx);
|
|
2614
|
+
},
|
|
2615
|
+
{ tags: [...NAMED_LANDMARK_TAGS] }
|
|
2616
|
+
);
|
|
2490
2617
|
var HTML_ARIA_RULES = [
|
|
2491
2618
|
landmarkRoleRule,
|
|
2492
2619
|
landmarkNameAdvisory,
|
|
@@ -2587,6 +2714,62 @@ var figureContract = contract([
|
|
|
2587
2714
|
]);
|
|
2588
2715
|
var detailsContract = firstChildContract("summary", "summary");
|
|
2589
2716
|
var fieldsetContract = firstChildContract("legend", "legend");
|
|
2717
|
+
var objectContract = contract([
|
|
2718
|
+
{ name: "param", match: isTag("param") },
|
|
2719
|
+
{ name: "content", match: isOpenContent("param") }
|
|
2720
|
+
]);
|
|
2721
|
+
var INTERACTIVE_CONTENT_TAGS = ["a", "button", "input", "select", "textarea", "label"];
|
|
2722
|
+
var buttonContract = closedContract([
|
|
2723
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2724
|
+
]);
|
|
2725
|
+
var anchorContract = closedContract([
|
|
2726
|
+
{ name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
|
|
2727
|
+
]);
|
|
2728
|
+
var LABELABLE_TAGS = [
|
|
2729
|
+
"button",
|
|
2730
|
+
"input",
|
|
2731
|
+
"meter",
|
|
2732
|
+
"output",
|
|
2733
|
+
"progress",
|
|
2734
|
+
"select",
|
|
2735
|
+
"textarea"
|
|
2736
|
+
];
|
|
2737
|
+
var labelContract = contract([
|
|
2738
|
+
{ name: "control", match: isTag(...LABELABLE_TAGS), cardinality: { max: 1 } }
|
|
2739
|
+
]);
|
|
2740
|
+
var P_BLOCKED_TAGS = [
|
|
2741
|
+
"address",
|
|
2742
|
+
"article",
|
|
2743
|
+
"aside",
|
|
2744
|
+
"blockquote",
|
|
2745
|
+
"details",
|
|
2746
|
+
"dialog",
|
|
2747
|
+
"div",
|
|
2748
|
+
"dl",
|
|
2749
|
+
"fieldset",
|
|
2750
|
+
"figure",
|
|
2751
|
+
"footer",
|
|
2752
|
+
"form",
|
|
2753
|
+
"h1",
|
|
2754
|
+
"h2",
|
|
2755
|
+
"h3",
|
|
2756
|
+
"h4",
|
|
2757
|
+
"h5",
|
|
2758
|
+
"h6",
|
|
2759
|
+
"header",
|
|
2760
|
+
"hr",
|
|
2761
|
+
"main",
|
|
2762
|
+
"nav",
|
|
2763
|
+
"ol",
|
|
2764
|
+
"p",
|
|
2765
|
+
"pre",
|
|
2766
|
+
"section",
|
|
2767
|
+
"table",
|
|
2768
|
+
"ul"
|
|
2769
|
+
];
|
|
2770
|
+
var pContract = closedContract([
|
|
2771
|
+
{ name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
|
|
2772
|
+
]);
|
|
2590
2773
|
var mediaContract = contract([
|
|
2591
2774
|
{ name: "source", match: isTag("source") },
|
|
2592
2775
|
{ name: "track", match: isTag("track") },
|
|
@@ -2641,6 +2824,11 @@ var htmlContracts = {
|
|
|
2641
2824
|
details: detailsContract,
|
|
2642
2825
|
fieldset: fieldsetContract,
|
|
2643
2826
|
dialog: dialogContract,
|
|
2827
|
+
object: objectContract,
|
|
2828
|
+
button: buttonContract,
|
|
2829
|
+
a: anchorContract,
|
|
2830
|
+
label: labelContract,
|
|
2831
|
+
p: pContract,
|
|
2644
2832
|
head: headContract,
|
|
2645
2833
|
html: htmlContract
|
|
2646
2834
|
};
|
|
@@ -2867,6 +3055,11 @@ function composeNormalizers(normalizers, fn) {
|
|
|
2867
3055
|
function whenDefined(key, value) {
|
|
2868
3056
|
return value === void 0 ? {} : { [key]: value };
|
|
2869
3057
|
}
|
|
3058
|
+
function mergeAriaRules(aria, rules) {
|
|
3059
|
+
if (!aria?.length) return rules;
|
|
3060
|
+
if (!rules?.length) return aria;
|
|
3061
|
+
return [...aria, ...rules];
|
|
3062
|
+
}
|
|
2870
3063
|
function resolveFactoryOptions(options = {}) {
|
|
2871
3064
|
const { styling, enforcement } = options;
|
|
2872
3065
|
const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
|
|
@@ -2887,7 +3080,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
2887
3080
|
...whenDefined("defaultVariants", styling?.defaults),
|
|
2888
3081
|
...whenDefined("compoundVariants", styling?.compounds),
|
|
2889
3082
|
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
2890
|
-
...whenDefined("ariaRules", enforcement?.aria),
|
|
3083
|
+
...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
|
|
2891
3084
|
...whenDefined("childRules", enforcement?.children),
|
|
2892
3085
|
...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
|
|
2893
3086
|
...whenDefined("allowText", enforcement?.allowText),
|