@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
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ var _Collection_locked, _Collection_matched, _Collection_nodes, _Collection_origin;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.modelLog = exports.UnsupportedError = exports.Collection = exports.cleanObject = exports.mergeHints = exports.normalizeModel = exports.isTransparent = exports.isChoice = exports.isZeroOrMore = exports.isOneOrMore = exports.isOptional = exports.isRequire = exports.matches = exports.isModel = exports.getChildNodesWithoutWhitespaces = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const selector_1 = require("@markuplint/selector");
7
+ const debug_1 = require("./debug");
8
+ const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
9
+ const getChildNodesWithoutWhitespacesCaches = new Map();
10
+ function getChildNodesWithoutWhitespaces(
11
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
12
+ el) {
13
+ let nodes = getChildNodesWithoutWhitespacesCaches.get(el);
14
+ if (nodes) {
15
+ return nodes;
16
+ }
17
+ nodes = Array.from(el.childNodes).filter(node => {
18
+ return !(node.is(node.TEXT_NODE) && node.isWhitespace());
19
+ });
20
+ getChildNodesWithoutWhitespacesCaches.set(el, nodes);
21
+ return nodes;
22
+ }
23
+ exports.getChildNodesWithoutWhitespaces = getChildNodesWithoutWhitespaces;
24
+ function isModel(model) {
25
+ if (typeof model === 'string') {
26
+ return true;
27
+ }
28
+ let modelMode = false;
29
+ for (const m of model) {
30
+ if (typeof m === 'string') {
31
+ modelMode = true;
32
+ continue;
33
+ }
34
+ if (modelMode) {
35
+ throw new TypeError(`Invalid schema: ${JSON.stringify(model)}`);
36
+ }
37
+ }
38
+ return modelMode;
39
+ }
40
+ exports.isModel = isModel;
41
+ function matches(selector,
42
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
43
+ node, specs) {
44
+ const selectorResult = (0, selector_1.createSelector)(selector, specs).search(node);
45
+ const matched = selectorResult.filter((r) => r.matched);
46
+ if (matched.length > 0) {
47
+ return {
48
+ matched: true,
49
+ };
50
+ }
51
+ const not = selectorResult
52
+ .map(r => { var _a; return (r.matched ? [] : (_a = r.not) !== null && _a !== void 0 ? _a : []); })
53
+ .flat()
54
+ .map(descendants)
55
+ .flat()
56
+ .shift();
57
+ return {
58
+ matched: false,
59
+ not,
60
+ };
61
+ }
62
+ exports.matches = matches;
63
+ function descendants(
64
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
65
+ selectorResult) {
66
+ let nodes = selectorResult.nodes.slice();
67
+ while (selectorResult.has.length > 0) {
68
+ for (const dep of selectorResult.has) {
69
+ if (dep.has.length === 0) {
70
+ nodes = dep.nodes;
71
+ continue;
72
+ }
73
+ selectorResult = dep;
74
+ continue;
75
+ }
76
+ break;
77
+ }
78
+ return nodes;
79
+ }
80
+ function isRequire(content) {
81
+ return 'require' in content;
82
+ }
83
+ exports.isRequire = isRequire;
84
+ function isOptional(content) {
85
+ return 'optional' in content;
86
+ }
87
+ exports.isOptional = isOptional;
88
+ function isOneOrMore(content) {
89
+ return 'oneOrMore' in content;
90
+ }
91
+ exports.isOneOrMore = isOneOrMore;
92
+ function isZeroOrMore(content) {
93
+ return 'zeroOrMore' in content;
94
+ }
95
+ exports.isZeroOrMore = isZeroOrMore;
96
+ function isChoice(content) {
97
+ return 'choice' in content;
98
+ }
99
+ exports.isChoice = isChoice;
100
+ function isTransparent(content) {
101
+ return 'transparent' in content;
102
+ }
103
+ exports.isTransparent = isTransparent;
104
+ function normalizeModel(pattern) {
105
+ var _a, _b, _c, _d, _e;
106
+ let model;
107
+ let min;
108
+ let max;
109
+ let repeat;
110
+ let missingType;
111
+ if (isRequire(pattern)) {
112
+ model = pattern.require;
113
+ min = (_a = pattern.min) !== null && _a !== void 0 ? _a : 1;
114
+ max = Math.max((_b = pattern.max) !== null && _b !== void 0 ? _b : 1, min);
115
+ missingType = 'MISSING_NODE_REQUIRED';
116
+ }
117
+ else if (isOptional(pattern)) {
118
+ model = pattern.optional;
119
+ min = 0;
120
+ max = Math.max((_c = pattern.max) !== null && _c !== void 0 ? _c : 1, 1);
121
+ }
122
+ else if (isOneOrMore(pattern)) {
123
+ model = pattern.oneOrMore;
124
+ min = 1;
125
+ max = Math.max((_d = pattern.max) !== null && _d !== void 0 ? _d : Infinity, 1);
126
+ missingType = 'MISSING_NODE_ONE_OR_MORE';
127
+ }
128
+ else if (isZeroOrMore(pattern)) {
129
+ model = pattern.zeroOrMore;
130
+ min = 0;
131
+ max = Math.max((_e = pattern.max) !== null && _e !== void 0 ? _e : Infinity, 1);
132
+ }
133
+ else {
134
+ throw new Error('Unreachable code');
135
+ }
136
+ if (min === 0 && max === 1) {
137
+ repeat = '?';
138
+ }
139
+ else if (min === 0 && !Number.isFinite(max)) {
140
+ repeat = '*';
141
+ }
142
+ else if (min === 1 && max === 1) {
143
+ repeat = '';
144
+ }
145
+ else if (min === 1 && !Number.isFinite(max)) {
146
+ repeat = '+';
147
+ }
148
+ else {
149
+ repeat = `{${min},${max}}`;
150
+ }
151
+ return {
152
+ model,
153
+ min,
154
+ max,
155
+ repeat,
156
+ missingType,
157
+ };
158
+ }
159
+ exports.normalizeModel = normalizeModel;
160
+ function mergeHints(
161
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
162
+ a,
163
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
164
+ b) {
165
+ const missing = [a.missing, b.missing].sort((a, b) => { var _a, _b; return ((_a = b === null || b === void 0 ? void 0 : b.barelyMatchedElements) !== null && _a !== void 0 ? _a : 0) - ((_b = a === null || a === void 0 ? void 0 : a.barelyMatchedElements) !== null && _b !== void 0 ? _b : 0); })[0];
166
+ return cleanObject({
167
+ ...a,
168
+ ...b,
169
+ missing: missing && cleanObject(missing),
170
+ });
171
+ }
172
+ exports.mergeHints = mergeHints;
173
+ function cleanObject(object) {
174
+ const newObject = {};
175
+ Object.entries(object).forEach(([key, value]) => {
176
+ if (value !== undefined) {
177
+ newObject[key] = value;
178
+ }
179
+ });
180
+ return newObject;
181
+ }
182
+ exports.cleanObject = cleanObject;
183
+ class Collection {
184
+ constructor(
185
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
186
+ origin) {
187
+ _Collection_locked.set(this, new Set());
188
+ _Collection_matched.set(this, new Set());
189
+ _Collection_nodes.set(this, void 0);
190
+ _Collection_origin.set(this, void 0);
191
+ tslib_1.__classPrivateFieldSet(this, _Collection_origin, origin.slice(), "f");
192
+ tslib_1.__classPrivateFieldSet(this, _Collection_nodes, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f")), "f");
193
+ }
194
+ get matched() {
195
+ return Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f"));
196
+ }
197
+ get matchedCount() {
198
+ return tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
199
+ }
200
+ get nodes() {
201
+ return tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f").slice();
202
+ }
203
+ get unmatched() {
204
+ return Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_nodes, "f")).filter(n => !tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n));
205
+ }
206
+ addMatched(
207
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
208
+ nodes) {
209
+ const i = tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
210
+ for (const node of nodes) {
211
+ if (!tslib_1.__classPrivateFieldGet(this, _Collection_nodes, "f").has(node)) {
212
+ throw new ReferenceError(`External Node: ${node.nodeName}`);
213
+ }
214
+ tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").add(node);
215
+ }
216
+ return i < tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
217
+ }
218
+ back() {
219
+ tslib_1.__classPrivateFieldSet(this, _Collection_matched, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f")), "f");
220
+ }
221
+ lock() {
222
+ tslib_1.__classPrivateFieldSet(this, _Collection_locked, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f")), "f");
223
+ }
224
+ max(max) {
225
+ const sliced = Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f")).slice(max);
226
+ sliced.forEach(n => tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").delete(n));
227
+ }
228
+ toString(highlightExtraNodes = false) {
229
+ const out = [];
230
+ for (const n of tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f")) {
231
+ const raw = n.is(n.TEXT_NODE) ? `:text(${n.raw.replace(/\n/g, '\\n')})` : n.raw;
232
+ if (tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f").has(n)) {
233
+ if (represent_transparent_nodes_1.transparentMode.has(n)) {
234
+ out.push(debug_1.bgBlue.bold(raw));
235
+ }
236
+ else {
237
+ out.push(debug_1.bgGreen.bold(raw));
238
+ }
239
+ continue;
240
+ }
241
+ if (tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n)) {
242
+ if (represent_transparent_nodes_1.transparentMode.has(n)) {
243
+ out.push(debug_1.blue.bold(raw));
244
+ }
245
+ else {
246
+ out.push(debug_1.green.bold(raw));
247
+ }
248
+ continue;
249
+ }
250
+ if (highlightExtraNodes) {
251
+ if (represent_transparent_nodes_1.transparentMode.has(n)) {
252
+ out.push(debug_1.bgMagenta.bold(raw));
253
+ }
254
+ else {
255
+ out.push(debug_1.bgRed.bold(raw));
256
+ }
257
+ continue;
258
+ }
259
+ if (represent_transparent_nodes_1.transparentMode.has(n)) {
260
+ out.push((0, debug_1.cyan)(raw));
261
+ }
262
+ else {
263
+ out.push(raw);
264
+ }
265
+ }
266
+ return `[ ${out.join(', ')} ]`;
267
+ }
268
+ }
269
+ exports.Collection = Collection;
270
+ _Collection_locked = new WeakMap(), _Collection_matched = new WeakMap(), _Collection_nodes = new WeakMap(), _Collection_origin = new WeakMap();
271
+ class UnsupportedError extends Error {
272
+ }
273
+ exports.UnsupportedError = UnsupportedError;
274
+ function modelLog(model, repeat) {
275
+ if (!isModel(model)) {
276
+ return orderLog(model, repeat);
277
+ }
278
+ if (typeof model === 'string') {
279
+ return `<${model}>${repeat}`;
280
+ }
281
+ return `(<${model.join('>|<')}>)${repeat}`;
282
+ }
283
+ exports.modelLog = modelLog;
284
+ function orderLog(order, repeat) {
285
+ return order.length === 1 && order[0]
286
+ ? markRepeat(patternLog(order[0]), repeat)
287
+ : markRepeat(order.map(pattern => patternLog(pattern)).join(''), repeat);
288
+ }
289
+ function patternLog(pattern) {
290
+ if (isTransparent(pattern)) {
291
+ // 適当
292
+ return `:transparent(${modelLog(pattern.transparent, '')})`;
293
+ }
294
+ if (isChoice(pattern)) {
295
+ return `(${pattern.choice.map(candidate => orderLog(candidate, '')).join('|')})`;
296
+ }
297
+ const { model, repeat } = normalizeModel(pattern);
298
+ return modelLog(model, repeat);
299
+ }
300
+ function markRepeat(pattern, repeat) {
301
+ return repeat ? `(${pattern})${repeat}` : pattern;
302
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, undefined>>;
2
+ export default _default;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ml_core_1 = require("@markuplint/ml-core");
4
+ exports.default = (0, ml_core_1.createRule)({
5
+ verify({ document, report, t }) {
6
+ document.querySelectorAll('select').forEach(select => {
7
+ if (hasPlaceholderLabelOption(select)) {
8
+ return;
9
+ }
10
+ if (!needPlaceholderLabelOption(select)) {
11
+ return;
12
+ }
13
+ report({
14
+ scope: select,
15
+ message: t('need {0}', t('the {0}', 'placeholder label option')),
16
+ });
17
+ });
18
+ },
19
+ });
20
+ /**
21
+ * > If a select element has a required attribute specified,
22
+ * > does not have a multiple attribute specified,
23
+ * > and has a display size of 1,
24
+ * > then the select element must have a placeholder label option.
25
+ *
26
+ * @param select
27
+ * @returns
28
+ */
29
+ function needPlaceholderLabelOption(
30
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
31
+ select) {
32
+ var _a;
33
+ const hasRequired = select.hasAttribute('required');
34
+ if (!hasRequired) {
35
+ return false;
36
+ }
37
+ const hasMultiple = select.hasAttribute('multiple');
38
+ if (hasMultiple) {
39
+ return false;
40
+ }
41
+ const size = (_a = select.getAttribute('size')) !== null && _a !== void 0 ? _a : '1';
42
+ if (size !== '1') {
43
+ return false;
44
+ }
45
+ return true;
46
+ }
47
+ /**
48
+ * > If a select element has a required attribute specified,
49
+ * > does not have a multiple attribute specified,
50
+ * > and has a display size of 1;
51
+ * > and if the value of the first option element
52
+ * > in the select element's list of options (if any) is the empty string,
53
+ * > and that option element's parent node is the select element (and not an optgroup element),
54
+ * > then that option is the select element's **placeholder label option**.
55
+ *
56
+ * @param select
57
+ * @returns
58
+ */
59
+ function hasPlaceholderLabelOption(
60
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
61
+ select) {
62
+ var _a, _b;
63
+ // > has a required attribute specified
64
+ if (!select.hasAttribute('required')) {
65
+ return false;
66
+ }
67
+ // > does not have a multiple attribute specified
68
+ if (select.hasAttribute('multiple')) {
69
+ return false;
70
+ }
71
+ // > has a display size of 1
72
+ const size = (_a = select.getAttribute('size')) !== null && _a !== void 0 ? _a : '1';
73
+ if (size !== '1') {
74
+ return false;
75
+ }
76
+ // > in the select element's list of options (if any) is the empty string
77
+ const firstOption = select.querySelector('option');
78
+ if (!firstOption) {
79
+ // if any
80
+ return true;
81
+ }
82
+ // > that option element's parent node is the select element (and not an optgroup element)
83
+ if (((_b = firstOption.parentElement) === null || _b === void 0 ? void 0 : _b.localName) === 'optgroup') {
84
+ return false;
85
+ }
86
+ const value = firstOption.getAttribute('value');
87
+ return value === '' || value === null;
88
+ }
@@ -1,6 +1,6 @@
1
1
  import type { ARIAVersion } from '@markuplint/ml-spec';
2
- declare type Option = {
3
- ariaVersion: ARIAVersion;
2
+ type Option = {
3
+ ariaVersion: ARIAVersion;
4
4
  };
5
- declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Option>;
5
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Option>>;
6
6
  export default _default;
@@ -1,25 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
+ const ml_spec_1 = require("@markuplint/ml-spec");
4
5
  const helpers_1 = require("../helpers");
5
6
  exports.default = (0, ml_core_1.createRule)({
6
7
  defaultOptions: {
7
- ariaVersion: '1.2',
8
+ ariaVersion: ml_spec_1.ARIA_RECOMMENDED_VERSION,
8
9
  },
9
10
  async verify({ document, report, t }) {
10
11
  await document.walkOn('Element', el => {
12
+ var _a;
13
+ if (((_a = el.pretenderContext) === null || _a === void 0 ? void 0 : _a.type) === 'pretender') {
14
+ return;
15
+ }
11
16
  if ((0, helpers_1.accnameMayBeMutable)(el, document)) {
12
17
  return;
13
18
  }
14
- const computed = (0, ml_core_1.getComputedRole)(document.specs, el, el.rule.option.ariaVersion);
19
+ if (!(0, ml_spec_1.isExposed)(el, document.specs, el.rule.options.ariaVersion)) {
20
+ return;
21
+ }
22
+ const computed = (0, ml_core_1.getComputedRole)(document.specs, el, el.rule.options.ariaVersion);
15
23
  if (!computed.role) {
16
24
  return;
17
25
  }
18
- const roleSpec = (0, ml_core_1.getRoleSpec)(document.specs, computed.role.name, el.namespaceURI, el.rule.option.ariaVersion);
26
+ const roleSpec = (0, ml_core_1.getRoleSpec)(document.specs, computed.role.name, el.namespaceURI, el.rule.options.ariaVersion);
19
27
  if (!roleSpec || !roleSpec.accessibleNameRequired) {
20
28
  return;
21
29
  }
22
- const hasAccessibleName = !!el.getAccessibleName().trim();
30
+ const hasAccessibleName = !!el.getAccessibleName(el.rule.options.ariaVersion).trim();
23
31
  if (!hasAccessibleName) {
24
32
  report({ scope: el, message: t('Require {0}', 'accessible name') });
25
33
  }
@@ -0,0 +1,6 @@
1
+ import type { Lang } from './types';
2
+ type Options = {
3
+ langs?: Lang[];
4
+ };
5
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
6
+ export default _default;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ml_core_1 = require("@markuplint/ml-core");
4
+ const types_1 = require("@markuplint/types");
5
+ const utils_1 = require("./utils");
6
+ exports.default = (0, ml_core_1.createRule)({
7
+ defaultOptions: {
8
+ langs: undefined,
9
+ },
10
+ verify({ document, report, t }) {
11
+ document.querySelectorAll('time:not([datetime])').forEach(time => {
12
+ if (time.hasMutableChildren()) {
13
+ return;
14
+ }
15
+ const content = time.textContent.trim();
16
+ const result = (0, types_1.check)(content, 'DateTime');
17
+ if (result.matched) {
18
+ return;
19
+ }
20
+ const candidate = (0, utils_1.getCandidateDatetimeString)(content, time.rule.options.langs);
21
+ if (candidate) {
22
+ report({
23
+ scope: time,
24
+ message: t('need {0*}', `datetime="${candidate}"`),
25
+ });
26
+ return;
27
+ }
28
+ report({
29
+ scope: time,
30
+ message: t('need {0}', t('the "{0*}" {1}', 'datetime', 'attribute')),
31
+ });
32
+ });
33
+ },
34
+ });
@@ -0,0 +1,10 @@
1
+ export type DateTimeKey = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'ms';
2
+ export type DateTimeData = Partial<Record<DateTimeKey, number>>;
3
+ export type DateTime = {
4
+ datetime: DateTimeData;
5
+ zone?: number;
6
+ };
7
+ /**
8
+ * @see https://github.com/wanasit/chrono#locales
9
+ */
10
+ export type Lang = 'en' | 'ja' | 'fr' | 'nl' | 'ru' | 'de' | 'pt' | 'zh';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import type { DateTime, Lang } from './types';
2
+ /**
3
+ * Datetime-ish text to a datetime data
4
+ *
5
+ * @param content
6
+ * @param langs
7
+ * @param base Reference date for a test
8
+ * @returns
9
+ */
10
+ export declare function parseADatetime(content: string, langs: readonly Lang[], base?: Readonly<Date>): DateTime | null;
11
+ export declare function getCandidateDatetimeString(content: string, langs?: Lang[]): string | null;
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCandidateDatetimeString = exports.parseADatetime = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const chrono = tslib_1.__importStar(require("chrono-node"));
6
+ const defaultLangs = ['en', 'ja', 'fr', 'nl', 'ru', 'de', 'pt', 'zh'];
7
+ /**
8
+ * Datetime-ish text to a datetime data
9
+ *
10
+ * @param content
11
+ * @param langs
12
+ * @param base Reference date for a test
13
+ * @returns
14
+ */
15
+ function parseADatetime(content, langs, base) {
16
+ var _a;
17
+ const date = parseTryMultipleLangs(content, langs, base);
18
+ if (!date) {
19
+ return null;
20
+ }
21
+ const data = {};
22
+ if (date.isCertain('year')) {
23
+ data.year = date.get('year');
24
+ }
25
+ if (date.isCertain('month')) {
26
+ data.month = date.get('month');
27
+ }
28
+ if (date.isCertain('day')) {
29
+ data.day = date.get('day');
30
+ }
31
+ if (date.isCertain('hour')) {
32
+ data.hour = date.get('hour');
33
+ }
34
+ if (date.isCertain('hour')) {
35
+ data.minute = (_a = date.get('minute')) !== null && _a !== void 0 ? _a : 0;
36
+ }
37
+ if (date.isCertain('second')) {
38
+ data.second = date.get('second');
39
+ }
40
+ if (date.isCertain('millisecond')) {
41
+ data.ms = date.get('millisecond');
42
+ }
43
+ const datetime = {
44
+ datetime: data,
45
+ };
46
+ if (date.isCertain('timezoneOffset')) {
47
+ datetime.zone = date.get('timezoneOffset');
48
+ }
49
+ return datetime;
50
+ }
51
+ exports.parseADatetime = parseADatetime;
52
+ function getCandidateDatetimeString(content, langs = defaultLangs) {
53
+ const date = parseADatetime(content, langs);
54
+ if (!date) {
55
+ return null;
56
+ }
57
+ let datetimeStr = toDatetimeString(date.datetime);
58
+ if (!datetimeStr) {
59
+ return null;
60
+ }
61
+ if (date.zone != null) {
62
+ const plusMinus = date.zone < 0 ? '-' : '+';
63
+ const hour = Math.floor(Math.abs(date.zone) / 60);
64
+ const minute = Math.abs(date.zone) % 60;
65
+ datetimeStr += `${plusMinus}${f(hour, 2)}${f(minute, 2)}`;
66
+ }
67
+ return datetimeStr;
68
+ }
69
+ exports.getCandidateDatetimeString = getCandidateDatetimeString;
70
+ function toDatetimeString(date) {
71
+ if (only(date, ['year', 'month'])) {
72
+ return `${f(date.year, 4)}-${f(date.month, 2)}`;
73
+ }
74
+ if (only(date, ['year', 'month', 'day'])) {
75
+ return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}`;
76
+ }
77
+ if (only(date, ['month', 'day'])) {
78
+ return `${f(date.month, 2)}-${f(date.day, 2)}`;
79
+ }
80
+ if (only(date, ['hour', 'minute'])) {
81
+ return `${f(date.hour, 2)}:${f(date.minute, 2)}`;
82
+ }
83
+ if (only(date, ['hour', 'minute', 'second'])) {
84
+ return `${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}`;
85
+ }
86
+ if (only(date, ['hour', 'minute', 'second', 'ms'])) {
87
+ return `${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}.${date.ms}`;
88
+ }
89
+ if (only(date, ['year', 'month', 'day', 'hour', 'minute'])) {
90
+ return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}T${f(date.hour, 2)}:${f(date.minute, 2)}`;
91
+ }
92
+ if (only(date, ['year', 'month', 'day', 'hour', 'minute', 'second'])) {
93
+ return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}T${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}`;
94
+ }
95
+ if (only(date, ['year', 'month', 'day', 'hour', 'minute', 'second', 'ms'])) {
96
+ return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}T${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}.${date.ms}`;
97
+ }
98
+ return null;
99
+ }
100
+ function parseTryMultipleLangs(content, langs, base) {
101
+ for (const lang of langs) {
102
+ const results = chrono[lang].casual.parse(content, base);
103
+ // Is not multiple datetime contents
104
+ if (results.length < 1) {
105
+ continue;
106
+ }
107
+ const result = results[0];
108
+ if (!result) {
109
+ continue;
110
+ }
111
+ // Is not a range or period
112
+ if (result.end) {
113
+ continue;
114
+ }
115
+ return result.start;
116
+ }
117
+ return null;
118
+ }
119
+ function only(date, keys) {
120
+ const list = Object.keys(date);
121
+ for (const exists of list) {
122
+ if (!keys.includes(exists)) {
123
+ return false;
124
+ }
125
+ }
126
+ return true;
127
+ }
128
+ /**
129
+ * Formatter
130
+ *
131
+ * @param n
132
+ * @param pad zero padding
133
+ * @returns
134
+ */
135
+ function f(n, pad) {
136
+ return n.toString(10).padStart(pad, '0');
137
+ }
@@ -1,7 +1,7 @@
1
- declare type RequiredAttributes = string | (string | Attr)[];
2
- declare type Attr = {
3
- name: string;
4
- value: string | string[];
1
+ type RequiredAttributes = string | (string | Attr)[];
2
+ type Attr = {
3
+ name: string;
4
+ value?: string | string[];
5
5
  };
6
- declare const _default: import("@markuplint/ml-core").RuleSeed<RequiredAttributes, null>;
6
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<RequiredAttributes, undefined>>;
7
7
  export default _default;