@markuplint/rules 3.0.0-alpha.66 → 3.0.0-dev.176

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 (211) hide show
  1. package/README.md +10 -44
  2. package/lib/attr-check.d.ts +22 -10
  3. package/lib/attr-check.js +32 -23
  4. package/lib/attr-duplication/index.d.ts +3 -1
  5. package/lib/attr-duplication/index.js +3 -2
  6. package/lib/attr-value-quotes/index.d.ts +5 -5
  7. package/lib/attr-value-quotes/index.js +1 -1
  8. package/lib/case-sensitive-attr-name/index.d.ts +2 -2
  9. package/lib/case-sensitive-attr-name/index.js +3 -3
  10. package/lib/case-sensitive-tag-name/index.d.ts +2 -2
  11. package/lib/case-sensitive-tag-name/index.js +3 -3
  12. package/lib/character-reference/index.d.ts +1 -1
  13. package/lib/character-reference/index.js +1 -1
  14. package/lib/class-naming/index.d.ts +2 -2
  15. package/lib/class-naming/index.js +3 -5
  16. package/lib/create-message.d.ts +13 -2
  17. package/lib/create-message.js +9 -8
  18. package/lib/debug.d.ts +1 -1
  19. package/lib/debug.js +1 -1
  20. package/lib/deprecated-attr/index.d.ts +3 -1
  21. package/lib/deprecated-element/index.d.ts +3 -1
  22. package/lib/deprecated-element/index.js +4 -4
  23. package/lib/disallowed-element/index.d.ts +1 -1
  24. package/lib/doctype/index.d.ts +3 -3
  25. package/lib/doctype/index.js +2 -2
  26. package/lib/end-tag/index.d.ts +1 -1
  27. package/lib/end-tag/index.js +3 -18
  28. package/lib/helpers.d.ts +38 -47
  29. package/lib/helpers.js +42 -93
  30. package/lib/id-duplication/index.d.ts +3 -1
  31. package/lib/index.d.ts +242 -62
  32. package/lib/index.js +10 -1
  33. package/lib/ineffective-attr/index.d.ts +3 -1
  34. package/lib/ineffective-attr/index.js +3 -6
  35. package/lib/invalid-attr/index.d.ts +40 -12
  36. package/lib/invalid-attr/index.js +159 -28
  37. package/lib/label-has-control/index.d.ts +4 -0
  38. package/lib/label-has-control/index.js +28 -0
  39. package/lib/landmark-roles/index.d.ts +6 -6
  40. package/lib/landmark-roles/index.js +10 -6
  41. package/lib/no-boolean-attr-value/index.d.ts +3 -1
  42. package/lib/no-boolean-attr-value/index.js +1 -1
  43. package/lib/no-default-value/index.d.ts +3 -1
  44. package/lib/no-default-value/index.js +1 -1
  45. package/lib/no-empty-palpable-content/index.d.ts +6 -0
  46. package/lib/no-empty-palpable-content/index.js +42 -0
  47. package/lib/no-hard-code-id/index.d.ts +3 -1
  48. package/lib/no-hard-code-id/index.js +1 -1
  49. package/lib/no-refer-to-non-existent-id/index.d.ts +9 -4
  50. package/lib/no-refer-to-non-existent-id/index.js +65 -5
  51. package/lib/no-use-event-handler-attr/index.d.ts +3 -3
  52. package/lib/no-use-event-handler-attr/index.js +6 -6
  53. package/lib/permitted-contents/choice.d.ts +10 -0
  54. package/lib/permitted-contents/choice.js +72 -0
  55. package/lib/permitted-contents/complex-branch.d.ts +20 -0
  56. package/lib/permitted-contents/complex-branch.js +29 -0
  57. package/lib/permitted-contents/content-model.d.ts +2 -0
  58. package/lib/permitted-contents/content-model.js +53 -0
  59. package/lib/permitted-contents/count-pattern.d.ts +29 -0
  60. package/lib/permitted-contents/count-pattern.js +162 -0
  61. package/lib/permitted-contents/debug.browser.d.ts +30 -0
  62. package/lib/permitted-contents/debug.browser.js +14 -0
  63. package/lib/permitted-contents/debug.d.ts +3 -0
  64. package/lib/permitted-contents/debug.js +13 -0
  65. package/lib/permitted-contents/index.d.ts +2 -8
  66. package/lib/permitted-contents/index.js +76 -249
  67. package/lib/permitted-contents/matches-selector.d.ts +8 -0
  68. package/lib/permitted-contents/matches-selector.js +187 -0
  69. package/lib/permitted-contents/order.d.ts +20 -0
  70. package/lib/permitted-contents/order.js +99 -0
  71. package/lib/permitted-contents/recursive-branch.d.ts +11 -0
  72. package/lib/permitted-contents/recursive-branch.js +45 -0
  73. package/lib/permitted-contents/represent-transparent-nodes.d.ts +10 -0
  74. package/lib/permitted-contents/represent-transparent-nodes.js +78 -0
  75. package/lib/permitted-contents/start.d.ts +18 -0
  76. package/lib/permitted-contents/start.js +73 -0
  77. package/lib/permitted-contents/transparent.d.ts +2 -0
  78. package/lib/permitted-contents/transparent.js +31 -0
  79. package/lib/permitted-contents/types.d.ts +52 -0
  80. package/lib/permitted-contents/types.js +2 -0
  81. package/lib/permitted-contents/utils.d.ts +100 -0
  82. package/lib/permitted-contents/utils.js +302 -0
  83. package/lib/placeholder-label-option/index.d.ts +2 -0
  84. package/lib/placeholder-label-option/index.js +88 -0
  85. package/lib/require-accessible-name/index.d.ts +3 -3
  86. package/lib/require-accessible-name/index.js +12 -4
  87. package/lib/require-datetime/index.d.ts +6 -0
  88. package/lib/require-datetime/index.js +34 -0
  89. package/lib/require-datetime/types.d.ts +10 -0
  90. package/lib/require-datetime/types.js +2 -0
  91. package/lib/require-datetime/utils.d.ts +11 -0
  92. package/lib/require-datetime/utils.js +137 -0
  93. package/lib/required-attr/index.d.ts +5 -5
  94. package/lib/required-attr/index.js +20 -17
  95. package/lib/required-element/index.d.ts +3 -3
  96. package/lib/required-element/index.js +3 -2
  97. package/lib/required-h1/index.d.ts +3 -3
  98. package/lib/required-h1/index.js +4 -3
  99. package/lib/use-list/index.d.ts +4 -4
  100. package/lib/use-list/index.js +9 -7
  101. package/lib/wai-aria/checkings/_.d.ts +15 -0
  102. package/lib/wai-aria/checkings/_.js +27 -0
  103. package/lib/wai-aria/checkings/abstract-role.js +1 -1
  104. package/lib/wai-aria/checkings/default-value.d.ts +7 -3
  105. package/lib/wai-aria/checkings/deprecated-props.d.ts +8 -4
  106. package/lib/wai-aria/checkings/disallowed-prop.d.ts +8 -4
  107. package/lib/wai-aria/checkings/disallowed-prop.js +27 -3
  108. package/lib/wai-aria/checkings/implicit-props.d.ts +8 -4
  109. package/lib/wai-aria/checkings/implicit-props.js +3 -2
  110. package/lib/wai-aria/checkings/implicit-role.js +2 -2
  111. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +11 -0
  112. package/lib/wai-aria/checkings/interaction-in-hidden.js +49 -0
  113. package/lib/wai-aria/checkings/no-global-prop.d.ts +7 -3
  114. package/lib/wai-aria/checkings/{non-existant-role.d.ts → non-existent-role.d.ts} +1 -1
  115. package/lib/wai-aria/checkings/{non-existant-role.js → non-existent-role.js} +4 -4
  116. package/lib/wai-aria/checkings/permitted-roles.js +1 -1
  117. package/lib/wai-aria/checkings/presentational-children.d.ts +29 -0
  118. package/lib/wai-aria/checkings/presentational-children.js +62 -0
  119. package/lib/wai-aria/checkings/{checking-required-owned-elements.d.ts → required-owned-elements.d.ts} +7 -3
  120. package/lib/wai-aria/checkings/required-owned-elements.js +103 -0
  121. package/lib/wai-aria/checkings/required-prop copy.d.ts +15 -0
  122. package/lib/wai-aria/checkings/required-prop copy.js +27 -0
  123. package/lib/wai-aria/checkings/required-prop.d.ts +12 -6
  124. package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +15 -0
  125. package/lib/wai-aria/checkings/unadopted-explicit-roles.js +17 -0
  126. package/lib/wai-aria/checkings/value.d.ts +19 -4
  127. package/lib/wai-aria/checkings/value.js +77 -5
  128. package/lib/wai-aria/index.d.ts +1 -1
  129. package/lib/wai-aria/index.js +27 -16
  130. package/lib/wai-aria/types.d.ts +11 -9
  131. package/lib/xxx/index.d.ts +2 -0
  132. package/lib/xxx/index.js +32 -0
  133. package/package.json +18 -12
  134. package/schema.json +12 -0
  135. package/test/attr-check.spec.js +77 -0
  136. package/test/attr-duplication/index.spec.js +159 -0
  137. package/test/attr-value-quotes/index.spec.js +133 -0
  138. package/test/case-sensitive-attr-name/index.spec.js +65 -0
  139. package/test/case-sensitive-tag-name/index.spec.js +80 -0
  140. package/test/character-reference/index.spec.js +57 -0
  141. package/test/class-naming/index.spec.js +470 -0
  142. package/test/create-message.spec.js +497 -0
  143. package/test/deprecated-attr/index.spec.js +48 -0
  144. package/test/deprecated-element/index.spec.js +48 -0
  145. package/test/disallowed-element/index.spec.js +90 -0
  146. package/test/doctype/index.spec.js +50 -0
  147. package/test/end-tag/index.spec.js +162 -0
  148. package/test/id-duplication/index.spec.js +47 -0
  149. package/test/ineffective-attr/index.spec.js +31 -0
  150. package/test/invalid-attr/index.spec.js +1632 -0
  151. package/test/label-has-control/index.spec.js +29 -0
  152. package/test/landmark-roles/index.spec.js +187 -0
  153. package/test/no-boolean-attr-value/index.spec.js +41 -0
  154. package/test/no-default-value/index.spec.js +74 -0
  155. package/test/no-empty-palpable-content/index.spec.js +115 -0
  156. package/test/no-hard-code-id/index.spec.js +100 -0
  157. package/test/no-refer-to-non-existent-id/index.spec.js +254 -0
  158. package/test/no-use-event-handler-attr/index.spec.js +57 -0
  159. package/test/permitted-contents/choice.spec.js +174 -0
  160. package/test/permitted-contents/count-pattern.spec.js +308 -0
  161. package/test/permitted-contents/index.spec.js +1371 -0
  162. package/test/permitted-contents/matches-selector.spec.js +59 -0
  163. package/test/permitted-contents/order.spec.js +351 -0
  164. package/test/permitted-contents/recursive-branch.spec.js +41 -0
  165. package/test/permitted-contents/represent-transparent-nodes.spec.js +24 -0
  166. package/test/permitted-contents/start.spec.js +67 -0
  167. package/test/placeholder-label-option/index.spec.js +113 -0
  168. package/test/require-accessible-name/index.spec.js +446 -0
  169. package/test/require-datetime/index.spec.js +54 -0
  170. package/test/require-datetime/utils.spec.js +52 -0
  171. package/test/required-attr/index.spec.js +414 -0
  172. package/test/required-element/index.spec.js +188 -0
  173. package/test/required-h1/index.spec.js +69 -0
  174. package/test/use-list/index.spec.js +109 -0
  175. package/test/wai-aria/checkings/value.spec.js +33 -0
  176. package/test/wai-aria/index.spec.js +1173 -0
  177. package/lib/__foo/index.d.ts +0 -2
  178. package/lib/__foo/index.js +0 -46
  179. package/lib/attr-equal-space-after/index.d.ts +0 -3
  180. package/lib/attr-equal-space-after/index.js +0 -90
  181. package/lib/attr-equal-space-before/index.d.ts +0 -3
  182. package/lib/attr-equal-space-before/index.js +0 -90
  183. package/lib/attr-spacing/index.d.ts +0 -6
  184. package/lib/attr-spacing/index.js +0 -100
  185. package/lib/helper/aria/get-aria.d.ts +0 -7
  186. package/lib/helper/aria/get-aria.js +0 -53
  187. package/lib/helper/aria/get-computed-role.d.ts +0 -10
  188. package/lib/helper/aria/get-computed-role.js +0 -24
  189. package/lib/helper/aria/get-implicit-role.d.ts +0 -7
  190. package/lib/helper/aria/get-implicit-role.js +0 -12
  191. package/lib/helper/aria/get-permitted-roles.d.ts +0 -14
  192. package/lib/helper/aria/get-permitted-roles.js +0 -26
  193. package/lib/helper/aria/resolve-version.d.ts +0 -2
  194. package/lib/helper/aria/resolve-version.js +0 -21
  195. package/lib/helper/spec/aria-spec.d.ts +0 -5
  196. package/lib/helper/spec/aria-spec.js +0 -12
  197. package/lib/helper/spec/get-role-spec.d.ts +0 -11
  198. package/lib/helper/spec/get-role-spec.js +0 -39
  199. package/lib/helper/spec/html-spec.d.ts +0 -2
  200. package/lib/helper/spec/html-spec.js +0 -14
  201. package/lib/indentation/index.d.ts +0 -7
  202. package/lib/indentation/index.js +0 -208
  203. package/lib/permitted-contents/array.combination.d.ts +0 -1
  204. package/lib/permitted-contents/array.combination.js +0 -33
  205. package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +0 -11
  206. package/lib/permitted-contents/permitted-content.spec-to-regexp.js +0 -230
  207. package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +0 -2
  208. package/lib/permitted-contents/unfold-content-models-to-tags.js +0 -8
  209. package/lib/wai-aria/checkings/checking-required-owned-elements.js +0 -63
  210. package/tsconfig.test.json +0 -3
  211. package/tsconfig.tsbuildinfo +0 -1
@@ -1,2 +1,4 @@
1
- declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, null>;
1
+ declare const _default: Readonly<
2
+ import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
3
+ >;
2
4
  export default _default;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
+ const shared_1 = require("@markuplint/shared");
4
5
  exports.default = (0, ml_core_1.createRule)({
5
- defaultServerity: 'warning',
6
+ defaultSeverity: 'warning',
6
7
  async verify({ document, report, t }) {
7
8
  await document.walkOn('Attr', attr => {
8
9
  const attrSpec = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);
@@ -14,11 +15,7 @@ exports.default = (0, ml_core_1.createRule)({
14
15
  if (!spec) {
15
16
  return;
16
17
  }
17
- const ineffectiveConditions = spec.ineffective
18
- ? Array.isArray(spec.ineffective)
19
- ? spec.ineffective
20
- : [spec.ineffective]
21
- : [];
18
+ const ineffectiveConditions = (0, shared_1.toNoEmptyStringArrayFromStringOrArray)(spec.ineffective);
22
19
  if (ineffectiveConditions.some(selector => attr.ownerElement.matches(selector))) {
23
20
  report({
24
21
  scope: attr,
@@ -1,16 +1,44 @@
1
1
  import type { AttributeType } from '@markuplint/ml-spec';
2
- declare type Option = {
3
- attrs?: Record<string, Rule>;
4
- ignoreAttrNamePrefix?: string | string[];
2
+ type Option = {
3
+ /**
4
+ * @since 3.7.0
5
+ */
6
+ allowAttrs?: (string | Attr)[] | Record<string, ValueRule>;
7
+ /**
8
+ * @since 3.7.0
9
+ */
10
+ disallowAttrs?: (string | Attr)[] | Record<string, ValueRule>;
11
+ ignoreAttrNamePrefix?: string | string[];
12
+ allowToAddPropertiesForPretender?: boolean;
13
+ /**
14
+ * @deprecated Since version 3.7.0. Use `allowAttrs` or `disallowAttrs` instead.
15
+ * This option (`attr`) is now considered ambiguous and may lead to confusion.
16
+ * Please use the more explicit `allowAttrs` or `disallowAttrs` option
17
+ * to specify allowed attributes for the `invalid-attr` rule.
18
+ * @see {@link Option.allowAttrs}
19
+ * @see {@link Option.disallowAttrs}
20
+ */
21
+ attrs?: Record<
22
+ string,
23
+ | ValueRule
24
+ | {
25
+ disallowed: true;
26
+ }
27
+ >;
5
28
  };
6
- declare type Rule = {
7
- enum: [string, ...string[]];
8
- } | {
9
- pattern: string;
10
- } | {
11
- type: AttributeType;
12
- } | {
13
- disallowed: true;
29
+ type Attr = {
30
+ name: string;
31
+ value: AttributeType | ValueRule;
14
32
  };
15
- declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Option>;
33
+ type ValueRule =
34
+ | {
35
+ enum: [string, ...string[]];
36
+ }
37
+ | {
38
+ pattern: string;
39
+ }
40
+ | {
41
+ type: AttributeType;
42
+ };
43
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Option>>;
16
44
  export default _default;
@@ -9,14 +9,16 @@ exports.default = (0, ml_core_1.createRule)({
9
9
  defaultOptions: {},
10
10
  async verify({ document, report, t }) {
11
11
  await document.walkOn('Attr', attr => {
12
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
12
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
13
+ // Default
14
+ const allowToAddPropertiesForPretender = (_a = attr.rule.options.allowToAddPropertiesForPretender) !== null && _a !== void 0 ? _a : true;
13
15
  if (attr.isDirective) {
14
16
  return;
15
17
  }
16
18
  const attrSpecs = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);
17
19
  const attrName = attr.nameNode;
18
20
  const name = attr.name;
19
- if (!attr.ownerElement.isCustomElement && attr.candidate) {
21
+ if (attr.ownerElement.elementType === 'html' && attr.candidate) {
20
22
  const message = t('{0} is {1:c}', t('the "{0*}" {1}', name, 'attribute'), 'disallowed') +
21
23
  t('. ') +
22
24
  t('Did you mean "{0}"?', attr.candidate);
@@ -31,50 +33,150 @@ exports.default = (0, ml_core_1.createRule)({
31
33
  }
32
34
  const valueNode = attr.valueNode;
33
35
  const value = attr.value;
34
- if (attr.rule.option.ignoreAttrNamePrefix) {
35
- const ignoreAttrNamePrefixes = Array.isArray(attr.rule.option.ignoreAttrNamePrefix)
36
- ? attr.rule.option.ignoreAttrNamePrefix
37
- : [attr.rule.option.ignoreAttrNamePrefix];
36
+ if (attr.rule.options.ignoreAttrNamePrefix != null) {
37
+ const ignoreAttrNamePrefixes = Array.isArray(attr.rule.options.ignoreAttrNamePrefix)
38
+ ? attr.rule.options.ignoreAttrNamePrefix
39
+ : [attr.rule.options.ignoreAttrNamePrefix];
38
40
  if (ignoreAttrNamePrefixes.some(prefix => name.indexOf(prefix) === 0)) {
39
41
  return;
40
42
  }
41
43
  }
42
44
  let invalid = false;
43
- const customRule = attr.rule.option.attrs ? attr.rule.option.attrs[name] : null;
44
- if (customRule) {
45
- if ('enum' in customRule) {
45
+ const allowAttrs = {};
46
+ const disallowAttrs = {};
47
+ if (attr.rule.options.allowAttrs) {
48
+ if (Array.isArray(attr.rule.options.allowAttrs)) {
49
+ for (const allowAttr of attr.rule.options.allowAttrs) {
50
+ if (typeof allowAttr === 'string') {
51
+ allowAttrs[allowAttr] = { type: 'Any' };
52
+ continue;
53
+ }
54
+ if (isValueRule(allowAttr.value)) {
55
+ allowAttrs[allowAttr.name] = allowAttr.value;
56
+ continue;
57
+ }
58
+ allowAttrs[allowAttr.name] = { type: allowAttr.value };
59
+ }
60
+ }
61
+ else {
62
+ for (const [attrName, valueRule] of Object.entries(attr.rule.options.allowAttrs)) {
63
+ allowAttrs[attrName] = valueRule;
64
+ }
65
+ }
66
+ }
67
+ if (attr.rule.options.disallowAttrs) {
68
+ if (Array.isArray(attr.rule.options.disallowAttrs)) {
69
+ for (const disallowAttr of attr.rule.options.disallowAttrs) {
70
+ if (typeof disallowAttr === 'string') {
71
+ disallowAttrs[disallowAttr] = { type: 'Any' };
72
+ continue;
73
+ }
74
+ if (isValueRule(disallowAttr.value)) {
75
+ disallowAttrs[disallowAttr.name] = disallowAttr.value;
76
+ continue;
77
+ }
78
+ disallowAttrs[disallowAttr.name] = { type: disallowAttr.value };
79
+ }
80
+ }
81
+ else {
82
+ for (const [attrName, valueRule] of Object.entries(attr.rule.options.disallowAttrs)) {
83
+ disallowAttrs[attrName] = valueRule;
84
+ }
85
+ }
86
+ }
87
+ if (attr.rule.options.attrs) {
88
+ for (const [attrName, valueRule] of Object.entries(attr.rule.options.attrs)) {
89
+ if ('disallowed' in valueRule) {
90
+ disallowAttrs[attrName] = { type: 'Any' };
91
+ }
92
+ else {
93
+ allowAttrs[attrName] = valueRule;
94
+ }
95
+ }
96
+ }
97
+ const allowValue = (_b = allowAttrs[name]) !== null && _b !== void 0 ? _b : null;
98
+ const disallowValue = (_c = disallowAttrs[name]) !== null && _c !== void 0 ? _c : null;
99
+ if (allowValue) {
100
+ if ('enum' in allowValue) {
46
101
  invalid = (0, attr_check_1.attrCheck)(t, name.toLowerCase(), value, true, {
47
102
  name,
48
103
  type: {
49
- enum: customRule.enum,
104
+ enum: allowValue.enum,
50
105
  },
51
106
  description: '',
52
107
  });
53
108
  }
54
- else if ('pattern' in customRule) {
55
- if (!(0, helpers_1.match)(value, customRule.pattern)) {
109
+ else if ('pattern' in allowValue) {
110
+ if (!(0, helpers_1.match)(value, allowValue.pattern)) {
111
+ invalid = {
112
+ invalidType: 'invalid-value',
113
+ message: t('{0} is unmatched with the below patterns: {1}', t('the "{0*}" {1}', name, 'attribute'), allowValue.pattern),
114
+ };
115
+ }
116
+ }
117
+ else if ('type' in allowValue) {
118
+ invalid = (0, attr_check_1.attrCheck)(t, name, value, true, { name, type: allowValue.type, description: '' });
119
+ }
120
+ }
121
+ else if (disallowValue) {
122
+ if ('enum' in disallowValue) {
123
+ const checkResult = (0, attr_check_1.attrCheck)(t, name.toLowerCase(), value, true, {
124
+ name,
125
+ type: {
126
+ enum: disallowValue.enum,
127
+ },
128
+ description: '',
129
+ });
130
+ if (checkResult === false) {
56
131
  invalid = {
57
132
  invalidType: 'invalid-value',
58
- message: t('{0} is unmatched with the below patterns: {1}', t('the "{0*}" {1}', name, 'attribute'), customRule.pattern),
133
+ message: t('{0} is disallowed to accept the following values: {1}', t('the "{0*}" {1}', name, 'attribute'), t(disallowValue.enum)),
59
134
  };
60
135
  }
61
136
  }
62
- else if ('type' in customRule) {
63
- invalid = (0, attr_check_1.attrCheck)(t, name, value, true, { name, type: customRule.type, description: '' });
137
+ else if ('pattern' in disallowValue) {
138
+ if ((0, helpers_1.match)(value, disallowValue.pattern)) {
139
+ invalid = {
140
+ invalidType: 'invalid-value',
141
+ message: t('{0} is matched with the below disallowed patterns: {1}', t('the "{0*}" {1}', name, 'attribute'), disallowValue.pattern),
142
+ };
143
+ }
64
144
  }
65
- else if ('disallowed' in customRule && customRule.disallowed) {
66
- invalid = {
67
- invalidType: 'non-existent',
68
- message: t('{0} is disallowed', t('the "{0*}" {1}', name, 'attribute')),
69
- };
145
+ else if ('type' in disallowValue) {
146
+ if (disallowValue.type === 'Any') {
147
+ invalid = {
148
+ invalidType: 'non-existent',
149
+ message: t('{0} is disallowed', t('the "{0*}" {1}', name, 'attribute')),
150
+ };
151
+ }
152
+ else {
153
+ const checkResult = (0, attr_check_1.attrCheck)(t, name, value, true, {
154
+ name,
155
+ type: disallowValue.type,
156
+ description: '',
157
+ });
158
+ if (checkResult === false) {
159
+ invalid = {
160
+ invalidType: 'invalid-value',
161
+ message: t('{0} is disallowed', t('{0} of {1}', t('the {0}', 'type'), t('the "{0*}" {1}', name, 'attribute'))),
162
+ };
163
+ }
164
+ }
70
165
  }
71
166
  }
72
- else if (!attr.ownerElement.isCustomElement && attrSpecs) {
167
+ else if (attr.ownerElement.elementType === 'html' && attrSpecs) {
73
168
  log('Checking %s[%s="%s"]', attr.nodeName, name, value);
74
169
  invalid = (0, helpers_1.isValidAttr)(t, name, value, attr.isDynamicValue || false, attr.ownerElement, attrSpecs, log);
75
170
  }
76
- if (invalid) {
171
+ if (invalid !== false) {
77
172
  switch (invalid.invalidType) {
173
+ case 'disallowed-attr': {
174
+ report({
175
+ scope: attr,
176
+ message: invalid.message,
177
+ });
178
+ break;
179
+ }
78
180
  case 'invalid-value': {
79
181
  if (attr.isDynamicValue) {
80
182
  break;
@@ -82,16 +184,19 @@ exports.default = (0, ml_core_1.createRule)({
82
184
  report({
83
185
  scope: attr,
84
186
  message: invalid.message,
85
- line: ((_a = valueNode === null || valueNode === void 0 ? void 0 : valueNode.startLine) !== null && _a !== void 0 ? _a : 0) + ((_c = (_b = invalid.loc) === null || _b === void 0 ? void 0 : _b.line) !== null && _c !== void 0 ? _c : 0),
86
- col: ((_d = invalid.loc) === null || _d === void 0 ? void 0 : _d.line)
87
- ? ((_e = invalid.loc) === null || _e === void 0 ? void 0 : _e.col) + 1
88
- : ((_f = valueNode === null || valueNode === void 0 ? void 0 : valueNode.startCol) !== null && _f !== void 0 ? _f : 0) + ((_h = (_g = invalid.loc) === null || _g === void 0 ? void 0 : _g.col) !== null && _h !== void 0 ? _h : 0),
89
- raw: (_k = (_j = invalid.loc) === null || _j === void 0 ? void 0 : _j.raw) !== null && _k !== void 0 ? _k : value,
187
+ line: ((_d = valueNode === null || valueNode === void 0 ? void 0 : valueNode.startLine) !== null && _d !== void 0 ? _d : 0) + ((_f = (_e = invalid.loc) === null || _e === void 0 ? void 0 : _e.line) !== null && _f !== void 0 ? _f : 0),
188
+ col: invalid.loc && invalid.loc.line > 0
189
+ ? ((_g = invalid.loc) === null || _g === void 0 ? void 0 : _g.col) + 1
190
+ : ((_h = valueNode === null || valueNode === void 0 ? void 0 : valueNode.startCol) !== null && _h !== void 0 ? _h : 0) + ((_k = (_j = invalid.loc) === null || _j === void 0 ? void 0 : _j.col) !== null && _k !== void 0 ? _k : 0),
191
+ raw: (_m = (_l = invalid.loc) === null || _l === void 0 ? void 0 : _l.raw) !== null && _m !== void 0 ? _m : value,
90
192
  });
91
193
  break;
92
194
  }
93
195
  case 'non-existent': {
94
- const spec = (0, ml_core_1.getSpec)(attr.ownerElement, document.specs);
196
+ if (allowToAddPropertiesForPretender && ((_o = attr.ownerElement.pretenderContext) === null || _o === void 0 ? void 0 : _o.type) === 'origin') {
197
+ return;
198
+ }
199
+ const spec = (0, ml_core_1.getSpec)(attr.ownerElement, document.specs.specs);
95
200
  if (spec === null || spec === void 0 ? void 0 : spec.possibleToAddProperties) {
96
201
  return;
97
202
  }
@@ -108,3 +213,29 @@ exports.default = (0, ml_core_1.createRule)({
108
213
  });
109
214
  },
110
215
  });
216
+ function isValueRule(
217
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
218
+ value) {
219
+ if (typeof value === 'string') {
220
+ return false;
221
+ }
222
+ if ('enum' in value) {
223
+ if (Object.keys(value).length > 1) {
224
+ return false;
225
+ }
226
+ return true;
227
+ }
228
+ if ('token' in value) {
229
+ return false;
230
+ }
231
+ if ('pattern' in value) {
232
+ return true;
233
+ }
234
+ if (value.type === 'integer' || value.type === 'float') {
235
+ return false;
236
+ }
237
+ if (Object.keys(value).length > 1) {
238
+ return false;
239
+ }
240
+ return true;
241
+ }
@@ -0,0 +1,4 @@
1
+ declare const _default: Readonly<
2
+ import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
3
+ >;
4
+ export default _default;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ml_core_1 = require("@markuplint/ml-core");
4
+ const controlSelector = ["input:not([type='hidden' i])", 'select', 'textarea'].join(',');
5
+ exports.default = (0, ml_core_1.createRule)({
6
+ defaultSeverity: 'warning',
7
+ async verify({ document, report, t }) {
8
+ await document.walkOn('Element', el => {
9
+ if (el.localName !== 'label') {
10
+ return;
11
+ }
12
+ if (el.children.length === 0 && !el.hasAttribute('for')) {
13
+ report({
14
+ scope: el,
15
+ message: t('{0} should associate with {1}', t('The "{0*}" {1}', 'label', 'element'), t('a {0}', 'control')),
16
+ });
17
+ }
18
+ const controls = el.querySelectorAll(controlSelector);
19
+ const secondControl = controls[1];
20
+ if (secondControl) {
21
+ report({
22
+ scope: secondControl,
23
+ message: t('{0} associates only {1}', t('The "{0*}" {1}', 'label', 'element'), t('first {0}', 'control')),
24
+ });
25
+ }
26
+ });
27
+ },
28
+ });
@@ -1,8 +1,8 @@
1
- declare type Options = {
2
- ignoreRoles: Roles[];
3
- labelEachArea: boolean;
1
+ type Options = {
2
+ ignoreRoles: Roles[];
3
+ labelEachArea: boolean;
4
4
  };
5
- declare type TopLevelRoles = 'banner' | 'main' | 'complementary' | 'contentinfo';
6
- declare type Roles = TopLevelRoles | 'form' | 'navigation' | 'region';
7
- declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Options>;
5
+ type TopLevelRoles = 'banner' | 'main' | 'complementary' | 'contentinfo';
6
+ type Roles = TopLevelRoles | 'form' | 'navigation' | 'region';
7
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
8
8
  export default _default;
@@ -12,7 +12,7 @@ const selectors = {
12
12
  };
13
13
  const topLevelRoles = ['banner', 'main', 'complementary', 'contentinfo'];
14
14
  exports.default = (0, ml_core_1.createRule)({
15
- defaultServerity: 'warning',
15
+ defaultSeverity: 'warning',
16
16
  defaultOptions: {
17
17
  ignoreRoles: [],
18
18
  labelEachArea: true,
@@ -72,7 +72,7 @@ exports.default = (0, ml_core_1.createRule)({
72
72
  if (el.rule.disabled) {
73
73
  continue;
74
74
  }
75
- if ((_a = el.rule.option.ignoreRoles) === null || _a === void 0 ? void 0 : _a.includes(role)) {
75
+ if ((_a = el.rule.options.ignoreRoles) === null || _a === void 0 ? void 0 : _a.includes(role)) {
76
76
  continue;
77
77
  }
78
78
  if (el.isDescendantByUUIDList(uuidList)) {
@@ -93,7 +93,7 @@ exports.default = (0, ml_core_1.createRule)({
93
93
  if (el.rule.disabled) {
94
94
  continue;
95
95
  }
96
- if (!el.rule.option.labelEachArea) {
96
+ if (!el.rule.options.labelEachArea) {
97
97
  continue;
98
98
  }
99
99
  if (!hasLabel(el)) {
@@ -106,13 +106,17 @@ exports.default = (0, ml_core_1.createRule)({
106
106
  }
107
107
  },
108
108
  });
109
- function landmarkRoleElementUUIDList(roleset) {
109
+ function landmarkRoleElementUUIDList(
110
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
111
+ roleset) {
110
112
  return Object.values(roleset)
111
113
  .map(elements => elements.map(element => element.uuid))
112
114
  .flat();
113
115
  }
114
- function hasLabel(el) {
115
- const hasHeading = !!el.querySelectorAll('h1, h2, h3, h4, h5, h6').length;
116
+ function hasLabel(
117
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
118
+ el) {
119
+ const hasHeading = el.querySelectorAll('h1, h2, h3, h4, h5, h6').length > 0;
116
120
  if (hasHeading && el.matches('[aria-labelledby]')) {
117
121
  return true;
118
122
  }
@@ -1,2 +1,4 @@
1
- declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, null>;
1
+ declare const _default: Readonly<
2
+ import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
3
+ >;
2
4
  export default _default;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
4
  exports.default = (0, ml_core_1.createRule)({
5
- defaultServerity: 'warning',
5
+ defaultSeverity: 'warning',
6
6
  async verify({ document, report, t }) {
7
7
  await document.walkOn('Attr', attr => {
8
8
  var _a, _b;
@@ -1,2 +1,4 @@
1
- declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, null>;
1
+ declare const _default: Readonly<
2
+ import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
3
+ >;
2
4
  export default _default;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
4
  const helpers_1 = require("../helpers");
5
5
  exports.default = (0, ml_core_1.createRule)({
6
- defaultServerity: 'warning',
6
+ defaultSeverity: 'warning',
7
7
  async verify({ document, report, t }) {
8
8
  await document.walkOn('Attr', attr => {
9
9
  var _a, _b, _c;
@@ -0,0 +1,6 @@
1
+ type Options = {
2
+ extendsExposableElements?: boolean;
3
+ ignoreIfAriaBusy?: boolean;
4
+ };
5
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
6
+ export default _default;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ml_core_1 = require("@markuplint/ml-core");
4
+ const ml_spec_1 = require("@markuplint/ml-spec");
5
+ exports.default = (0, ml_core_1.createRule)({
6
+ defaultSeverity: 'warning',
7
+ defaultOptions: {
8
+ extendsExposableElements: true,
9
+ ignoreIfAriaBusy: true,
10
+ },
11
+ async verify({ document, report, t }) {
12
+ await document.walkOn('Element', el => {
13
+ /**
14
+ * Exception
15
+ *
16
+ * - The `textarea` element is possibly empty because a user inputs it.
17
+ */
18
+ if (el.localName === 'textarea') {
19
+ return;
20
+ }
21
+ if (!(0, ml_spec_1.isPalpableElement)(el, el.ownerMLDocument.specs, {
22
+ extendsSvg: false,
23
+ extendsExposableElements: el.rule.options.extendsExposableElements,
24
+ })) {
25
+ return;
26
+ }
27
+ if ((0, ml_spec_1.isNothingContentModel)(el)) {
28
+ return;
29
+ }
30
+ if (el.rule.options.ignoreIfAriaBusy && el.getAttribute('aria-busy') === 'true') {
31
+ return;
32
+ }
33
+ const isEmpty = Array.from(el.childNodes).every(node => node.is(node.TEXT_NODE) && node.isWhitespace());
34
+ if (isEmpty) {
35
+ report({
36
+ scope: el,
37
+ message: t('{0} should not {1}', t('the {0}', 'element'), 'empty'),
38
+ });
39
+ }
40
+ });
41
+ },
42
+ });
@@ -1,2 +1,4 @@
1
- declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, null>;
1
+ declare const _default: Readonly<
2
+ import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
3
+ >;
2
4
  export default _default;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
4
  exports.default = (0, ml_core_1.createRule)({
5
- defaultServerity: 'warning',
5
+ defaultSeverity: 'warning',
6
6
  async verify({ document, report, t }) {
7
7
  if (!document.isFragment) {
8
8
  return;
@@ -1,5 +1,10 @@
1
- import type { ARIAVersion } from '@markuplint/ml-spec';
2
- declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
3
- ariaVersion: ARIAVersion;
4
- }>;
1
+ declare const _default: Readonly<
2
+ import('@markuplint/ml-core').RuleSeed<
3
+ import('@markuplint/ml-core').RuleConfigValue,
4
+ {
5
+ ariaVersion: '1.1' | '1.2' | '1.3';
6
+ fragmentRefersNameAttr: boolean;
7
+ }
8
+ >
9
+ >;
5
10
  export default _default;