@markuplint/rules 3.0.0-canary.3 → 3.0.0-dev.177

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.
Files changed (163) hide show
  1. package/README.md +1 -1
  2. package/lib/attr-check.d.ts +20 -8
  3. package/lib/attr-check.js +31 -22
  4. package/lib/attr-duplication/index.d.ts +3 -1
  5. package/lib/attr-duplication/index.js +2 -1
  6. package/lib/attr-value-quotes/index.d.ts +2 -2
  7. package/lib/case-sensitive-attr-name/index.d.ts +1 -1
  8. package/lib/case-sensitive-tag-name/index.d.ts +1 -1
  9. package/lib/character-reference/index.d.ts +1 -1
  10. package/lib/class-naming/index.d.ts +1 -1
  11. package/lib/class-naming/index.js +2 -4
  12. package/lib/create-message.d.ts +13 -2
  13. package/lib/create-message.js +4 -3
  14. package/lib/debug.js +1 -1
  15. package/lib/deprecated-attr/index.d.ts +3 -1
  16. package/lib/deprecated-element/index.d.ts +3 -1
  17. package/lib/deprecated-element/index.js +2 -2
  18. package/lib/disallowed-element/index.d.ts +1 -1
  19. package/lib/doctype/index.d.ts +2 -2
  20. package/lib/end-tag/index.d.ts +1 -1
  21. package/lib/helpers.d.ts +37 -22
  22. package/lib/helpers.js +27 -14
  23. package/lib/id-duplication/index.d.ts +3 -1
  24. package/lib/index.d.ts +243 -3
  25. package/lib/index.js +6 -1
  26. package/lib/ineffective-attr/index.d.ts +3 -1
  27. package/lib/ineffective-attr/index.js +2 -5
  28. package/lib/invalid-attr/index.d.ts +39 -12
  29. package/lib/invalid-attr/index.js +153 -27
  30. package/lib/label-has-control/index.d.ts +3 -1
  31. package/lib/landmark-roles/index.d.ts +3 -3
  32. package/lib/landmark-roles/index.js +9 -5
  33. package/lib/no-boolean-attr-value/index.d.ts +3 -1
  34. package/lib/no-default-value/index.d.ts +3 -1
  35. package/lib/no-empty-palpable-content/index.d.ts +3 -3
  36. package/lib/no-empty-palpable-content/index.js +11 -3
  37. package/lib/no-hard-code-id/index.d.ts +3 -1
  38. package/lib/no-refer-to-non-existent-id/index.d.ts +9 -4
  39. package/lib/no-refer-to-non-existent-id/index.js +65 -5
  40. package/lib/no-use-event-handler-attr/index.d.ts +2 -2
  41. package/lib/no-use-event-handler-attr/index.js +4 -4
  42. package/lib/permitted-contents/choice.d.ts +8 -1
  43. package/lib/permitted-contents/choice.js +37 -2
  44. package/lib/permitted-contents/complex-branch.d.ts +8 -1
  45. package/lib/permitted-contents/complex-branch.js +4 -2
  46. package/lib/permitted-contents/content-model.d.ts +1 -1
  47. package/lib/permitted-contents/content-model.js +7 -3
  48. package/lib/permitted-contents/count-pattern.d.ts +18 -2
  49. package/lib/permitted-contents/count-pattern.js +71 -64
  50. package/lib/permitted-contents/debug.browser.d.ts +30 -0
  51. package/lib/permitted-contents/debug.browser.js +14 -0
  52. package/lib/permitted-contents/debug.d.ts +2 -1
  53. package/lib/permitted-contents/debug.js +9 -1
  54. package/lib/permitted-contents/index.d.ts +1 -1
  55. package/lib/permitted-contents/index.js +12 -15
  56. package/lib/permitted-contents/matches-selector.d.ts +7 -2
  57. package/lib/permitted-contents/matches-selector.js +8 -6
  58. package/lib/permitted-contents/order.d.ts +8 -1
  59. package/lib/permitted-contents/order.js +25 -15
  60. package/lib/permitted-contents/recursive-branch.d.ts +8 -1
  61. package/lib/permitted-contents/recursive-branch.js +5 -3
  62. package/lib/permitted-contents/represent-transparent-nodes.d.ts +7 -3
  63. package/lib/permitted-contents/represent-transparent-nodes.js +4 -5
  64. package/lib/permitted-contents/start.d.ts +7 -1
  65. package/lib/permitted-contents/start.js +5 -3
  66. package/lib/permitted-contents/transparent.d.ts +2 -2
  67. package/lib/permitted-contents/transparent.js +11 -14
  68. package/lib/permitted-contents/types.d.ts +35 -28
  69. package/lib/permitted-contents/utils.d.ts +96 -28
  70. package/lib/permitted-contents/utils.js +135 -17
  71. package/lib/placeholder-label-option/index.d.ts +2 -0
  72. package/lib/placeholder-label-option/index.js +88 -0
  73. package/lib/require-accessible-name/index.d.ts +2 -2
  74. package/lib/require-accessible-name/index.js +5 -5
  75. package/lib/require-datetime/index.d.ts +6 -0
  76. package/lib/require-datetime/index.js +34 -0
  77. package/lib/require-datetime/types.d.ts +10 -0
  78. package/lib/require-datetime/types.js +2 -0
  79. package/lib/require-datetime/utils.d.ts +11 -0
  80. package/lib/require-datetime/utils.js +137 -0
  81. package/lib/required-attr/index.d.ts +3 -3
  82. package/lib/required-attr/index.js +19 -16
  83. package/lib/required-element/index.d.ts +2 -2
  84. package/lib/required-element/index.js +3 -2
  85. package/lib/required-h1/index.d.ts +3 -3
  86. package/lib/required-h1/index.js +4 -3
  87. package/lib/use-list/index.d.ts +3 -3
  88. package/lib/use-list/index.js +7 -5
  89. package/lib/wai-aria/checkings/_.d.ts +15 -0
  90. package/lib/wai-aria/checkings/_.js +27 -0
  91. package/lib/wai-aria/checkings/abstract-role.js +1 -1
  92. package/lib/wai-aria/checkings/default-value.d.ts +7 -3
  93. package/lib/wai-aria/checkings/deprecated-props.d.ts +8 -4
  94. package/lib/wai-aria/checkings/disallowed-prop.d.ts +8 -4
  95. package/lib/wai-aria/checkings/disallowed-prop.js +27 -3
  96. package/lib/wai-aria/checkings/implicit-props.d.ts +8 -4
  97. package/lib/wai-aria/checkings/implicit-props.js +3 -2
  98. package/lib/wai-aria/checkings/implicit-role.js +1 -1
  99. package/lib/wai-aria/checkings/interaction-in-hidden.js +3 -1
  100. package/lib/wai-aria/checkings/no-global-prop.d.ts +7 -3
  101. package/lib/wai-aria/checkings/non-existent-role.js +1 -1
  102. package/lib/wai-aria/checkings/permitted-roles.js +1 -1
  103. package/lib/wai-aria/checkings/presentational-children.js +4 -2
  104. package/lib/wai-aria/checkings/required-owned-elements.d.ts +7 -3
  105. package/lib/wai-aria/checkings/required-owned-elements.js +28 -12
  106. package/lib/wai-aria/checkings/required-prop copy.d.ts +15 -0
  107. package/lib/wai-aria/checkings/required-prop copy.js +27 -0
  108. package/lib/wai-aria/checkings/required-prop.d.ts +12 -6
  109. package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +15 -0
  110. package/lib/wai-aria/checkings/unadopted-explicit-roles.js +17 -0
  111. package/lib/wai-aria/checkings/value.d.ts +15 -6
  112. package/lib/wai-aria/checkings/value.js +3 -1
  113. package/lib/wai-aria/index.d.ts +1 -1
  114. package/lib/wai-aria/index.js +13 -12
  115. package/lib/wai-aria/types.d.ts +10 -10
  116. package/lib/xxx/index.d.ts +2 -0
  117. package/lib/xxx/index.js +32 -0
  118. package/package.json +16 -11
  119. package/schema.json +6 -0
  120. package/test/attr-check.spec.js +77 -0
  121. package/test/attr-duplication/index.spec.js +159 -0
  122. package/test/attr-value-quotes/index.spec.js +133 -0
  123. package/test/case-sensitive-attr-name/index.spec.js +65 -0
  124. package/test/case-sensitive-tag-name/index.spec.js +80 -0
  125. package/test/character-reference/index.spec.js +57 -0
  126. package/test/class-naming/index.spec.js +470 -0
  127. package/test/create-message.spec.js +497 -0
  128. package/test/deprecated-attr/index.spec.js +48 -0
  129. package/test/deprecated-element/index.spec.js +48 -0
  130. package/test/disallowed-element/index.spec.js +90 -0
  131. package/test/doctype/index.spec.js +50 -0
  132. package/test/end-tag/index.spec.js +162 -0
  133. package/test/id-duplication/index.spec.js +47 -0
  134. package/test/ineffective-attr/index.spec.js +31 -0
  135. package/test/invalid-attr/index.spec.js +1632 -0
  136. package/test/label-has-control/index.spec.js +29 -0
  137. package/test/landmark-roles/index.spec.js +187 -0
  138. package/test/no-boolean-attr-value/index.spec.js +41 -0
  139. package/test/no-default-value/index.spec.js +74 -0
  140. package/test/no-empty-palpable-content/index.spec.js +115 -0
  141. package/test/no-hard-code-id/index.spec.js +100 -0
  142. package/test/no-refer-to-non-existent-id/index.spec.js +254 -0
  143. package/test/no-use-event-handler-attr/index.spec.js +57 -0
  144. package/test/permitted-contents/choice.spec.js +174 -0
  145. package/test/permitted-contents/count-pattern.spec.js +308 -0
  146. package/test/permitted-contents/index.spec.js +1371 -0
  147. package/test/permitted-contents/matches-selector.spec.js +59 -0
  148. package/test/permitted-contents/order.spec.js +351 -0
  149. package/test/permitted-contents/recursive-branch.spec.js +41 -0
  150. package/test/permitted-contents/represent-transparent-nodes.spec.js +24 -0
  151. package/test/permitted-contents/start.spec.js +67 -0
  152. package/test/placeholder-label-option/index.spec.js +113 -0
  153. package/test/require-accessible-name/index.spec.js +446 -0
  154. package/test/require-datetime/index.spec.js +54 -0
  155. package/test/require-datetime/utils.spec.js +52 -0
  156. package/test/required-attr/index.spec.js +414 -0
  157. package/test/required-element/index.spec.js +188 -0
  158. package/test/required-h1/index.spec.js +69 -0
  159. package/test/use-list/index.spec.js +109 -0
  160. package/test/wai-aria/checkings/value.spec.js +33 -0
  161. package/test/wai-aria/index.spec.js +1173 -0
  162. package/tsconfig.test.json +0 -3
  163. package/tsconfig.tsbuildinfo +0 -1
@@ -7,6 +7,7 @@ exports.default = (0, ml_core_1.createRule)({
7
7
  ignoreHasMutableContents: true,
8
8
  },
9
9
  async verify({ document, report, t }) {
10
+ var _a, _b;
10
11
  const hasMutableContent = document.nodeList.some(n => n.is(n.ELEMENT_NODE) && n.hasMutableChildren());
11
12
  if (!hasMutableContent) {
12
13
  for (const query of document.rule.value) {
@@ -17,7 +18,7 @@ exports.default = (0, ml_core_1.createRule)({
17
18
  message,
18
19
  line: 1,
19
20
  col: 1,
20
- raw: document.nodeList[0].raw.slice(0, 1),
21
+ raw: (_b = (_a = document.nodeList[0]) === null || _a === void 0 ? void 0 : _a.raw.slice(0, 1)) !== null && _b !== void 0 ? _b : '',
21
22
  });
22
23
  }
23
24
  }
@@ -26,7 +27,7 @@ exports.default = (0, ml_core_1.createRule)({
26
27
  if (el.rule.value === document.rule.value) {
27
28
  return;
28
29
  }
29
- if (el.rule.option.ignoreHasMutableContents && el.hasMutableChildren()) {
30
+ if (el.rule.options.ignoreHasMutableContents && el.hasMutableChildren()) {
30
31
  return;
31
32
  }
32
33
  for (const query of el.rule.value) {
@@ -1,6 +1,6 @@
1
1
  export interface Options {
2
- 'expected-once': boolean;
3
- 'in-document-fragment': boolean;
2
+ 'expected-once': boolean;
3
+ 'in-document-fragment': boolean;
4
4
  }
5
- declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Options>;
5
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
6
6
  export default _default;
@@ -7,11 +7,12 @@ exports.default = (0, ml_core_1.createRule)({
7
7
  'in-document-fragment': false,
8
8
  },
9
9
  async verify({ document, report, t }) {
10
+ var _a, _b;
10
11
  const h1Stack = [];
11
12
  if (document.nodeList.length === 0) {
12
13
  return;
13
14
  }
14
- if (!document.rule.option['in-document-fragment'] && document.isFragment) {
15
+ if (!document.rule.options['in-document-fragment'] && document.isFragment) {
15
16
  return;
16
17
  }
17
18
  await document.walkOn('Element', node => {
@@ -25,10 +26,10 @@ exports.default = (0, ml_core_1.createRule)({
25
26
  message,
26
27
  line: 1,
27
28
  col: 1,
28
- raw: document.nodeList[0].raw.slice(0, 1),
29
+ raw: (_b = (_a = document.nodeList[0]) === null || _a === void 0 ? void 0 : _a.raw.slice(0, 1)) !== null && _b !== void 0 ? _b : '',
29
30
  });
30
31
  }
31
- else if (document.rule.option['expected-once'] && h1Stack.length > 1) {
32
+ else if (document.rule.options['expected-once'] && h1Stack.length > 1 && h1Stack[1]) {
32
33
  const message = t('{0} is {1:c}', t('the "{0*}" {1}', 'h1', 'element'), 'duplicated');
33
34
  report({
34
35
  message,
@@ -1,6 +1,6 @@
1
- type Bullets = string[];
1
+ type Bullets = readonly string[];
2
2
  type Options = {
3
- spaceNeededBullets?: string[];
3
+ spaceNeededBullets?: string[];
4
4
  };
5
- declare const _default: import("@markuplint/ml-core").RuleSeed<Bullets, Options>;
5
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<Bullets, Options>>;
6
6
  export default _default;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
- const helpers_1 = require("../helpers");
4
+ const shared_1 = require("@markuplint/shared");
5
5
  exports.default = (0, ml_core_1.createRule)({
6
6
  defaultValue: [
7
7
  /**
@@ -57,7 +57,8 @@ exports.default = (0, ml_core_1.createRule)({
57
57
  defaultSeverity: 'warning',
58
58
  async verify({ document, report, t }) {
59
59
  await document.walkOn('Text', textNode => {
60
- const text = (0, helpers_1.decodeCharRef)(textNode.raw.trim());
60
+ var _a;
61
+ const text = (0, shared_1.decodeEntities)(textNode.raw.trim());
61
62
  if (!text) {
62
63
  // empty
63
64
  return;
@@ -67,7 +68,7 @@ exports.default = (0, ml_core_1.createRule)({
67
68
  return;
68
69
  }
69
70
  const bullets = textNode.rule.value;
70
- const spaceNeededBullets = textNode.rule.option.spaceNeededBullets || [];
71
+ const spaceNeededBullets = (_a = textNode.rule.options.spaceNeededBullets) !== null && _a !== void 0 ? _a : [];
71
72
  if (isMayListItem(text, bullets, spaceNeededBullets)) {
72
73
  report({
73
74
  scope: textNode,
@@ -78,15 +79,16 @@ exports.default = (0, ml_core_1.createRule)({
78
79
  },
79
80
  });
80
81
  function isMayListItem(text, bullets, spaceNeededBullets) {
82
+ var _a;
81
83
  const textArray = Array.from(text);
82
- const firstLetter = textArray[0];
84
+ const firstLetter = (_a = textArray[0]) !== null && _a !== void 0 ? _a : '';
83
85
  const isBullet = bullets.includes(firstLetter);
84
86
  const needSpace = spaceNeededBullets.includes(firstLetter);
85
87
  const continuous = firstLetter === textArray[1];
86
88
  if (continuous) {
87
89
  return false;
88
90
  }
89
- if (isBullet && needSpace) {
91
+ if (isBullet && needSpace && text[1]) {
90
92
  const secondLetter = text[1];
91
93
  const isSpace = /^\s$/.test(secondLetter);
92
94
  return isSpace;
@@ -0,0 +1,15 @@
1
+ import type { Options } from '../types';
2
+ import type { ElementChecker } from '@markuplint/ml-core';
3
+ import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
+ export declare const checkingRequiredProp: ElementChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role?:
9
+ | (ARIARole & {
10
+ isImplicit?: boolean;
11
+ })
12
+ | null;
13
+ propSpecs: readonly ARIAProperty[];
14
+ }
15
+ >;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkingRequiredProp = void 0;
4
+ const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
5
+ var _a;
6
+ if (!role) {
7
+ return;
8
+ }
9
+ if (role.isImplicit) {
10
+ return;
11
+ }
12
+ const requiredProps = role.ownedProperties.filter(s => s.required).map(s => s.name);
13
+ for (const requiredProp of requiredProps) {
14
+ const has = el.attributes.some(attr => {
15
+ const attrName = attr.name.toLowerCase();
16
+ return attrName === requiredProp;
17
+ });
18
+ if (!has) {
19
+ const propSpec = propSpecs.find(p => p.name === requiredProp);
20
+ return {
21
+ scope: el,
22
+ message: t('{0:c} on {1}', t('Require {0}', t('the "{0*}" {1}', requiredProp, `ARIA ${(_a = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _a !== void 0 ? _a : 'property'}`)), t('the "{0*}" {1}', role.name, 'role')),
23
+ };
24
+ }
25
+ }
26
+ };
27
+ exports.checkingRequiredProp = checkingRequiredProp;
@@ -4,7 +4,7 @@ exports.checkingAbstractRole = void 0;
4
4
  const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingAbstractRole = ({ attr }) => t => {
6
6
  var _a;
7
- const { roles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.option.version);
7
+ const { roles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.options.version);
8
8
  const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
9
9
  if (!tokens) {
10
10
  return;
@@ -1,6 +1,10 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty } from '@markuplint/ml-spec';
4
- export declare const checkingDefaultValue: AttrChecker<boolean, Options, {
5
- propSpecs: ARIAProperty[];
6
- }>;
4
+ export declare const checkingDefaultValue: AttrChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ propSpecs: readonly ARIAProperty[];
9
+ }
10
+ >;
@@ -1,7 +1,11 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
- export declare const checkingDeprecatedProps: AttrChecker<boolean, Options, {
5
- role: ARIARole | null;
6
- propSpecs: ARIAProperty[];
7
- }>;
4
+ export declare const checkingDeprecatedProps: AttrChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role: ARIARole | null;
9
+ propSpecs: readonly ARIAProperty[];
10
+ }
11
+ >;
@@ -1,7 +1,11 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
- export declare const checkingDisallowedProp: AttrChecker<boolean, Options, {
5
- role: ARIARole | null;
6
- propSpecs: ARIAProperty[];
7
- }>;
4
+ export declare const checkingDisallowedProp: AttrChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role: ARIARole | null;
9
+ propSpecs: readonly ARIAProperty[];
10
+ }
11
+ >;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkingDisallowedProp = void 0;
4
+ const ml_spec_1 = require("@markuplint/ml-spec");
4
5
  const checkingDisallowedProp = ({ attr, role, propSpecs }) => t => {
5
- var _a;
6
+ var _a, _b, _c, _d;
6
7
  if (!role) {
7
8
  return;
8
9
  }
@@ -10,13 +11,36 @@ const checkingDisallowedProp = ({ attr, role, propSpecs }) => t => {
10
11
  return;
11
12
  }
12
13
  const statesAndProp = role.ownedProperties.find(p => p.name === attr.name);
14
+ const propSpec = propSpecs.find(p => p.name === attr.name);
15
+ const elAriaSpec = (0, ml_spec_1.getARIA)(attr.ownerMLDocument.specs, attr.ownerElement.localName, attr.ownerElement.namespaceURI, attr.rule.options.version, attr.ownerElement.matches.bind(attr.ownerElement));
16
+ if ((elAriaSpec === null || elAriaSpec === void 0 ? void 0 : elAriaSpec.properties) !== false && ((_a = elAriaSpec === null || elAriaSpec === void 0 ? void 0 : elAriaSpec.properties) === null || _a === void 0 ? void 0 : _a.without)) {
17
+ for (const ignore of elAriaSpec.properties.without) {
18
+ if (ignore.name === attr.name) {
19
+ return {
20
+ scope: attr,
21
+ message: t('{0:c} on {1}', t(ignore.type === 'must-not'
22
+ ? '{0} must not {1}'
23
+ : ignore.type === 'should-not'
24
+ ? '{0} should not {1}'
25
+ : '{0} is not recommended to {1}',
26
+ // {0}
27
+ t('the "{0*}" {1}', attr.name, `ARIA ${(_b = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _b !== void 0 ? _b : 'property'}`),
28
+ // {1}
29
+ 'use'), t('the "{0*}" {1}', attr.ownerElement.localName, 'element')) +
30
+ (ignore.alt
31
+ ? t('. ') +
32
+ t('{0} if you {1} {2}', t(ignore.alt.method === 'remove-attr' ? 'Remove {0}' : 'Add {0}', t('the "{0*}" {1}', ignore.alt.target, 'attribute')), 'use', t('the {0}', `ARIA ${(_c = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _c !== void 0 ? _c : 'property'}`))
33
+ : ''),
34
+ };
35
+ }
36
+ }
37
+ }
13
38
  if (statesAndProp) {
14
39
  return;
15
40
  }
16
- const propSpec = propSpecs.find(p => p.name === attr.name);
17
41
  return {
18
42
  scope: attr,
19
- message: t('{0:c} on {1}', t('{0} is {1:c}', t('the "{0*}" {1}', attr.name, `ARIA ${(_a = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _a !== void 0 ? _a : 'property'}`), 'disallowed'), t('the "{0*}" {1}', role.name, 'role')),
43
+ message: t('{0:c} on {1}', t('{0} is {1:c}', t('the "{0*}" {1}', attr.name, `ARIA ${(_d = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _d !== void 0 ? _d : 'property'}`), 'disallowed'), t('the "{0*}" {1}', role.name, 'role')),
20
44
  };
21
45
  };
22
46
  exports.checkingDisallowedProp = checkingDisallowedProp;
@@ -1,7 +1,11 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty, Attribute } from '@markuplint/ml-spec';
4
- export declare const checkingImplicitProps: AttrChecker<boolean, Options, {
5
- propSpecs: ARIAProperty[];
6
- attrSpecs: Attribute[] | null;
7
- }>;
4
+ export declare const checkingImplicitProps: AttrChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ propSpecs: readonly ARIAProperty[];
9
+ attrSpecs: readonly Attribute[] | null;
10
+ }
11
+ >;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkingImplicitProps = void 0;
4
4
  const helpers_1 = require("../../helpers");
5
5
  const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
6
+ var _a;
6
7
  if (!attrSpecs) {
7
8
  return;
8
9
  }
@@ -15,8 +16,8 @@ const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
15
16
  }
16
17
  for (const equivalentHtmlAttr of propSpec.equivalentHtmlAttrs) {
17
18
  const htmlAttrSpec = attrSpecs.find(a => a.name === equivalentHtmlAttr.htmlAttrName);
18
- const isValid = (0, helpers_1.isValidAttr)(t, equivalentHtmlAttr.htmlAttrName, equivalentHtmlAttr.value || '', false, attr.ownerElement, attrSpecs);
19
- if (isValid && isValid.invalidType === 'non-existent') {
19
+ const isValid = (0, helpers_1.isValidAttr)(t, equivalentHtmlAttr.htmlAttrName, (_a = equivalentHtmlAttr.value) !== null && _a !== void 0 ? _a : '', false, attr.ownerElement, attrSpecs);
20
+ if (isValid !== false && isValid.invalidType === 'non-existent') {
20
21
  continue;
21
22
  }
22
23
  const value = attr.value.trim().toLowerCase();
@@ -4,7 +4,7 @@ exports.checkingImplicitRole = void 0;
4
4
  const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingImplicitRole = ({ attr }) => t => {
6
6
  var _a;
7
- const implicitRole = (0, ml_spec_1.getImplicitRoleName)(attr.ownerElement, attr.rule.option.version, attr.ownerMLDocument.specs);
7
+ const implicitRole = (0, ml_spec_1.getImplicitRoleName)(attr.ownerElement, attr.rule.options.version, attr.ownerMLDocument.specs);
8
8
  const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
9
9
  if (!tokens) {
10
10
  return;
@@ -34,7 +34,9 @@ const checkingInteractionInHidden = ({ el }) => t => {
34
34
  };
35
35
  };
36
36
  exports.checkingInteractionInHidden = checkingInteractionInHidden;
37
- function getClosestAriaHidden(el) {
37
+ function getClosestAriaHidden(
38
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
39
+ el) {
38
40
  let current = el;
39
41
  while (current) {
40
42
  const ariaHidden = current.getAttributeNode('aria-hidden');
@@ -1,6 +1,10 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty } from '@markuplint/ml-spec';
4
- export declare const checkingNoGlobalProp: AttrChecker<boolean, Options, {
5
- propSpecs: ARIAProperty[];
6
- }>;
4
+ export declare const checkingNoGlobalProp: AttrChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ propSpecs: readonly ARIAProperty[];
9
+ }
10
+ >;
@@ -4,7 +4,7 @@ exports.checkingNonExistentRole = void 0;
4
4
  const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingNonExistentRole = ({ attr }) => t => {
6
6
  var _a;
7
- const { roles, graphicsRoles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.option.version);
7
+ const { roles, graphicsRoles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.options.version);
8
8
  const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
9
9
  if (!tokens) {
10
10
  return;
@@ -5,7 +5,7 @@ const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingPermittedRoles = ({ attr }) => t => {
6
6
  var _a;
7
7
  const el = attr.ownerElement;
8
- const permittedRoles = (0, ml_spec_1.getPermittedRoles)(el, el.rule.option.version, attr.ownerMLDocument.specs);
8
+ const permittedRoles = (0, ml_spec_1.getPermittedRoles)(el, el.rule.options.version, attr.ownerMLDocument.specs);
9
9
  if (permittedRoles.length === 0) {
10
10
  return {
11
11
  scope: attr,
@@ -46,11 +46,13 @@ const checkingPresentationalChildren = ({ el }) => t => {
46
46
  };
47
47
  };
48
48
  exports.checkingPresentationalChildren = checkingPresentationalChildren;
49
- function getAncestorHasPresentationalChildren(el) {
49
+ function getAncestorHasPresentationalChildren(
50
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
51
+ el) {
50
52
  var _a;
51
53
  let current = el.parentElement;
52
54
  while (current) {
53
- const computed = (0, ml_spec_1.getComputedRole)(el.ownerMLDocument.specs, current, el.rule.option.version);
55
+ const computed = (0, ml_spec_1.getComputedRole)(el.ownerMLDocument.specs, current, el.rule.options.version);
54
56
  if ((_a = computed.role) === null || _a === void 0 ? void 0 : _a.childrenPresentational) {
55
57
  return computed;
56
58
  }
@@ -6,6 +6,10 @@ import type { ARIARole } from '@markuplint/ml-spec';
6
6
  *
7
7
  * @see https://w3c.github.io/aria/#mustContain
8
8
  */
9
- export declare const checkingRequiredOwnedElements: ElementChecker<boolean, Options, {
10
- role?: ARIARole | null;
11
- }>;
9
+ export declare const checkingRequiredOwnedElements: ElementChecker<
10
+ boolean,
11
+ Options,
12
+ {
13
+ role?: ARIARole | null;
14
+ }
15
+ >;
@@ -11,7 +11,7 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
11
11
  if (!role) {
12
12
  return;
13
13
  }
14
- if (!role.requiredOwnedElements.length) {
14
+ if (role.requiredOwnedElements.length === 0) {
15
15
  return;
16
16
  }
17
17
  /**
@@ -28,18 +28,13 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
28
28
  return;
29
29
  }
30
30
  // TODO: Needs to resolve `aria-own`
31
- if (el.isEmpty()) {
32
- return {
33
- scope: el,
34
- message: t('{0}. Or, {1}', t('require {0}', role.requiredOwnedElements.length === 1
35
- ? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
36
- : t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`), t('require {0}', 'aria-busy="true"')),
37
- };
38
- }
39
31
  const children = Array.from(el.childNodes).map(child => {
40
32
  if (child.is(child.ELEMENT_NODE)) {
41
- const computedChild = (0, ml_spec_1.getComputedRole)(child.ownerMLDocument.specs, child, child.rule.option.version);
42
- if (role.requiredOwnedElements.some(ownedRole => (0, ml_spec_1.isRequiredOwnedElement)(computedChild, ownedRole, child.ownerMLDocument.specs, child.rule.option.version))) {
33
+ if (child.matches('[aria-busy="true" i]')) {
34
+ return [child, 'BUSY'];
35
+ }
36
+ const computedChild = (0, ml_spec_1.getComputedRole)(child.ownerMLDocument.specs, child, child.rule.options.version);
37
+ if (role.requiredOwnedElements.some(ownedRole => (0, ml_spec_1.isRequiredOwnedElement)(computedChild.el, computedChild.role, ownedRole, child.ownerMLDocument.specs, child.rule.options.version))) {
43
38
  return [child, 'REQUIRED'];
44
39
  }
45
40
  return [child, 'OTHER'];
@@ -49,6 +44,9 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
49
44
  }
50
45
  return [null, 'NO_ELEMENT'];
51
46
  });
47
+ if (children.some(([, type]) => type === 'BUSY')) {
48
+ return;
49
+ }
52
50
  /**
53
51
  * > Any element that will be owned by the element with this role.
54
52
  * > For example, an element with the role list
@@ -77,11 +75,29 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
77
75
  if (el.hasMutableChildren(true)) {
78
76
  return;
79
77
  }
78
+ if (mayBeBeforeCreated(el)) {
79
+ return {
80
+ scope: el,
81
+ message: t('{0}. Or, {1}', t('require {0}', role.requiredOwnedElements.length === 1 && role.requiredOwnedElements[0]
82
+ ? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
83
+ : t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`), t('require {0}', 'aria-busy="true"')),
84
+ };
85
+ }
80
86
  return {
81
87
  scope: el,
82
- message: t('{0} expects {1}', t('the "{0*}" {1}', role.name, 'role'), role.requiredOwnedElements.length === 1
88
+ message: t('{0} expects {1}', t('the "{0*}" {1}', role.name, 'role'), role.requiredOwnedElements.length === 1 && role.requiredOwnedElements[0]
83
89
  ? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
84
90
  : t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`),
85
91
  };
86
92
  };
87
93
  exports.checkingRequiredOwnedElements = checkingRequiredOwnedElements;
94
+ function mayBeBeforeCreated(
95
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
96
+ el) {
97
+ if (el.isEmpty()) {
98
+ return true;
99
+ }
100
+ return Array.from(el.children).every(child => {
101
+ return ['script', 'template'].includes(child.localName);
102
+ });
103
+ }
@@ -0,0 +1,15 @@
1
+ import type { Options } from '../types';
2
+ import type { ElementChecker } from '@markuplint/ml-core';
3
+ import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
+ export declare const checkingRequiredProp: ElementChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role?:
9
+ | (ARIARole & {
10
+ isImplicit?: boolean;
11
+ })
12
+ | null;
13
+ propSpecs: readonly ARIAProperty[];
14
+ }
15
+ >;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkingRequiredProp = void 0;
4
+ const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
5
+ var _a;
6
+ if (!role) {
7
+ return;
8
+ }
9
+ if (role.isImplicit) {
10
+ return;
11
+ }
12
+ const requiredProps = role.ownedProperties.filter(s => s.required).map(s => s.name);
13
+ for (const requiredProp of requiredProps) {
14
+ const has = el.attributes.some(attr => {
15
+ const attrName = attr.name.toLowerCase();
16
+ return attrName === requiredProp;
17
+ });
18
+ if (!has) {
19
+ const propSpec = propSpecs.find(p => p.name === requiredProp);
20
+ return {
21
+ scope: el,
22
+ message: t('{0:c} on {1}', t('Require {0}', t('the "{0*}" {1}', requiredProp, `ARIA ${(_a = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _a !== void 0 ? _a : 'property'}`)), t('the "{0*}" {1}', role.name, 'role')),
23
+ };
24
+ }
25
+ }
26
+ };
27
+ exports.checkingRequiredProp = checkingRequiredProp;
@@ -1,9 +1,15 @@
1
1
  import type { Options } from '../types';
2
2
  import type { ElementChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
- export declare const checkingRequiredProp: ElementChecker<boolean, Options, {
5
- role?: (ARIARole & {
6
- isImplicit?: boolean;
7
- }) | null;
8
- propSpecs: ARIAProperty[];
9
- }>;
4
+ export declare const checkingRequiredProp: ElementChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role?:
9
+ | (ARIARole & {
10
+ isImplicit?: boolean;
11
+ })
12
+ | null;
13
+ propSpecs: readonly ARIAProperty[];
14
+ }
15
+ >;
@@ -0,0 +1,15 @@
1
+ import type { Options } from '../types';
2
+ import type { ElementChecker } from '@markuplint/ml-core';
3
+ import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
+ export declare const checkingUnadoptedExplicitRoles: ElementChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role?:
9
+ | (ARIARole & {
10
+ isImplicit?: boolean;
11
+ })
12
+ | null;
13
+ propSpecs: readonly ARIAProperty[];
14
+ }
15
+ >;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkingUnadoptedExplicitRoles = void 0;
4
+ const checkingUnadoptedExplicitRoles = ({ el, role, propSpecs }) => t => {
5
+ if (!role) {
6
+ return;
7
+ }
8
+ if (role.name) {
9
+ console.log(el.localName, role.name);
10
+ return {
11
+ scope: el,
12
+ message: '',
13
+ };
14
+ }
15
+ return;
16
+ };
17
+ exports.checkingUnadoptedExplicitRoles = checkingUnadoptedExplicitRoles;
@@ -1,13 +1,22 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
3
  import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
- export declare const checkingValue: AttrChecker<boolean, Options, {
5
- role?: ARIARole | null;
6
- propSpecs: ARIAProperty[];
7
- booleanish?: boolean;
8
- }>;
4
+ export declare const checkingValue: AttrChecker<
5
+ boolean,
6
+ Options,
7
+ {
8
+ role?: ARIARole | null;
9
+ propSpecs: readonly ARIAProperty[];
10
+ booleanish?: boolean;
11
+ }
12
+ >;
9
13
  /**
10
14
  *
11
15
  * @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
12
16
  */
13
- export declare function checkAriaValue(type: string, value: string, tokenEnum: string[], booleanish?: boolean): boolean;
17
+ export declare function checkAriaValue(
18
+ type: string,
19
+ value: string,
20
+ tokenEnum: readonly string[],
21
+ booleanish?: boolean,
22
+ ): boolean;
@@ -14,7 +14,9 @@ const checkingValue = ({ attr, role, propSpecs, booleanish }) => t => {
14
14
  return {
15
15
  scope: attr,
16
16
  message: t('{0:c} on {1}', t('{0} is {1:c}', t('the "{0}"', attr.value), 'disallowed'), t('the "{0*}" {1}', attr.name, `ARIA ${(_a = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _a !== void 0 ? _a : 'property'}`)) +
17
- ('enum' in result && result.enum.length ? t('. ') + t('Allowed values are: {0}', t(result.enum)) : ''),
17
+ ('enum' in result && result.enum.length > 0
18
+ ? t('. ') + t('Allowed values are: {0}', t(result.enum))
19
+ : ''),
18
20
  };
19
21
  };
20
22
  exports.checkingValue = checkingValue;
@@ -1,3 +1,3 @@
1
1
  import type { Options } from './types';
2
- declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Options>;
2
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
3
3
  export default _default;