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

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 (129) hide show
  1. package/README.md +10 -44
  2. package/lib/attr-check.d.ts +2 -2
  3. package/lib/attr-check.js +1 -1
  4. package/lib/attr-duplication/index.js +1 -1
  5. package/lib/attr-value-quotes/index.d.ts +3 -3
  6. package/lib/attr-value-quotes/index.js +1 -1
  7. package/lib/case-sensitive-attr-name/index.d.ts +1 -1
  8. package/lib/case-sensitive-attr-name/index.js +3 -3
  9. package/lib/case-sensitive-tag-name/index.d.ts +1 -1
  10. package/lib/case-sensitive-tag-name/index.js +3 -3
  11. package/lib/character-reference/index.js +1 -1
  12. package/lib/class-naming/index.d.ts +1 -1
  13. package/lib/class-naming/index.js +2 -2
  14. package/lib/create-message.d.ts +1 -1
  15. package/lib/create-message.js +5 -5
  16. package/lib/debug.d.ts +1 -1
  17. package/lib/deprecated-element/index.js +2 -2
  18. package/lib/doctype/index.d.ts +2 -2
  19. package/lib/doctype/index.js +2 -2
  20. package/lib/end-tag/index.js +3 -18
  21. package/lib/helpers.d.ts +8 -32
  22. package/lib/helpers.js +17 -81
  23. package/lib/index.d.ts +2 -62
  24. package/lib/index.js +4 -0
  25. package/lib/ineffective-attr/index.js +1 -1
  26. package/lib/invalid-attr/index.d.ts +3 -2
  27. package/lib/invalid-attr/index.js +19 -14
  28. package/lib/label-has-control/index.d.ts +2 -0
  29. package/lib/label-has-control/index.js +28 -0
  30. package/lib/landmark-roles/index.d.ts +3 -3
  31. package/lib/landmark-roles/index.js +3 -3
  32. package/lib/no-boolean-attr-value/index.js +1 -1
  33. package/lib/no-default-value/index.js +1 -1
  34. package/lib/no-empty-palpable-content/index.d.ts +6 -0
  35. package/lib/no-empty-palpable-content/index.js +34 -0
  36. package/lib/no-hard-code-id/index.js +1 -1
  37. package/lib/no-refer-to-non-existent-id/index.js +1 -1
  38. package/lib/no-use-event-handler-attr/index.d.ts +1 -1
  39. package/lib/no-use-event-handler-attr/index.js +6 -6
  40. package/lib/permitted-contents/choice.d.ts +3 -0
  41. package/lib/permitted-contents/choice.js +37 -0
  42. package/lib/permitted-contents/complex-branch.d.ts +13 -0
  43. package/lib/permitted-contents/complex-branch.js +27 -0
  44. package/lib/permitted-contents/content-model.d.ts +2 -0
  45. package/lib/permitted-contents/content-model.js +49 -0
  46. package/lib/permitted-contents/count-pattern.d.ts +13 -0
  47. package/lib/permitted-contents/count-pattern.js +155 -0
  48. package/lib/permitted-contents/debug.browser.d.ts +30 -0
  49. package/lib/permitted-contents/debug.browser.js +14 -0
  50. package/lib/permitted-contents/debug.d.ts +3 -0
  51. package/lib/permitted-contents/debug.js +13 -0
  52. package/lib/permitted-contents/index.d.ts +1 -7
  53. package/lib/permitted-contents/index.js +76 -246
  54. package/lib/permitted-contents/matches-selector.d.ts +3 -0
  55. package/lib/permitted-contents/matches-selector.js +185 -0
  56. package/lib/permitted-contents/order.d.ts +13 -0
  57. package/lib/permitted-contents/order.js +89 -0
  58. package/lib/permitted-contents/recursive-branch.d.ts +4 -0
  59. package/lib/permitted-contents/recursive-branch.js +43 -0
  60. package/lib/permitted-contents/represent-transparent-nodes.d.ts +6 -0
  61. package/lib/permitted-contents/represent-transparent-nodes.js +76 -0
  62. package/lib/permitted-contents/start.d.ts +12 -0
  63. package/lib/permitted-contents/start.js +71 -0
  64. package/lib/permitted-contents/transparent.d.ts +2 -0
  65. package/lib/permitted-contents/transparent.js +29 -0
  66. package/lib/permitted-contents/types.d.ts +45 -0
  67. package/lib/permitted-contents/types.js +2 -0
  68. package/lib/permitted-contents/utils.d.ts +32 -0
  69. package/lib/permitted-contents/utils.js +184 -0
  70. package/lib/require-accessible-name/index.d.ts +1 -1
  71. package/lib/require-accessible-name/index.js +11 -3
  72. package/lib/required-attr/index.d.ts +2 -2
  73. package/lib/required-attr/index.js +1 -1
  74. package/lib/required-element/index.d.ts +1 -1
  75. package/lib/required-element/index.js +1 -1
  76. package/lib/required-h1/index.js +2 -2
  77. package/lib/use-list/index.d.ts +2 -2
  78. package/lib/use-list/index.js +3 -3
  79. package/lib/wai-aria/checkings/abstract-role.js +1 -1
  80. package/lib/wai-aria/checkings/implicit-role.js +2 -2
  81. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +11 -0
  82. package/lib/wai-aria/checkings/interaction-in-hidden.js +47 -0
  83. package/lib/wai-aria/checkings/{non-existant-role.d.ts → non-existent-role.d.ts} +1 -1
  84. package/lib/wai-aria/checkings/{non-existant-role.js → non-existent-role.js} +4 -4
  85. package/lib/wai-aria/checkings/permitted-roles.js +1 -1
  86. package/lib/wai-aria/checkings/presentational-children.d.ts +29 -0
  87. package/lib/wai-aria/checkings/presentational-children.js +60 -0
  88. package/lib/wai-aria/checkings/{checking-required-owned-elements.d.ts → required-owned-elements.d.ts} +0 -0
  89. package/lib/wai-aria/checkings/required-owned-elements.js +101 -0
  90. package/lib/wai-aria/checkings/value.d.ts +6 -0
  91. package/lib/wai-aria/checkings/value.js +74 -4
  92. package/lib/wai-aria/index.js +25 -15
  93. package/lib/wai-aria/types.d.ts +3 -1
  94. package/package.json +12 -8
  95. package/schema.json +6 -0
  96. package/tsconfig.tsbuildinfo +1 -1
  97. package/lib/__foo/index.d.ts +0 -2
  98. package/lib/__foo/index.js +0 -46
  99. package/lib/attr-equal-space-after/index.d.ts +0 -3
  100. package/lib/attr-equal-space-after/index.js +0 -90
  101. package/lib/attr-equal-space-before/index.d.ts +0 -3
  102. package/lib/attr-equal-space-before/index.js +0 -90
  103. package/lib/attr-spacing/index.d.ts +0 -6
  104. package/lib/attr-spacing/index.js +0 -100
  105. package/lib/helper/aria/get-aria.d.ts +0 -7
  106. package/lib/helper/aria/get-aria.js +0 -53
  107. package/lib/helper/aria/get-computed-role.d.ts +0 -10
  108. package/lib/helper/aria/get-computed-role.js +0 -24
  109. package/lib/helper/aria/get-implicit-role.d.ts +0 -7
  110. package/lib/helper/aria/get-implicit-role.js +0 -12
  111. package/lib/helper/aria/get-permitted-roles.d.ts +0 -14
  112. package/lib/helper/aria/get-permitted-roles.js +0 -26
  113. package/lib/helper/aria/resolve-version.d.ts +0 -2
  114. package/lib/helper/aria/resolve-version.js +0 -21
  115. package/lib/helper/spec/aria-spec.d.ts +0 -5
  116. package/lib/helper/spec/aria-spec.js +0 -12
  117. package/lib/helper/spec/get-role-spec.d.ts +0 -11
  118. package/lib/helper/spec/get-role-spec.js +0 -39
  119. package/lib/helper/spec/html-spec.d.ts +0 -2
  120. package/lib/helper/spec/html-spec.js +0 -14
  121. package/lib/indentation/index.d.ts +0 -7
  122. package/lib/indentation/index.js +0 -208
  123. package/lib/permitted-contents/array.combination.d.ts +0 -1
  124. package/lib/permitted-contents/array.combination.js +0 -33
  125. package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +0 -11
  126. package/lib/permitted-contents/permitted-content.spec-to-regexp.js +0 -230
  127. package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +0 -2
  128. package/lib/permitted-contents/unfold-content-models-to-tags.js +0 -8
  129. package/lib/wai-aria/checkings/checking-required-owned-elements.js +0 -63
package/README.md CHANGED
@@ -1,58 +1,24 @@
1
1
  # @markuplint/rules
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/%40markuplint%2Frules.svg)](https://www.npmjs.com/package/@markuplint/rules)
4
- [![Build Status](https://travis-ci.org/markuplint/markuplint.svg?branch=main)](https://travis-ci.org/markuplint/markuplint)
5
- [![Coverage Status](https://coveralls.io/repos/github/markuplint/markuplint/badge.svg?branch=main)](https://coveralls.io/github/markuplint/markuplint?branch=main)
6
4
 
7
- ## Rules
5
+ **Built-in rules**
8
6
 
9
- ### Conformance checking
7
+ ## Documentation
10
8
 
11
- - [`attr-duplication`](./src/attr-duplication)
12
- - [`character-reference`](./src/character-reference)
13
- - [`deprecated-attr`](./src/deprecated-attr)
14
- - [`deprecated-element`](./src/deprecated-element)
15
- - [`disallowed-element`](./src/disallowed-element)
16
- - [`doctype`](./src/doctype)
17
- - [`id-duplication`](./src/id-duplication)
18
- - [`ineffective-attr`](./src/ineffective-attr)
19
- - [`invalid-attr`](./src/invalid-attr)
20
- - [`permitted-contents`](./src/permitted-contents)
21
- - [`required-attr`](./src/required-attr)
22
- - [`required-element`](./src/required-element)
23
-
24
- ### Accessibility
25
-
26
- - [`landmark-roles`](./src/landmark-roles)
27
- - [`no-refer-to-non-existent-id`](./src/no-refer-to-non-existent-id)
28
- - [`required-h1`](./src/required-h1)
29
- - [`use-list`](./src/use-list)
30
- - [`wai-aria`](./src/wai-aria)
31
-
32
- ### Naming Convention
33
-
34
- - [`class-naming`](./src/class-naming)
35
-
36
- ### Maintainability
37
-
38
- - [`no-hard-code-id`](./src/no-hard-code-id)
39
- - [`no-use-event-handler-attr`](./src/no-use-event-handler-attr)
40
-
41
- ### Style
42
-
43
- - [`attr-value-quotes`](./src/attr-value-quotes)
44
- - [`case-sensitive-attr-name`](./src/case-sensitive-attr-name)
45
- - [`case-sensitive-tag-name`](./src/case-sensitive-tag-name)
46
- - [`end-tag`](./src/end-tag)
47
- - [`no-boolean-attr-value`](./src/no-boolean-attr-value)
48
- - [`no-default-value`](./src/no-default-value)
9
+ - [Rules](https://markuplint.dev/rules/)
49
10
 
50
11
  ## Install
51
12
 
52
- Generally, you **don't have to install** this package because markuplint dependents it defaultly.
13
+ [`markuplint`](https://www.npmjs.com/package/markuplint) package includes this package.
53
14
 
54
- ```sh
15
+ <details>
16
+ <summary>If you are installing purposely, how below:</summary>
17
+
18
+ ```shell
55
19
  $ npm install -D @markuplint/rules
56
20
 
57
21
  $ yarn add -D @markuplint/rules
58
22
  ```
23
+
24
+ </details>
@@ -1,11 +1,11 @@
1
1
  import type { Translator } from '@markuplint/i18n';
2
2
  import type { Attribute as AttrSpec, AttributeType } from '@markuplint/ml-spec';
3
- declare type Invalid = {
3
+ type Invalid = {
4
4
  invalidType: 'non-existent' | 'invalid-value';
5
5
  message: string;
6
6
  loc?: Loc;
7
7
  };
8
- declare type Loc = {
8
+ type Loc = {
9
9
  raw: string;
10
10
  line: number;
11
11
  col: number;
package/lib/attr-check.js CHANGED
@@ -23,7 +23,7 @@ function attrCheck(t, name, value, isCustomRule, spec) {
23
23
  return false;
24
24
  }
25
25
  }
26
- // Existance
26
+ // Existence
27
27
  if (!spec) {
28
28
  (0, debug_1.log)('The "%s" attribute DOES\'NT EXIST in the spec', name);
29
29
  return {
@@ -11,7 +11,7 @@ exports.default = (0, ml_core_1.createRule)({
11
11
  continue;
12
12
  }
13
13
  const attrName = attr.name;
14
- const name = node.isCustomElement ? attrName : attrName.toLowerCase();
14
+ const name = node.elementType === 'html' ? attrName.toLowerCase() : attrName;
15
15
  if (attrNameStack.includes(name)) {
16
16
  const scope = attr.nameNode || attr;
17
17
  report({
@@ -1,6 +1,6 @@
1
- export declare type Type = 'double' | 'single';
2
- export declare type Quote = '"' | "'";
3
- export declare type QuoteMap = {
1
+ export type Type = 'double' | 'single';
2
+ export type Quote = '"' | "'";
3
+ export type QuoteMap = {
4
4
  [P in Type]: Quote;
5
5
  };
6
6
  declare const _default: import("@markuplint/ml-core").RuleSeed<Type, null>;
@@ -6,7 +6,7 @@ const quoteList = {
6
6
  single: "'",
7
7
  };
8
8
  exports.default = (0, ml_core_1.createRule)({
9
- defaultServerity: 'warning',
9
+ defaultSeverity: 'warning',
10
10
  defaultValue: 'double',
11
11
  async verify({ document, report, t }) {
12
12
  await document.walkOn('Attr', attr => {
@@ -1,3 +1,3 @@
1
- export declare type Value = 'lower' | 'upper';
1
+ export type Value = 'lower' | 'upper';
2
2
  declare const _default: import("@markuplint/ml-core").RuleSeed<Value, null>;
3
3
  export default _default;
@@ -2,13 +2,13 @@
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
  defaultValue: 'lower',
7
7
  async verify({ document, report, t }) {
8
8
  await document.walkOn('Attr', attr => {
9
9
  var _a, _b, _c, _d;
10
10
  const el = attr.ownerElement;
11
- if (el.isForeignElement || el.isCustomElement) {
11
+ if (el.isForeignElement || el.elementType !== 'html') {
12
12
  return;
13
13
  }
14
14
  const value = attr.rule.value;
@@ -46,7 +46,7 @@ exports.default = (0, ml_core_1.createRule)({
46
46
  await document.walkOn('Attr', attr => {
47
47
  var _a;
48
48
  const el = attr.ownerElement;
49
- if (el.isForeignElement || el.isCustomElement) {
49
+ if (el.isForeignElement || el.elementType !== 'html') {
50
50
  return;
51
51
  }
52
52
  const attrSpecs = (0, ml_core_1.getAttrSpecs)(el, document.specs);
@@ -1,3 +1,3 @@
1
- export declare type Value = 'lower' | 'upper';
1
+ export type Value = 'lower' | 'upper';
2
2
  declare const _default: import("@markuplint/ml-core").RuleSeed<Value, null>;
3
3
  export default _default;
@@ -2,11 +2,11 @@
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
  defaultValue: 'lower',
7
7
  async verify({ document, report, t }) {
8
8
  await document.walkOn('Element', el => {
9
- if (el.isForeignElement || el.isCustomElement) {
9
+ if (el.isForeignElement || el.elementType !== 'html') {
10
10
  return;
11
11
  }
12
12
  const ms = el.rule.severity === 'error' ? 'must' : 'should';
@@ -38,7 +38,7 @@ exports.default = (0, ml_core_1.createRule)({
38
38
  },
39
39
  async fix({ document }) {
40
40
  await document.walkOn('Element', el => {
41
- if (el.isForeignElement || el.isCustomElement) {
41
+ if (el.isForeignElement || el.elementType !== 'html') {
42
42
  return;
43
43
  }
44
44
  const deny = el.rule.value === 'lower' ? /[A-Z]/ : /[a-z]/;
@@ -40,7 +40,7 @@ exports.default = (0, ml_core_1.createRule)({
40
40
  }
41
41
  });
42
42
  for (const targetNode of targetNodes) {
43
- if (!('scope' in targetNode && 'line' in targetNode)) {
43
+ if (!('scope' in targetNode && 'line' in targetNode && targetNode.line != null)) {
44
44
  continue;
45
45
  }
46
46
  const escapedText = targetNode.raw.replace(/&(?:[a-z]+|#[0-9]+|x[0-9]);/gi, $0 => '*'.repeat($0.length));
@@ -1,3 +1,3 @@
1
- export declare type Value = string | string[] | null;
1
+ export type Value = string | string[] | null;
2
2
  declare const _default: import("@markuplint/ml-core").RuleSeed<Value, null>;
3
3
  export default _default;
@@ -3,14 +3,14 @@ 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
  defaultValue: null,
8
8
  async verify({ document, report, t }) {
9
9
  await document.walkOn('Element', el => {
10
10
  if (!el.rule.value) {
11
11
  return;
12
12
  }
13
- const classPatterns = Array.isArray(el.rule.value) ? el.rule.value : [el.rule.value];
13
+ const classPatterns = (Array.isArray(el.rule.value) ? el.rule.value : [el.rule.value]).filter(className => className && typeof className === 'string');
14
14
  const attrs = el.getAttributeToken('class');
15
15
  for (const attr of attrs) {
16
16
  if (attr.isDynamicValue) {
@@ -2,4 +2,4 @@ import type { Translator } from '@markuplint/i18n';
2
2
  import type { AttributeType } from '@markuplint/ml-spec';
3
3
  import type { UnmatchedResult } from '@markuplint/types';
4
4
  export declare function createMessageValueExpected(t: Translator, baseTarget: string, type: AttributeType, matches: UnmatchedResult): string;
5
- export declare function __createMessageValueExpected(t: Translator, baseTarget: string, expected: string | null, matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | 'candicate' | 'ref' | 'extra'>): string;
5
+ export declare function __createMessageValueExpected(t: Translator, baseTarget: string, expected: string | null, matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | 'candidate' | 'ref' | 'extra'>): string;
@@ -26,7 +26,7 @@ function __createMessageValueExpected(t, baseTarget, expected, matches) {
26
26
  let reasonPart;
27
27
  let expectPart;
28
28
  let unnecessaryPart;
29
- let candicatePart;
29
+ let candidatePart;
30
30
  let expectOrNeed = 'expects';
31
31
  if (matches.partName) {
32
32
  if (matches.partName === 'the content of the list') {
@@ -188,10 +188,10 @@ function __createMessageValueExpected(t, baseTarget, expected, matches) {
188
188
  }
189
189
  }
190
190
  }
191
- if (matches.candicate) {
192
- candicatePart = t('Did you mean "{0*}"?', matches.candicate);
191
+ if (matches.candidate) {
192
+ candidatePart = t('Did you mean "{0*}"?', matches.candidate);
193
193
  }
194
- let message = [reasonPart, unnecessaryPart, expectPart, candicatePart].filter(s => s).join(t('. '));
194
+ let message = [reasonPart, unnecessaryPart, expectPart, candidatePart].filter(s => s).join(t('. '));
195
195
  if (matches.ref) {
196
196
  message += ` (${matches.ref})`;
197
197
  }
@@ -232,7 +232,7 @@ function expectValueToWord(t, expect, type) {
232
232
  return expect.value ? `%${expect.value}%` : '';
233
233
  case 'format':
234
234
  return t('the {0} format', expect.value);
235
- case 'regxp':
235
+ case 'regexp':
236
236
  return t('{0} ({1})', 'regular expression', expect.value);
237
237
  case 'syntax':
238
238
  if ((0, types_1.isKeyword)(type) && type[0] === '<') {
package/lib/debug.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import debug from 'debug';
2
- export declare type Log = debug.Debugger;
2
+ export type Log = debug.Debugger;
3
3
  export declare const log: debug.Debugger;
@@ -6,10 +6,10 @@ exports.default = (0, ml_core_1.createRule)({
6
6
  await document.walkOn('Element', el => {
7
7
  if (!(el.namespaceURI === 'http://www.w3.org/1999/xhtml' ||
8
8
  el.namespaceURI === 'http://www.w3.org/2000/svg') ||
9
- el.isCustomElement) {
9
+ el.elementType !== 'html') {
10
10
  return;
11
11
  }
12
- const spec = (0, ml_core_1.getSpec)(el, document.specs);
12
+ const spec = (0, ml_core_1.getSpec)(el, document.specs.specs);
13
13
  if (spec && (spec.obsolete || spec.deprecated || spec.nonStandard)) {
14
14
  const message = t('{0} is {1:c}', t('the "{0*}" {1}', el.localName, 'element'), spec.deprecated ? 'deprecated' : spec.obsolete ? 'obsolete' : 'non-standard');
15
15
  report({
@@ -1,5 +1,5 @@
1
- declare type Option = {
2
- denyObsolateType: boolean;
1
+ type Option = {
2
+ denyObsoleteType: boolean;
3
3
  };
4
4
  declare const _default: import("@markuplint/ml-core").RuleSeed<"always", Option>;
5
5
  export default _default;
@@ -4,7 +4,7 @@ const ml_core_1 = require("@markuplint/ml-core");
4
4
  exports.default = (0, ml_core_1.createRule)({
5
5
  defaultValue: 'always',
6
6
  defaultOptions: {
7
- denyObsolateType: true,
7
+ denyObsoleteType: true,
8
8
  },
9
9
  verify({ document, report, t }) {
10
10
  if (document.isFragment) {
@@ -23,7 +23,7 @@ exports.default = (0, ml_core_1.createRule)({
23
23
  if ((doctype.name.toLowerCase() === 'html' && doctype.publicId) || doctype.systemId) {
24
24
  report({
25
25
  scope: doctype,
26
- message: t('Never {0} {1}', 'declarate', 'obsolete doctype'),
26
+ message: t('Never {0} {1}', 'declare', 'obsolete doctype'),
27
27
  });
28
28
  }
29
29
  },
@@ -1,24 +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 voidElements = [
5
- 'area',
6
- 'base',
7
- 'br',
8
- 'col',
9
- 'embed',
10
- 'hr',
11
- 'img',
12
- 'input',
13
- 'link',
14
- 'meta',
15
- 'param',
16
- 'source',
17
- 'track',
18
- 'wbr',
19
- ];
4
+ const ml_spec_1 = require("@markuplint/ml-spec");
20
5
  exports.default = (0, ml_core_1.createRule)({
21
- defaultServerity: 'warning',
6
+ defaultSeverity: 'warning',
22
7
  async verify({ document, report, t }) {
23
8
  if (document.endTag === 'never') {
24
9
  return;
@@ -28,7 +13,7 @@ exports.default = (0, ml_core_1.createRule)({
28
13
  if (el.isOmitted) {
29
14
  return;
30
15
  }
31
- if (voidElements.some(vE => vE === el.localName)) {
16
+ if ((0, ml_spec_1.isVoidElement)(el)) {
32
17
  return;
33
18
  }
34
19
  if (el.closeTag != null) {
package/lib/helpers.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Log } from './debug';
2
2
  import type { Translator } from '@markuplint/i18n';
3
3
  import type { Element, RuleConfigValue, Document } from '@markuplint/ml-core';
4
- import type { ARIAVersion, Attribute, MLMLSpec } from '@markuplint/ml-spec';
4
+ import type { Attribute } from '@markuplint/ml-spec';
5
5
  export declare function attrMatches<T extends RuleConfigValue, R>(node: Element<T, R>, condition: Attribute['condition']): boolean;
6
6
  export declare function match(needle: string, pattern: string): boolean;
7
7
  /**
@@ -30,42 +30,18 @@ export declare function isValidAttr(t: Translator, name: string, value: string,
30
30
  } | undefined;
31
31
  };
32
32
  export declare function toNormalizedValue(value: string, spec: Attribute): string;
33
- /**
34
- *
35
- * @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
36
- *
37
- * @param type
38
- * @param value
39
- * @param tokenEnum
40
- */
41
- export declare function checkAriaValue(type: string, value: string, tokenEnum: string[]): boolean;
42
- export declare function checkAria(specs: Readonly<MLMLSpec>, attrName: string, currentValue: string, version: ARIAVersion, role?: string): {
43
- currentValue: string;
44
- isValid: boolean;
45
- } | {
46
- currentValue: string;
47
- isValid: boolean;
48
- name: string;
49
- type: "property" | "state";
50
- deprecated?: true | undefined;
51
- isGlobal?: true | undefined;
52
- value: import("@markuplint/ml-spec").ARIAAttributeValue;
53
- conditionalValue?: {
54
- role: string[];
55
- value: import("@markuplint/ml-spec").ARIAAttributeValue;
56
- }[] | undefined;
57
- enum: string[];
58
- defaultValue?: string | undefined;
59
- equivalentHtmlAttrs?: import("@markuplint/ml-spec").EquivalentHtmlAttr[] | undefined;
60
- valueDescriptions?: Record<string, string> | undefined;
61
- };
62
33
  export declare function accnameMayBeMutable(el: Element<any, any>, document: Document<any, any>): boolean;
63
- export declare function getOwnedLabel<V extends RuleConfigValue, O>(el: Element<V, O>, docuemnt: Document<V, O>): Element<V, O> | null;
34
+ export declare function getOwnedLabel<V extends RuleConfigValue, O>(el: Element<V, O>, document: Document<V, O>): Element<V, O> | null;
64
35
  export declare function decodeCharRef(characterReference: string): string;
65
36
  export declare class Collection<T> {
66
37
  #private;
67
38
  constructor(...items: (T | null | undefined)[]);
39
+ [Symbol.iterator](): Iterator<T>;
68
40
  add(...items: (T | null | undefined)[]): void;
69
41
  toArray(): readonly T[];
70
- [Symbol.iterator](): Iterator<T>;
71
42
  }
43
+ type Writeable<T> = {
44
+ -readonly [P in keyof T]: T[P];
45
+ };
46
+ export declare function deepCopy<T>(value: T): Writeable<T>;
47
+ export {};
package/lib/helpers.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  var _Collection_items;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.Collection = exports.decodeCharRef = exports.getOwnedLabel = exports.accnameMayBeMutable = exports.checkAria = exports.checkAriaValue = exports.toNormalizedValue = exports.isValidAttr = exports.rePCENChar = exports.match = exports.attrMatches = void 0;
4
+ exports.deepCopy = exports.Collection = exports.decodeCharRef = exports.getOwnedLabel = exports.accnameMayBeMutable = exports.toNormalizedValue = exports.isValidAttr = exports.rePCENChar = exports.match = exports.attrMatches = void 0;
5
5
  const tslib_1 = require("tslib");
6
- const ml_core_1 = require("@markuplint/ml-core");
6
+ // @ts-ignore
7
+ const structured_clone_1 = tslib_1.__importDefault(require("@ungap/structured-clone"));
7
8
  const html_entities_1 = require("html-entities");
8
9
  const attr_check_1 = require("./attr-check");
9
10
  function attrMatches(node, condition) {
@@ -105,99 +106,30 @@ function toNormalizedValue(value, spec) {
105
106
  return normalized;
106
107
  }
107
108
  exports.toNormalizedValue = toNormalizedValue;
108
- /**
109
- *
110
- * @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
111
- *
112
- * @param type
113
- * @param value
114
- * @param tokenEnum
115
- */
116
- function checkAriaValue(type, value, tokenEnum) {
117
- switch (type) {
118
- case 'token': {
119
- return tokenEnum.includes(value);
120
- }
121
- case 'token list': {
122
- const list = value.split(/\s+/g).map(s => s.trim());
123
- return list.every(token => tokenEnum.includes(token));
124
- }
125
- case 'string':
126
- case 'ID reference':
127
- case 'ID reference list': {
128
- return true;
129
- }
130
- case 'true/false': {
131
- return ['true', 'false'].includes(value);
132
- }
133
- case 'tristate': {
134
- return ['mixed', 'true', 'false', 'undefined'].includes(value);
135
- }
136
- case 'true/false/undefined': {
137
- return ['true', 'false', 'undefined'].includes(value);
138
- }
139
- case 'integer': {
140
- return parseInt(value).toString() === value;
141
- }
142
- case 'number': {
143
- return parseFloat(value).toString() === value;
144
- }
145
- }
146
- // For skipping checking
147
- return true;
148
- }
149
- exports.checkAriaValue = checkAriaValue;
150
- function checkAria(specs, attrName, currentValue, version, role) {
151
- const ariaAttrs = (0, ml_core_1.ariaSpecs)(specs, version).props;
152
- const aria = ariaAttrs.find(a => a.name === attrName);
153
- if (!aria) {
154
- return {
155
- currentValue,
156
- // For skipping checking
157
- isValid: true,
158
- };
159
- }
160
- let valueType = aria.value;
161
- if (role && aria.conditionalValue) {
162
- for (const cond of aria.conditionalValue) {
163
- if (cond.role.includes(role)) {
164
- valueType = cond.value;
165
- break;
166
- }
167
- }
168
- }
169
- const isValid = checkAriaValue(valueType, currentValue, aria.enum);
170
- return {
171
- ...aria,
172
- currentValue,
173
- isValid,
174
- };
175
- }
176
- exports.checkAria = checkAria;
177
109
  function accnameMayBeMutable(el, document) {
178
110
  if (el.hasMutableAttributes() || el.hasMutableChildren(true)) {
179
111
  return true;
180
112
  }
181
- const ownedLable = getOwnedLabel(el, document);
182
- if (ownedLable && (ownedLable.hasMutableAttributes() || ownedLable.hasMutableChildren(true))) {
113
+ const ownedLabel = getOwnedLabel(el, document);
114
+ if (ownedLabel && (ownedLabel.hasMutableAttributes() || ownedLabel.hasMutableChildren(true))) {
183
115
  return true;
184
116
  }
185
117
  return false;
186
118
  }
187
119
  exports.accnameMayBeMutable = accnameMayBeMutable;
188
120
  const labelable = ['button', 'input:not([type=hidden])', 'meter', 'output', 'progress', 'select', 'textarea'];
189
- function getOwnedLabel(el, docuemnt) {
121
+ function getOwnedLabel(el, document) {
190
122
  if (!labelable.some(cond => el.matches(cond))) {
191
123
  return null;
192
124
  }
193
- let ownedLable = el.closest('label');
194
- if (!ownedLable) {
125
+ let ownedLabel = el.closest('label');
126
+ if (!ownedLabel) {
195
127
  const id = el.getAttribute('id');
196
128
  if (id) {
197
- ownedLable = docuemnt.querySelector(`label[for="${id}"]`);
129
+ ownedLabel = document.querySelector(`label[for="${id}"]`);
198
130
  }
199
131
  }
200
- return ownedLable;
132
+ return ownedLabel;
201
133
  }
202
134
  exports.getOwnedLabel = getOwnedLabel;
203
135
  function decodeCharRef(characterReference) {
@@ -209,6 +141,9 @@ class Collection {
209
141
  _Collection_items.set(this, new Set());
210
142
  this.add(...items);
211
143
  }
144
+ [(_Collection_items = new WeakMap(), Symbol.iterator)]() {
145
+ return tslib_1.__classPrivateFieldGet(this, _Collection_items, "f").values();
146
+ }
212
147
  add(...items) {
213
148
  for (const item of items) {
214
149
  if (item == null) {
@@ -220,8 +155,9 @@ class Collection {
220
155
  toArray() {
221
156
  return Object.freeze(Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_items, "f")));
222
157
  }
223
- [(_Collection_items = new WeakMap(), Symbol.iterator)]() {
224
- return tslib_1.__classPrivateFieldGet(this, _Collection_items, "f").values();
225
- }
226
158
  }
227
159
  exports.Collection = Collection;
160
+ function deepCopy(value) {
161
+ return (0, structured_clone_1.default)(value);
162
+ }
163
+ exports.deepCopy = deepCopy;
package/lib/index.d.ts CHANGED
@@ -1,63 +1,3 @@
1
- declare const _default: {
2
- 'attr-duplication': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
3
- 'attr-value-quotes': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./attr-value-quotes").Type, null>;
4
- 'case-sensitive-attr-name': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./case-sensitive-attr-name").Value, null>;
5
- 'case-sensitive-tag-name': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./case-sensitive-tag-name").Value, null>;
6
- 'character-reference': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
7
- 'class-naming': import("packages/@markuplint/ml-core/lib").RuleSeed<import("./class-naming").Value, null>;
8
- 'deprecated-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
9
- 'deprecated-element': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
10
- 'disallowed-element': import("packages/@markuplint/ml-core/lib").RuleSeed<string[], null>;
11
- doctype: import("packages/@markuplint/ml-core/lib").RuleSeed<"always", {
12
- denyObsolateType: boolean;
13
- }>;
14
- 'end-tag': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, null>;
15
- 'id-duplication': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
16
- 'ineffective-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
17
- 'invalid-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, {
18
- attrs?: Record<string, {
19
- enum: [string, ...string[]];
20
- } | {
21
- pattern: string;
22
- } | {
23
- type: import("packages/@markuplint/ml-spec/lib").AttributeType;
24
- } | {
25
- disallowed: true;
26
- }> | undefined;
27
- ignoreAttrNamePrefix?: string | string[] | undefined;
28
- }>;
29
- 'landmark-roles': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, {
30
- ignoreRoles: (("banner" | "main" | "complementary" | "contentinfo") | "form" | "navigation" | "region")[];
31
- labelEachArea: boolean;
32
- }>;
33
- 'no-boolean-attr-value': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
34
- 'no-default-value': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
35
- 'no-hard-code-id': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, null>;
36
- 'no-refer-to-non-existent-id': import("packages/@markuplint/ml-core/lib").RuleSeed<import("packages/@markuplint/ml-config/src").RuleConfigValue, {
37
- ariaVersion: import("packages/@markuplint/ml-spec/lib").ARIAVersion;
38
- }>;
39
- 'no-use-event-handler-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, {
40
- ignore?: string | string[] | undefined;
41
- }>;
42
- 'permitted-contents': import("packages/@markuplint/ml-core/lib").RuleSeed<(import("packages/@markuplint/ml-spec/lib").ContentModel & {
43
- tag: string;
44
- })[], {
45
- ignoreHasMutableChildren: boolean;
46
- }>;
47
- 'require-accessible-name': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, {
48
- ariaVersion: import("packages/@markuplint/ml-spec/lib").ARIAVersion;
49
- }>;
50
- 'required-attr': import("packages/@markuplint/ml-core/lib").RuleSeed<string | (string | {
51
- name: string;
52
- value: string | string[];
53
- })[], null>;
54
- 'required-element': import("packages/@markuplint/ml-core/lib").RuleSeed<string[], {
55
- ignoreHasMutableContents: boolean;
56
- }>;
57
- 'required-h1': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, import("./required-h1").Options>;
58
- 'use-list': import("packages/@markuplint/ml-core/lib").RuleSeed<string[], {
59
- spaceNeededBullets?: string[] | undefined;
60
- }>;
61
- 'wai-aria': import("packages/@markuplint/ml-core/lib").RuleSeed<boolean, import("./wai-aria/types").Options>;
62
- };
1
+ import type { AnyRuleSeed } from '@markuplint/ml-core';
2
+ declare const _default: Record<string, AnyRuleSeed>;
63
3
  export default _default;
package/lib/index.js CHANGED
@@ -15,9 +15,11 @@ const end_tag_1 = tslib_1.__importDefault(require("./end-tag"));
15
15
  const id_duplication_1 = tslib_1.__importDefault(require("./id-duplication"));
16
16
  const ineffective_attr_1 = tslib_1.__importDefault(require("./ineffective-attr"));
17
17
  const invalid_attr_1 = tslib_1.__importDefault(require("./invalid-attr"));
18
+ const label_has_control_1 = tslib_1.__importDefault(require("./label-has-control"));
18
19
  const landmark_roles_1 = tslib_1.__importDefault(require("./landmark-roles"));
19
20
  const no_boolean_attr_value_1 = tslib_1.__importDefault(require("./no-boolean-attr-value"));
20
21
  const no_default_value_1 = tslib_1.__importDefault(require("./no-default-value"));
22
+ const no_empty_palpable_content_1 = tslib_1.__importDefault(require("./no-empty-palpable-content"));
21
23
  const no_hard_code_id_1 = tslib_1.__importDefault(require("./no-hard-code-id"));
22
24
  const no_refer_to_non_existent_id_1 = tslib_1.__importDefault(require("./no-refer-to-non-existent-id"));
23
25
  const no_use_event_handler_attr_1 = tslib_1.__importDefault(require("./no-use-event-handler-attr"));
@@ -43,9 +45,11 @@ exports.default = {
43
45
  'id-duplication': id_duplication_1.default,
44
46
  'ineffective-attr': ineffective_attr_1.default,
45
47
  'invalid-attr': invalid_attr_1.default,
48
+ 'label-has-control': label_has_control_1.default,
46
49
  'landmark-roles': landmark_roles_1.default,
47
50
  'no-boolean-attr-value': no_boolean_attr_value_1.default,
48
51
  'no-default-value': no_default_value_1.default,
52
+ 'no-empty-palpable-content': no_empty_palpable_content_1.default,
49
53
  'no-hard-code-id': no_hard_code_id_1.default,
50
54
  'no-refer-to-non-existent-id': no_refer_to_non_existent_id_1.default,
51
55
  'no-use-event-handler-attr': no_use_event_handler_attr_1.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
  const attrSpec = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);