@markuplint/rules 3.12.0 → 4.0.0-alpha.1

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 (142) hide show
  1. package/lib/attr-check.js +14 -19
  2. package/lib/attr-duplication/index.js +3 -6
  3. package/lib/attr-value-quotes/index.js +5 -9
  4. package/lib/case-sensitive-attr-name/index.js +9 -13
  5. package/lib/case-sensitive-tag-name/index.js +2 -4
  6. package/lib/character-reference/index.js +6 -8
  7. package/lib/class-naming/index.js +9 -11
  8. package/lib/create-message.js +9 -16
  9. package/lib/debug.js +2 -6
  10. package/lib/deprecated-attr/index.js +6 -9
  11. package/lib/deprecated-element/index.js +3 -5
  12. package/lib/disallowed-element/index.js +2 -4
  13. package/lib/doctype/index.js +2 -4
  14. package/lib/end-tag/index.js +5 -8
  15. package/lib/helpers.d.ts +1 -1
  16. package/lib/helpers.js +17 -28
  17. package/lib/id-duplication/index.js +2 -4
  18. package/lib/index.d.ts +15 -15
  19. package/lib/index.js +63 -66
  20. package/lib/ineffective-attr/index.js +5 -7
  21. package/lib/invalid-attr/index.js +30 -33
  22. package/lib/label-has-control/index.js +2 -4
  23. package/lib/landmark-roles/index.js +3 -6
  24. package/lib/no-boolean-attr-value/index.js +6 -9
  25. package/lib/no-default-value/index.js +9 -12
  26. package/lib/no-empty-palpable-content/index.js +5 -7
  27. package/lib/no-hard-code-id/index.js +2 -4
  28. package/lib/no-refer-to-non-existent-id/index.js +26 -30
  29. package/lib/no-use-event-handler-attr/index.js +4 -6
  30. package/lib/permitted-contents/choice.d.ts +1 -1
  31. package/lib/permitted-contents/choice.js +13 -18
  32. package/lib/permitted-contents/complex-branch.d.ts +1 -1
  33. package/lib/permitted-contents/complex-branch.js +10 -14
  34. package/lib/permitted-contents/content-model.d.ts +1 -1
  35. package/lib/permitted-contents/content-model.js +5 -9
  36. package/lib/permitted-contents/count-pattern.d.ts +1 -1
  37. package/lib/permitted-contents/count-pattern.js +19 -24
  38. package/lib/permitted-contents/debug.browser.js +9 -12
  39. package/lib/permitted-contents/debug.d.ts +8 -1
  40. package/lib/permitted-contents/debug.js +12 -13
  41. package/lib/permitted-contents/index.d.ts +1 -1
  42. package/lib/permitted-contents/index.js +10 -13
  43. package/lib/permitted-contents/matches-selector.d.ts +1 -1
  44. package/lib/permitted-contents/matches-selector.js +12 -17
  45. package/lib/permitted-contents/order.d.ts +1 -1
  46. package/lib/permitted-contents/order.js +17 -22
  47. package/lib/permitted-contents/recursive-branch.d.ts +2 -2
  48. package/lib/permitted-contents/recursive-branch.js +9 -13
  49. package/lib/permitted-contents/represent-transparent-nodes.d.ts +1 -1
  50. package/lib/permitted-contents/represent-transparent-nodes.js +15 -20
  51. package/lib/permitted-contents/start.d.ts +1 -1
  52. package/lib/permitted-contents/start.js +13 -21
  53. package/lib/permitted-contents/transparent.d.ts +1 -1
  54. package/lib/permitted-contents/transparent.js +4 -9
  55. package/lib/permitted-contents/types.js +1 -2
  56. package/lib/permitted-contents/utils.d.ts +1 -1
  57. package/lib/permitted-contents/utils.js +55 -74
  58. package/lib/placeholder-label-option/index.js +5 -9
  59. package/lib/require-accessible-name/index.js +10 -13
  60. package/lib/require-datetime/index.d.ts +1 -1
  61. package/lib/require-datetime/index.js +6 -8
  62. package/lib/require-datetime/types.js +1 -2
  63. package/lib/require-datetime/utils.d.ts +1 -1
  64. package/lib/require-datetime/utils.js +4 -11
  65. package/lib/required-attr/index.js +8 -11
  66. package/lib/required-element/index.js +3 -6
  67. package/lib/required-h1/index.js +3 -6
  68. package/lib/use-list/index.js +6 -10
  69. package/lib/wai-aria/checkings/abstract-role.d.ts +1 -1
  70. package/lib/wai-aria/checkings/abstract-role.js +5 -10
  71. package/lib/wai-aria/checkings/default-value.d.ts +1 -1
  72. package/lib/wai-aria/checkings/default-value.js +2 -6
  73. package/lib/wai-aria/checkings/deprecated-props.d.ts +1 -1
  74. package/lib/wai-aria/checkings/deprecated-props.js +3 -8
  75. package/lib/wai-aria/checkings/disallowed-prop.d.ts +1 -1
  76. package/lib/wai-aria/checkings/disallowed-prop.js +7 -12
  77. package/lib/wai-aria/checkings/implicit-props.d.ts +1 -1
  78. package/lib/wai-aria/checkings/implicit-props.js +6 -11
  79. package/lib/wai-aria/checkings/implicit-role.d.ts +1 -1
  80. package/lib/wai-aria/checkings/implicit-role.js +4 -9
  81. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +1 -1
  82. package/lib/wai-aria/checkings/interaction-in-hidden.js +4 -8
  83. package/lib/wai-aria/checkings/no-global-prop.d.ts +1 -1
  84. package/lib/wai-aria/checkings/no-global-prop.js +2 -7
  85. package/lib/wai-aria/checkings/non-existent-role.d.ts +1 -1
  86. package/lib/wai-aria/checkings/non-existent-role.js +4 -9
  87. package/lib/wai-aria/checkings/permitted-roles.d.ts +1 -1
  88. package/lib/wai-aria/checkings/permitted-roles.js +4 -9
  89. package/lib/wai-aria/checkings/presentational-children.d.ts +1 -1
  90. package/lib/wai-aria/checkings/presentational-children.js +4 -9
  91. package/lib/wai-aria/checkings/required-owned-elements.d.ts +1 -1
  92. package/lib/wai-aria/checkings/required-owned-elements.js +4 -8
  93. package/lib/wai-aria/checkings/required-prop.d.ts +1 -1
  94. package/lib/wai-aria/checkings/required-prop.js +2 -7
  95. package/lib/wai-aria/checkings/value.d.ts +1 -1
  96. package/lib/wai-aria/checkings/value.js +4 -10
  97. package/lib/wai-aria/index.d.ts +1 -1
  98. package/lib/wai-aria/index.js +38 -40
  99. package/lib/wai-aria/types.js +1 -2
  100. package/package.json +17 -12
  101. package/test/attr-check.spec.js +0 -77
  102. package/test/attr-duplication/index.spec.js +0 -159
  103. package/test/attr-value-quotes/index.spec.js +0 -133
  104. package/test/case-sensitive-attr-name/index.spec.js +0 -65
  105. package/test/case-sensitive-tag-name/index.spec.js +0 -80
  106. package/test/character-reference/index.spec.js +0 -72
  107. package/test/class-naming/index.spec.js +0 -470
  108. package/test/create-message.spec.js +0 -497
  109. package/test/deprecated-attr/index.spec.js +0 -48
  110. package/test/deprecated-element/index.spec.js +0 -35
  111. package/test/disallowed-element/index.spec.js +0 -90
  112. package/test/doctype/index.spec.js +0 -50
  113. package/test/end-tag/index.spec.js +0 -162
  114. package/test/id-duplication/index.spec.js +0 -47
  115. package/test/ineffective-attr/index.spec.js +0 -31
  116. package/test/invalid-attr/index.spec.js +0 -1641
  117. package/test/label-has-control/index.spec.js +0 -29
  118. package/test/landmark-roles/index.spec.js +0 -187
  119. package/test/no-boolean-attr-value/index.spec.js +0 -41
  120. package/test/no-default-value/index.spec.js +0 -74
  121. package/test/no-empty-palpable-content/index.spec.js +0 -115
  122. package/test/no-hard-code-id/index.spec.js +0 -100
  123. package/test/no-refer-to-non-existent-id/index.spec.js +0 -254
  124. package/test/no-use-event-handler-attr/index.spec.js +0 -57
  125. package/test/permitted-contents/choice.spec.js +0 -174
  126. package/test/permitted-contents/count-pattern.spec.js +0 -308
  127. package/test/permitted-contents/index.spec.js +0 -1395
  128. package/test/permitted-contents/matches-selector.spec.js +0 -59
  129. package/test/permitted-contents/order.spec.js +0 -351
  130. package/test/permitted-contents/recursive-branch.spec.js +0 -41
  131. package/test/permitted-contents/represent-transparent-nodes.spec.js +0 -24
  132. package/test/permitted-contents/start.spec.js +0 -67
  133. package/test/placeholder-label-option/index.spec.js +0 -113
  134. package/test/require-accessible-name/index.spec.js +0 -444
  135. package/test/require-datetime/index.spec.js +0 -54
  136. package/test/require-datetime/utils.spec.js +0 -52
  137. package/test/required-attr/index.spec.js +0 -414
  138. package/test/required-element/index.spec.js +0 -188
  139. package/test/required-h1/index.spec.js +0 -69
  140. package/test/use-list/index.spec.js +0 -109
  141. package/test/wai-aria/checkings/value.spec.js +0 -33
  142. package/test/wai-aria/index.spec.js +0 -1203
@@ -1,254 +0,0 @@
1
- const { mlRuleTest } = require('markuplint');
2
-
3
- const rule = require('../../lib/no-refer-to-non-existent-id').default;
4
-
5
- test('label[for]', async () => {
6
- const { violations } = await mlRuleTest(rule, '<label for="foo"></label>');
7
- expect(violations).toStrictEqual([
8
- {
9
- severity: 'error',
10
- line: 1,
11
- col: 13,
12
- raw: 'foo',
13
- message: 'Missing "foo" ID',
14
- },
15
- ]);
16
- });
17
-
18
- test('td[headers]', async () => {
19
- const { violations } = await mlRuleTest(
20
- rule,
21
- `<table>
22
- <tr>
23
- <th id="a"></th>
24
- <th id="b"></th>
25
- <td headers="a c"></td>
26
- </tr>
27
- </table>`,
28
- {
29
- parser: {
30
- '.*': '@markuplint/jsx-parser',
31
- },
32
- },
33
- );
34
- expect(violations).toStrictEqual([
35
- {
36
- severity: 'error',
37
- line: 5,
38
- col: 18,
39
- raw: 'a c',
40
- message: 'Missing "c" ID',
41
- },
42
- ]);
43
- });
44
-
45
- test('td[headers] (Dynamic)', async () => {
46
- const { violations } = await mlRuleTest(
47
- rule,
48
- `<table>
49
- <tr>
50
- <th id={a}></th>
51
- <th id={b}></th>
52
- <td headers="a c"></td>
53
- </tr>
54
- </table>`,
55
- {
56
- parser: {
57
- '.*': '@markuplint/jsx-parser',
58
- },
59
- },
60
- );
61
- expect(violations.length).toBe(0);
62
- });
63
-
64
- test('td[headers] (Dynamic)', async () => {
65
- const { violations } = await mlRuleTest(
66
- rule,
67
- // cspell: disable
68
- `<table>
69
- <tr>
70
- <th id="a"></th>
71
- <th id="b"></th>
72
- <td headers={aandb}></td>
73
- </tr>
74
- </table>`,
75
- // cspell: enable
76
- {
77
- parser: {
78
- '.*': '@markuplint/jsx-parser',
79
- },
80
- },
81
- );
82
- expect(violations.length).toBe(0);
83
- });
84
-
85
- test('aria-describedby', async () => {
86
- const { violations } = await mlRuleTest(rule, '<section aria-describedby="foo"></section>');
87
- expect(violations).toStrictEqual([
88
- {
89
- severity: 'error',
90
- line: 1,
91
- col: 28,
92
- raw: 'foo',
93
- message: 'Missing "foo" ID',
94
- },
95
- ]);
96
- });
97
-
98
- test('fragment', async () => {
99
- expect((await mlRuleTest(rule, '<a href="#foo"></a>')).violations).toStrictEqual([
100
- {
101
- severity: 'error',
102
- line: 1,
103
- col: 10,
104
- raw: '#foo',
105
- message: 'Missing "foo" ID',
106
- },
107
- ]);
108
-
109
- expect((await mlRuleTest(rule, '<a href="#"></a>')).violations).toStrictEqual([]);
110
-
111
- expect((await mlRuleTest(rule, '<a href="#top"></a>')).violations).toStrictEqual([]);
112
-
113
- expect((await mlRuleTest(rule, '<a href="#TOP"></a>')).violations).toStrictEqual([]);
114
-
115
- expect(
116
- (await mlRuleTest(rule, `<a href="#${encodeURI('あいうえお')}"></a><div id="あいうえお"></div>`)).violations,
117
- ).toStrictEqual([]);
118
-
119
- expect(
120
- (
121
- await mlRuleTest(rule, '<><a href="#foo" /><div id="foo" /></>', {
122
- parser: {
123
- '.*': '@markuplint/jsx-parser',
124
- },
125
- })
126
- ).violations,
127
- ).toStrictEqual([]);
128
-
129
- expect(
130
- (
131
- await mlRuleTest(rule, '<><a href="#foo" /><div id={foo} /></>', {
132
- parser: {
133
- '.*': '@markuplint/jsx-parser',
134
- },
135
- })
136
- ).violations,
137
- ).toStrictEqual([]);
138
-
139
- expect(
140
- (
141
- await mlRuleTest(rule, '<><a href="#foo" /><div name="foo" /></>', {
142
- parser: {
143
- '.*': '@markuplint/jsx-parser',
144
- },
145
- })
146
- ).violations,
147
- ).toStrictEqual([
148
- {
149
- severity: 'error',
150
- line: 1,
151
- col: 12,
152
- raw: '#foo',
153
- message: 'Missing "foo" ID',
154
- },
155
- ]);
156
-
157
- expect(
158
- (
159
- await mlRuleTest(rule, '<><a href="#foo" /><div name={foo} /></>', {
160
- parser: {
161
- '.*': '@markuplint/jsx-parser',
162
- },
163
- })
164
- ).violations,
165
- ).toStrictEqual([
166
- {
167
- severity: 'error',
168
- line: 1,
169
- col: 12,
170
- raw: '#foo',
171
- message: 'Missing "foo" ID',
172
- },
173
- ]);
174
-
175
- expect(
176
- (
177
- await mlRuleTest(rule, '<><a href="#foo" /><div name="foo" /></>', {
178
- parser: {
179
- '.*': '@markuplint/jsx-parser',
180
- },
181
- rule: {
182
- options: {
183
- fragmentRefersNameAttr: true,
184
- },
185
- },
186
- })
187
- ).violations,
188
- ).toStrictEqual([]);
189
-
190
- expect(
191
- (
192
- await mlRuleTest(rule, '<><a href="#foo" /><div name={foo} /></>', {
193
- parser: {
194
- '.*': '@markuplint/jsx-parser',
195
- },
196
- rule: {
197
- options: {
198
- fragmentRefersNameAttr: true,
199
- },
200
- },
201
- })
202
- ).violations,
203
- ).toStrictEqual([]);
204
- });
205
-
206
- describe('Issues', () => {
207
- test('#748', async () => {
208
- expect(
209
- (
210
- await mlRuleTest(
211
- rule,
212
- `
213
- <main>
214
- <?php foo() ?>
215
- <a href="#foo">link</a>
216
- <div id="foo"></div>
217
- </main>`,
218
- {
219
- parser: {
220
- '.*': '@markuplint/php-parser',
221
- },
222
- },
223
- )
224
- ).violations,
225
- ).toStrictEqual([]);
226
- });
227
-
228
- test('#776', async () => {
229
- expect(
230
- (
231
- await mlRuleTest(
232
- rule,
233
- /* cSpell:disable */
234
- `
235
- <a href="#apple%3Aorange">apple:orange</a>
236
- <p id="apple:orange">apple:orange</p>
237
-
238
- <a href="#apple%26orange">apple&amp;orange</a>
239
- <p id="apple&amp;orange">apple&amp;orange</p>
240
-
241
- <a href="#apple%26lemon">apple&amp;lemon</a>
242
- <p id="apple&lemon">apple&amp;lemon</p>
243
- `,
244
- /* cSpell:enable */
245
- {
246
- parser: {
247
- '.*': '@markuplint/php-parser',
248
- },
249
- },
250
- )
251
- ).violations,
252
- ).toStrictEqual([]);
253
- });
254
- });
@@ -1,57 +0,0 @@
1
- const { mlRuleTest } = require('markuplint');
2
-
3
- const rule = require('../../lib/no-use-event-handler-attr').default;
4
-
5
- it('disallows onclick', async () => {
6
- const { violations } = await mlRuleTest(rule, '<div onclick="e => e"></div>');
7
- expect(violations).toStrictEqual([
8
- {
9
- severity: 'warning',
10
- line: 1,
11
- col: 6,
12
- raw: 'onclick="e => e"',
13
- message: 'The "onclick" attribute is disallowed',
14
- },
15
- ]);
16
- });
17
-
18
- it('allows onclick because ignores it', async () => {
19
- const { violations } = await mlRuleTest(rule, '<div onclick="e => e"></div>', {
20
- rule: {
21
- options: {
22
- ignore: 'onclick',
23
- },
24
- },
25
- });
26
- expect(violations).toStrictEqual([]);
27
- });
28
-
29
- it('✔ onclick, ✘ onmouseleave', async () => {
30
- const { violations } = await mlRuleTest(rule, '<div onclick="e => e" onmouseleave="e => e"></div>', {
31
- rule: {
32
- options: {
33
- ignore: 'onclick',
34
- },
35
- },
36
- });
37
- expect(violations).toStrictEqual([
38
- {
39
- severity: 'warning',
40
- line: 1,
41
- col: 23,
42
- raw: 'onmouseleave="e => e"',
43
- message: 'The "onmouseleave" attribute is disallowed',
44
- },
45
- ]);
46
- });
47
-
48
- it('ignore by regex', async () => {
49
- const { violations } = await mlRuleTest(rule, '<div onclick="e => e"></div>', {
50
- rule: {
51
- options: {
52
- ignore: '/^onc/',
53
- },
54
- },
55
- });
56
- expect(violations).toStrictEqual([]);
57
- });
@@ -1,174 +0,0 @@
1
- const specs = require('@markuplint/html-spec');
2
- const { createTestElement } = require('@markuplint/ml-core');
3
-
4
- const { choice } = require('../../lib/permitted-contents/choice');
5
-
6
- function c(models, innerHtml) {
7
- const el = createTestElement(`<div>${innerHtml}</div>`);
8
- return choice(models, Array.from(el.childNodes), specs, { ignoreHasMutableChildren: true }, 0);
9
- }
10
-
11
- it('ordered requires', () => {
12
- const models = {
13
- choice: [
14
- //
15
- [{ require: 'a' }],
16
- [{ require: 'b' }],
17
- [{ require: 'c' }],
18
- ],
19
- };
20
-
21
- expect(c(models, '').type).toBe('MISSING_NODE_REQUIRED');
22
- expect(c(models, '<a></a>').type).toBe('MATCHED');
23
- expect(c(models, '<a></a><a></a>').type).toBe('UNEXPECTED_EXTRA_NODE');
24
- expect(c(models, '<b></b>').type).toBe('MATCHED');
25
- expect(c(models, '<b></b><c></c>').type).toBe('UNEXPECTED_EXTRA_NODE');
26
- expect(c(models, '<c></c>').type).toBe('MATCHED');
27
- expect(c(models, '<d></d>').type).toBe('MISSING_NODE_REQUIRED');
28
- });
29
-
30
- test('optional', () => {
31
- const models = {
32
- choice: [
33
- [
34
- {
35
- require: 'a',
36
- },
37
- ],
38
- [
39
- {
40
- require: 'b',
41
- },
42
- ],
43
- [
44
- {
45
- optional: 'c',
46
- },
47
- ],
48
- ],
49
- };
50
-
51
- expect(c(models, '').type).toBe('MATCHED_ZERO');
52
- expect(c(models, '<a></a>').type).toBe('MATCHED');
53
- expect(c(models, '<b></b>').type).toBe('MATCHED');
54
- expect(c(models, '<c></c>').type).toBe('MATCHED');
55
- expect(c(models, '<d></d>').type).toBe('UNEXPECTED_EXTRA_NODE');
56
- });
57
-
58
- test('interleave', () => {
59
- const models = {
60
- choice: [
61
- [
62
- {
63
- require: 'a',
64
- },
65
- {
66
- require: 'b',
67
- },
68
- ],
69
- [
70
- {
71
- require: 'b',
72
- },
73
- {
74
- require: 'a',
75
- },
76
- ],
77
- ],
78
- };
79
-
80
- expect(c(models, '<a></a>').type).toBe('MISSING_NODE_REQUIRED');
81
- expect(c(models, '<b></b>').type).toBe('MISSING_NODE_REQUIRED');
82
- expect(c(models, '<a></a><b></b>').type).toBe('MATCHED');
83
- expect(c(models, '<b></b><a></a>').type).toBe('MATCHED');
84
- expect(c(models, '<b></b><a></a><c></c>').type).toBe('UNEXPECTED_EXTRA_NODE');
85
- expect(c(models, '<b></b><a></a><a></a>').type).toBe('UNEXPECTED_EXTRA_NODE');
86
- });
87
-
88
- test('the dl element', () => {
89
- const models = {
90
- choice: [
91
- [
92
- {
93
- oneOrMore: [
94
- {
95
- zeroOrMore: ':model(script-supporting)',
96
- },
97
- {
98
- oneOrMore: 'dt',
99
- },
100
- {
101
- zeroOrMore: ':model(script-supporting)',
102
- },
103
- {
104
- oneOrMore: 'dd',
105
- },
106
- {
107
- zeroOrMore: ':model(script-supporting)',
108
- },
109
- ],
110
- },
111
- ],
112
- [
113
- {
114
- zeroOrMore: ':model(script-supporting)',
115
- },
116
- {
117
- oneOrMore: 'div',
118
- },
119
- {
120
- zeroOrMore: ':model(script-supporting)',
121
- },
122
- ],
123
- ],
124
- };
125
-
126
- expect(c(models, '<dt></dt><dd></dd>').type).toBe('MATCHED');
127
- expect(c(models, '').type).toBe('MISSING_NODE_ONE_OR_MORE');
128
- expect(c(models, '').query).toBe('dt');
129
- expect(c(models, '<dt></dt>').type).toBe('MISSING_NODE_ONE_OR_MORE');
130
- expect(c(models, '<div></div>').type).toBe('MATCHED');
131
- expect(c(models, '<div></div><div></div>').type).toBe('MATCHED');
132
- expect(c(models, '<dt></dt><dd></dd><dt></dt>').type).toBe('MISSING_NODE_ONE_OR_MORE');
133
- });
134
-
135
- it('part of the ruby element', () => {
136
- const models = {
137
- // 2. One or the other of the following:
138
- choice: [
139
- [
140
- {
141
- // - One or more rt elements
142
- oneOrMore: 'rt',
143
- },
144
- ],
145
- [
146
- {
147
- // - An rp element
148
- require: 'rp',
149
- },
150
- {
151
- // followed by one or more rt elements, each of which is itself followed by an rp element
152
- oneOrMore: [
153
- {
154
- require: 'rt',
155
- },
156
- {
157
- require: 'rp',
158
- },
159
- ],
160
- },
161
- ],
162
- ],
163
- };
164
-
165
- expect(c(models, '<rt></rt>').type).toBe('MATCHED');
166
- expect(c(models, '<rp></rp>').type).toBe('MISSING_NODE_REQUIRED');
167
- expect(c(models, '<rp></rp>').query).toBe('rt');
168
- expect(c(models, '<rt></rt><rt></rt>').type).toBe('MATCHED');
169
- expect(c(models, '<rp></rp><rt></rt><rp></rp>').type).toBe('MATCHED');
170
- expect(c(models, '<rp></rp><rt></rt>').type).toBe('MISSING_NODE_REQUIRED');
171
- expect(c(models, '<rp></rp><rt></rt>').query).toBe('rp');
172
- expect(c(models, '<rt></rt><rp></rp>').type).toBe('UNEXPECTED_EXTRA_NODE');
173
- expect(c(models, '<rt></rt><rp></rp>').query).toBe('rt');
174
- });