@markuplint/rules 3.0.0-alpha.2 → 3.0.0-alpha.27

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 (62) hide show
  1. package/README.md +10 -44
  2. package/lib/attr-check.d.ts +2 -2
  3. package/lib/attr-value-quotes/index.d.ts +3 -3
  4. package/lib/case-sensitive-attr-name/index.d.ts +1 -1
  5. package/lib/case-sensitive-tag-name/index.d.ts +1 -1
  6. package/lib/class-naming/index.d.ts +1 -1
  7. package/lib/class-naming/index.js +1 -1
  8. package/lib/debug.d.ts +1 -1
  9. package/lib/doctype/index.d.ts +1 -1
  10. package/lib/doctype/index.js +1 -1
  11. package/lib/end-tag/index.js +2 -17
  12. package/lib/helpers.d.ts +2 -31
  13. package/lib/helpers.js +1 -71
  14. package/lib/index.d.ts +2 -58
  15. package/lib/index.js +4 -0
  16. package/lib/invalid-attr/index.d.ts +3 -2
  17. package/lib/invalid-attr/index.js +16 -11
  18. package/lib/label-has-control/index.d.ts +2 -0
  19. package/lib/label-has-control/index.js +28 -0
  20. package/lib/landmark-roles/index.d.ts +3 -3
  21. package/lib/landmark-roles/index.js +2 -2
  22. package/lib/no-empty-palpable-content/index.d.ts +6 -0
  23. package/lib/no-empty-palpable-content/index.js +34 -0
  24. package/lib/no-refer-to-non-existent-id/index.js +1 -1
  25. package/lib/no-use-event-handler-attr/index.d.ts +1 -1
  26. package/lib/no-use-event-handler-attr/index.js +4 -4
  27. package/lib/permitted-contents/debug.browser.d.ts +30 -0
  28. package/lib/permitted-contents/debug.browser.js +14 -0
  29. package/lib/permitted-contents/debug.d.ts +1 -0
  30. package/lib/permitted-contents/debug.js +9 -1
  31. package/lib/permitted-contents/index.js +4 -4
  32. package/lib/permitted-contents/matches-selector.d.ts +1 -1
  33. package/lib/permitted-contents/represent-transparent-nodes.d.ts +1 -1
  34. package/lib/permitted-contents/represent-transparent-nodes.js +0 -3
  35. package/lib/permitted-contents/start.js +1 -1
  36. package/lib/permitted-contents/transparent.js +6 -11
  37. package/lib/permitted-contents/types.d.ts +12 -12
  38. package/lib/permitted-contents/utils.d.ts +4 -4
  39. package/lib/permitted-contents/utils.js +8 -8
  40. package/lib/require-accessible-name/index.d.ts +1 -1
  41. package/lib/require-accessible-name/index.js +7 -3
  42. package/lib/required-attr/index.d.ts +2 -2
  43. package/lib/required-element/index.d.ts +1 -1
  44. package/lib/required-element/index.js +1 -1
  45. package/lib/required-h1/index.js +2 -2
  46. package/lib/use-list/index.d.ts +2 -2
  47. package/lib/use-list/index.js +1 -1
  48. package/lib/wai-aria/checkings/abstract-role.js +1 -1
  49. package/lib/wai-aria/checkings/implicit-role.js +1 -1
  50. package/lib/wai-aria/checkings/{non-existant-role.d.ts → non-existent-role.d.ts} +1 -1
  51. package/lib/wai-aria/checkings/{non-existant-role.js → non-existent-role.js} +4 -4
  52. package/lib/wai-aria/checkings/permitted-roles.js +1 -1
  53. package/lib/wai-aria/checkings/presentational-children.js +1 -1
  54. package/lib/wai-aria/checkings/required-owned-elements.js +40 -10
  55. package/lib/wai-aria/checkings/value.d.ts +6 -0
  56. package/lib/wai-aria/checkings/value.js +74 -4
  57. package/lib/wai-aria/index.js +14 -14
  58. package/lib/wai-aria/types.d.ts +1 -1
  59. package/package.json +11 -8
  60. package/schema.json +6 -0
  61. package/tsconfig.test.json +0 -3
  62. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,30 @@
1
+ /// <reference types="debug" />
2
+ export declare const cmLog: import("debug").Debugger;
3
+ export declare const bgGreen: {
4
+ (): void;
5
+ bold(): void;
6
+ };
7
+ export declare const green: {
8
+ (): void;
9
+ bold(): void;
10
+ };
11
+ export declare const bgRed: {
12
+ (): void;
13
+ bold(): void;
14
+ };
15
+ export declare const bgBlue: {
16
+ (): void;
17
+ bold(): void;
18
+ };
19
+ export declare const blue: {
20
+ (): void;
21
+ bold(): void;
22
+ };
23
+ export declare const bgMagenta: {
24
+ (): void;
25
+ bold(): void;
26
+ };
27
+ export declare const cyan: {
28
+ (): void;
29
+ bold(): void;
30
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cyan = exports.bgMagenta = exports.blue = exports.bgBlue = exports.bgRed = exports.green = exports.bgGreen = exports.cmLog = void 0;
4
+ const debug_1 = require("../debug");
5
+ exports.cmLog = debug_1.log.extend('content-model');
6
+ const fn = () => { };
7
+ fn.bold = () => { };
8
+ exports.bgGreen = fn;
9
+ exports.green = fn;
10
+ exports.bgRed = fn;
11
+ exports.bgBlue = fn;
12
+ exports.blue = fn;
13
+ exports.bgMagenta = fn;
14
+ exports.cyan = fn;
@@ -1,2 +1,3 @@
1
1
  /// <reference types="debug" />
2
2
  export declare const cmLog: import("debug").Debugger;
3
+ export { bgGreen, green, bgRed, bgBlue, blue, bgMagenta, cyan } from 'ansi-colors';
@@ -1,5 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cmLog = void 0;
3
+ exports.cyan = exports.bgMagenta = exports.blue = exports.bgBlue = exports.bgRed = exports.green = exports.bgGreen = exports.cmLog = void 0;
4
4
  const debug_1 = require("../debug");
5
5
  exports.cmLog = debug_1.log.extend('content-model');
6
+ var ansi_colors_1 = require("ansi-colors");
7
+ Object.defineProperty(exports, "bgGreen", { enumerable: true, get: function () { return ansi_colors_1.bgGreen; } });
8
+ Object.defineProperty(exports, "green", { enumerable: true, get: function () { return ansi_colors_1.green; } });
9
+ Object.defineProperty(exports, "bgRed", { enumerable: true, get: function () { return ansi_colors_1.bgRed; } });
10
+ Object.defineProperty(exports, "bgBlue", { enumerable: true, get: function () { return ansi_colors_1.bgBlue; } });
11
+ Object.defineProperty(exports, "blue", { enumerable: true, get: function () { return ansi_colors_1.blue; } });
12
+ Object.defineProperty(exports, "bgMagenta", { enumerable: true, get: function () { return ansi_colors_1.bgMagenta; } });
13
+ Object.defineProperty(exports, "cyan", { enumerable: true, get: function () { return ansi_colors_1.cyan; } });
@@ -14,10 +14,10 @@ exports.default = (0, ml_core_1.createRule)({
14
14
  if (!el.rule.value) {
15
15
  return;
16
16
  }
17
- if (el.rule.option.ignoreHasMutableChildren && el.hasMutableChildren()) {
17
+ if (el.rule.options.ignoreHasMutableChildren && el.hasMutableChildren()) {
18
18
  return;
19
19
  }
20
- const results = (0, content_model_1.contentModel)(el, el.rule.value, el.rule.option);
20
+ const results = (0, content_model_1.contentModel)(el, el.rule.value, el.rule.options);
21
21
  for (const { type, scope, query, hint } of results) {
22
22
  let message = '';
23
23
  if (hint) {
@@ -75,10 +75,10 @@ exports.default = (0, ml_core_1.createRule)({
75
75
  });
76
76
  break;
77
77
  }
78
- case 'VOID_ELEMENT': {
78
+ case 'NOTHING': {
79
79
  report({
80
80
  scope: el,
81
- message: t('{0} is {1}', t('the {0}', 'element'), t('a {0}', 'void element')),
81
+ message: t('{0} disallows {1}', t('the {0}', 'element'), 'contents'),
82
82
  });
83
83
  break;
84
84
  }
@@ -1,3 +1,3 @@
1
1
  import type { ChildNode, Options, Result, Specs } from './types';
2
- export declare type SelectorResult = Result<'UNMATCHED_SELECTOR_BUT_MAY_EMPTY' | 'MISSING_NODE' | 'UNMATCHED_SELECTORS'>;
2
+ export type SelectorResult = Result<'UNMATCHED_SELECTOR_BUT_MAY_EMPTY' | 'MISSING_NODE' | 'UNMATCHED_SELECTORS'>;
3
3
  export declare function matchesSelector(query: string, node: ChildNode | undefined, specs: Specs, options: Options, depth: number): SelectorResult;
@@ -1,5 +1,5 @@
1
1
  import type { ChildNode, Options, Result, Specs } from './types';
2
- export declare const transparentMode: Map<import("packages/@markuplint/ml-core/lib/ml-dom/node/child-node").MLChildNode<import("./types").TagRule[], Options>, true>;
2
+ export declare const transparentMode: Map<ChildNode, true>;
3
3
  export declare function representTransparentNodes(nodes: ChildNode[], specs: Specs, options: Options): {
4
4
  nodes: ChildNode[];
5
5
  errors: Result[];
@@ -13,9 +13,6 @@ function representTransparentNodes(nodes, specs, options) {
13
13
  if (parent) {
14
14
  const { errors: parentErrors } = representTransparentNodes([parent], specs, options);
15
15
  errors.push(...parentErrors);
16
- // if (!Array.isArray(parentRes)) {
17
- // return parentRes;
18
- // }
19
16
  }
20
17
  for (const node of nodes) {
21
18
  if (!node.is(node.ELEMENT_NODE)) {
@@ -19,7 +19,7 @@ function start(contents, el, specs, options) {
19
19
  if (el.childNodes.length) {
20
20
  return [
21
21
  {
22
- type: 'VOID_ELEMENT',
22
+ type: 'NOTHING',
23
23
  scope: el,
24
24
  query: ':not(*)',
25
25
  hint: {},
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transparent = void 0;
4
- const count_pattern_1 = require("./count-pattern");
5
4
  const debug_1 = require("./debug");
6
- const utils_1 = require("./utils");
7
5
  const transparentLog = debug_1.cmLog.extend('transparent');
8
6
  function transparent(nodes, specs, options, depth) {
9
7
  var _a;
@@ -19,16 +17,13 @@ function transparent(nodes, specs, options, depth) {
19
17
  };
20
18
  }
21
19
  transparentLog('Transparent model element is component root');
22
- const collection = new utils_1.Collection(nodes);
23
- const result = (0, count_pattern_1.countPattern)({ zeroOrMore: ':model(flow)' }, collection.unmatched, specs, options, depth);
24
- collection.addMatched(result.matched);
25
20
  return {
26
- type: result.type,
27
- matched: collection.matched,
28
- unmatched: collection.unmatched,
29
- zeroMatch: result.zeroMatch,
30
- query: result.query,
31
- hint: result.hint,
21
+ type: 'MATCHED',
22
+ matched: nodes.slice(),
23
+ unmatched: [],
24
+ zeroMatch: false,
25
+ query: 'transparent',
26
+ hint: {},
32
27
  };
33
28
  }
34
29
  exports.transparent = transparent;
@@ -1,8 +1,8 @@
1
- import type { Element as _Element } from '@markuplint/ml-core';
1
+ import type { Element as _Element, ChildNode as _ChildNode } from '@markuplint/ml-core';
2
2
  import type { ContentModel, MLMLSpec } from '@markuplint/ml-spec';
3
- export declare type Element = _Element<TagRule[], Options>;
4
- export declare type ChildNode = Element['childNodes'][0];
5
- export declare type Specs = {
3
+ export type Element = _Element<TagRule[], Options>;
4
+ export type ChildNode = _ChildNode<TagRule[], Options>;
5
+ export type Specs = {
6
6
  cites: MLMLSpec['cites'];
7
7
  def: MLMLSpec['def'];
8
8
  specs: {
@@ -12,13 +12,13 @@ export declare type Specs = {
12
12
  };
13
13
  }[];
14
14
  };
15
- export declare type ContentModelResult = {
15
+ export type ContentModelResult = {
16
16
  type: MatchedReason | UnmatchedReason;
17
17
  scope: ChildNode;
18
18
  query: Result['query'];
19
19
  hint: Result['hint'];
20
20
  };
21
- export declare type Result<T extends string = MatchedReason> = {
21
+ export type Result<T extends string = MatchedReason> = {
22
22
  type: MatchedReason | UnmatchedReason | T;
23
23
  matched: ChildNode[];
24
24
  unmatched: ChildNode[];
@@ -30,16 +30,16 @@ export declare type Result<T extends string = MatchedReason> = {
30
30
  transparent?: Element;
31
31
  };
32
32
  };
33
- export declare type MatchedReason = 'MATCHED' | 'MATCHED_ZERO';
34
- export declare type UnmatchedReason = 'VOID_ELEMENT' | 'UNEXPECTED_EXTRA_NODE' | 'TRANSPARENT_MODEL_DISALLOWS' | MissingNodeReason;
35
- export declare type MissingNodeReason = 'MISSING_NODE_REQUIRED' | 'MISSING_NODE_ONE_OR_MORE';
36
- export declare type TransparentModel = {
33
+ export type MatchedReason = 'MATCHED' | 'MATCHED_ZERO';
34
+ export type UnmatchedReason = 'NOTHING' | 'UNEXPECTED_EXTRA_NODE' | 'TRANSPARENT_MODEL_DISALLOWS' | MissingNodeReason;
35
+ export type MissingNodeReason = 'MISSING_NODE_REQUIRED' | 'MISSING_NODE_ONE_OR_MORE';
36
+ export type TransparentModel = {
37
37
  el: Element;
38
38
  additionalCondition: string;
39
39
  };
40
- export declare type TagRule = {
40
+ export type TagRule = {
41
41
  tag: string;
42
42
  } & ContentModel;
43
- export declare type Options = {
43
+ export type Options = {
44
44
  ignoreHasMutableChildren: boolean;
45
45
  };
@@ -7,7 +7,7 @@ export declare function matches(selector: string, node: ChildNode, specs: Specs)
7
7
  not?: undefined;
8
8
  } | {
9
9
  matched: boolean;
10
- not: import("packages/@markuplint/ml-core/lib/ml-dom/node/child-node").MLChildNode<import("./types").TagRule[], import("./types").Options> | undefined;
10
+ not: ChildNode | undefined;
11
11
  };
12
12
  export declare function isRequire(content: PermittedContentPattern): content is PermittedContentRequire;
13
13
  export declare function isOptional(content: PermittedContentPattern): content is PermittedContentOptional;
@@ -18,10 +18,10 @@ export declare function isTransparent(content: PermittedContentPattern): content
18
18
  export declare class Collection {
19
19
  #private;
20
20
  constructor(origin: readonly ChildNode[]);
21
- get matched(): import("packages/@markuplint/ml-core/lib/ml-dom/node/child-node").MLChildNode<import("./types").TagRule[], import("./types").Options>[];
21
+ get matched(): ChildNode[];
22
22
  get matchedCount(): number;
23
- get nodes(): import("packages/@markuplint/ml-core/lib/ml-dom/node/child-node").MLChildNode<import("./types").TagRule[], import("./types").Options>[];
24
- get unmatched(): import("packages/@markuplint/ml-core/lib/ml-dom/node/child-node").MLChildNode<import("./types").TagRule[], import("./types").Options>[];
23
+ get nodes(): ChildNode[];
24
+ get unmatched(): ChildNode[];
25
25
  addMatched(nodes: ChildNode[]): boolean;
26
26
  back(): void;
27
27
  lock(): void;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.UnsupportedError = exports.Collection = exports.isTransparent = exports.isChoice = exports.isZeroOrMore = exports.isOneOrMore = exports.isOptional = exports.isRequire = exports.matches = exports.isModel = exports.getChildNodesWithoutWhitespaces = void 0;
5
5
  const tslib_1 = require("tslib");
6
6
  const selector_1 = require("@markuplint/selector");
7
- const ansi_colors_1 = require("ansi-colors");
7
+ const debug_1 = require("./debug");
8
8
  const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
9
9
  const getChildNodesWithoutWhitespacesCaches = new Map();
10
10
  function getChildNodesWithoutWhitespaces(el) {
@@ -142,33 +142,33 @@ class Collection {
142
142
  const raw = n.is(n.TEXT_NODE) ? `:text(${n.raw.replace(/\n/g, '\\n')})` : n.raw;
143
143
  if (tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f").has(n)) {
144
144
  if (represent_transparent_nodes_1.transparentMode.has(n)) {
145
- out.push(ansi_colors_1.bgBlue.bold(raw));
145
+ out.push(debug_1.bgBlue.bold(raw));
146
146
  }
147
147
  else {
148
- out.push(ansi_colors_1.bgGreen.bold(raw));
148
+ out.push(debug_1.bgGreen.bold(raw));
149
149
  }
150
150
  continue;
151
151
  }
152
152
  if (tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n)) {
153
153
  if (represent_transparent_nodes_1.transparentMode.has(n)) {
154
- out.push(ansi_colors_1.blue.bold(raw));
154
+ out.push(debug_1.blue.bold(raw));
155
155
  }
156
156
  else {
157
- out.push(ansi_colors_1.green.bold(raw));
157
+ out.push(debug_1.green.bold(raw));
158
158
  }
159
159
  continue;
160
160
  }
161
161
  if (highlightExtraNodes) {
162
162
  if (represent_transparent_nodes_1.transparentMode.has(n)) {
163
- out.push(ansi_colors_1.bgMagenta.bold(raw));
163
+ out.push(debug_1.bgMagenta.bold(raw));
164
164
  }
165
165
  else {
166
- out.push(ansi_colors_1.bgRed.bold(raw));
166
+ out.push(debug_1.bgRed.bold(raw));
167
167
  }
168
168
  continue;
169
169
  }
170
170
  if (represent_transparent_nodes_1.transparentMode.has(n)) {
171
- out.push((0, ansi_colors_1.cyan)(raw));
171
+ out.push((0, debug_1.cyan)(raw));
172
172
  }
173
173
  else {
174
174
  out.push(raw);
@@ -1,5 +1,5 @@
1
1
  import type { ARIAVersion } from '@markuplint/ml-spec';
2
- declare type Option = {
2
+ type Option = {
3
3
  ariaVersion: ARIAVersion;
4
4
  };
5
5
  declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Option>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
+ const 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: {
@@ -15,15 +16,18 @@ exports.default = (0, ml_core_1.createRule)({
15
16
  if ((0, helpers_1.accnameMayBeMutable)(el, document)) {
16
17
  return;
17
18
  }
18
- 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);
19
23
  if (!computed.role) {
20
24
  return;
21
25
  }
22
- 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);
23
27
  if (!roleSpec || !roleSpec.accessibleNameRequired) {
24
28
  return;
25
29
  }
26
- const hasAccessibleName = !!el.getAccessibleName(el.rule.option.ariaVersion).trim();
30
+ const hasAccessibleName = !!el.getAccessibleName(el.rule.options.ariaVersion).trim();
27
31
  if (!hasAccessibleName) {
28
32
  report({ scope: el, message: t('Require {0}', 'accessible name') });
29
33
  }
@@ -1,5 +1,5 @@
1
- declare type RequiredAttributes = string | (string | Attr)[];
2
- declare type Attr = {
1
+ type RequiredAttributes = string | (string | Attr)[];
2
+ type Attr = {
3
3
  name: string;
4
4
  value: string | string[];
5
5
  };
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  ignoreHasMutableContents: boolean;
3
3
  };
4
4
  declare const _default: import("@markuplint/ml-core").RuleSeed<string[], Options>;
@@ -26,7 +26,7 @@ exports.default = (0, ml_core_1.createRule)({
26
26
  if (el.rule.value === document.rule.value) {
27
27
  return;
28
28
  }
29
- if (el.rule.option.ignoreHasMutableContents && el.hasMutableChildren()) {
29
+ if (el.rule.options.ignoreHasMutableContents && el.hasMutableChildren()) {
30
30
  return;
31
31
  }
32
32
  for (const query of el.rule.value) {
@@ -11,7 +11,7 @@ exports.default = (0, ml_core_1.createRule)({
11
11
  if (document.nodeList.length === 0) {
12
12
  return;
13
13
  }
14
- if (!document.rule.option['in-document-fragment'] && document.isFragment) {
14
+ if (!document.rule.options['in-document-fragment'] && document.isFragment) {
15
15
  return;
16
16
  }
17
17
  await document.walkOn('Element', node => {
@@ -28,7 +28,7 @@ exports.default = (0, ml_core_1.createRule)({
28
28
  raw: document.nodeList[0].raw.slice(0, 1),
29
29
  });
30
30
  }
31
- else if (document.rule.option['expected-once'] && h1Stack.length > 1) {
31
+ else if (document.rule.options['expected-once'] && h1Stack.length > 1) {
32
32
  const message = t('{0} is {1:c}', t('the "{0*}" {1}', 'h1', 'element'), 'duplicated');
33
33
  report({
34
34
  message,
@@ -1,5 +1,5 @@
1
- declare type Bullets = string[];
2
- declare type Options = {
1
+ type Bullets = string[];
2
+ type Options = {
3
3
  spaceNeededBullets?: string[];
4
4
  };
5
5
  declare const _default: import("@markuplint/ml-core").RuleSeed<Bullets, Options>;
@@ -67,7 +67,7 @@ exports.default = (0, ml_core_1.createRule)({
67
67
  return;
68
68
  }
69
69
  const bullets = textNode.rule.value;
70
- const spaceNeededBullets = textNode.rule.option.spaceNeededBullets || [];
70
+ const spaceNeededBullets = textNode.rule.options.spaceNeededBullets || [];
71
71
  if (isMayListItem(text, bullets, spaceNeededBullets)) {
72
72
  report({
73
73
  scope: textNode,
@@ -4,7 +4,7 @@ exports.checkingAbstractRole = void 0;
4
4
  const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingAbstractRole = ({ attr }) => t => {
6
6
  var _a;
7
- const { roles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.option.version);
7
+ const { roles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.options.version);
8
8
  const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
9
9
  if (!tokens) {
10
10
  return;
@@ -4,7 +4,7 @@ exports.checkingImplicitRole = void 0;
4
4
  const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingImplicitRole = ({ attr }) => t => {
6
6
  var _a;
7
- const implicitRole = (0, ml_spec_1.getImplicitRoleName)(attr.ownerElement, attr.rule.option.version, attr.ownerMLDocument.specs);
7
+ const implicitRole = (0, ml_spec_1.getImplicitRoleName)(attr.ownerElement, attr.rule.options.version, attr.ownerMLDocument.specs);
8
8
  const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
9
9
  if (!tokens) {
10
10
  return;
@@ -1,3 +1,3 @@
1
1
  import type { Options } from '../types';
2
2
  import type { AttrChecker } from '@markuplint/ml-core';
3
- export declare const checkingNonExistantRole: AttrChecker<boolean, Options>;
3
+ export declare const checkingNonExistentRole: AttrChecker<boolean, Options>;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkingNonExistantRole = void 0;
3
+ exports.checkingNonExistentRole = void 0;
4
4
  const ml_spec_1 = require("@markuplint/ml-spec");
5
- const checkingNonExistantRole = ({ attr }) => t => {
5
+ const checkingNonExistentRole = ({ attr }) => t => {
6
6
  var _a;
7
- const { roles, graphicsRoles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.option.version);
7
+ const { roles, graphicsRoles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.options.version);
8
8
  const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
9
9
  if (!tokens) {
10
10
  return;
@@ -25,4 +25,4 @@ const checkingNonExistantRole = ({ attr }) => t => {
25
25
  }
26
26
  }
27
27
  };
28
- exports.checkingNonExistantRole = checkingNonExistantRole;
28
+ exports.checkingNonExistentRole = checkingNonExistentRole;
@@ -5,7 +5,7 @@ const ml_spec_1 = require("@markuplint/ml-spec");
5
5
  const checkingPermittedRoles = ({ attr }) => t => {
6
6
  var _a;
7
7
  const el = attr.ownerElement;
8
- const permittedRoles = (0, ml_spec_1.getPermittedRoles)(el, el.rule.option.version, attr.ownerMLDocument.specs);
8
+ const permittedRoles = (0, ml_spec_1.getPermittedRoles)(el, el.rule.options.version, attr.ownerMLDocument.specs);
9
9
  if (permittedRoles.length === 0) {
10
10
  return {
11
11
  scope: attr,
@@ -50,7 +50,7 @@ function getAncestorHasPresentationalChildren(el) {
50
50
  var _a;
51
51
  let current = el.parentElement;
52
52
  while (current) {
53
- const computed = (0, ml_spec_1.getComputedRole)(el.ownerMLDocument.specs, current, el.rule.option.version);
53
+ const computed = (0, ml_spec_1.getComputedRole)(el.ownerMLDocument.specs, current, el.rule.options.version);
54
54
  if ((_a = computed.role) === null || _a === void 0 ? void 0 : _a.childrenPresentational) {
55
55
  return computed;
56
56
  }
@@ -28,18 +28,13 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
28
28
  return;
29
29
  }
30
30
  // TODO: Needs to resolve `aria-own`
31
- if (el.isEmpty()) {
32
- return {
33
- scope: el,
34
- message: t('{0}. Or, {1}', t('require {0}', role.requiredOwnedElements.length === 1
35
- ? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
36
- : t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`), t('require {0}', 'aria-busy="true"')),
37
- };
38
- }
39
31
  const children = Array.from(el.childNodes).map(child => {
40
32
  if (child.is(child.ELEMENT_NODE)) {
41
- const computedChild = (0, ml_spec_1.getComputedRole)(child.ownerMLDocument.specs, child, child.rule.option.version);
42
- if (role.requiredOwnedElements.some(ownedRole => (0, ml_spec_1.isRequiredOwnedElement)(computedChild, ownedRole, child.ownerMLDocument.specs, child.rule.option.version))) {
33
+ if (child.matches('[aria-busy="true" i]')) {
34
+ return [child, 'BUSY'];
35
+ }
36
+ const computedChild = (0, ml_spec_1.getComputedRole)(child.ownerMLDocument.specs, child, child.rule.options.version);
37
+ if (role.requiredOwnedElements.some(ownedRole => (0, ml_spec_1.isRequiredOwnedElement)(computedChild, ownedRole, child.ownerMLDocument.specs, child.rule.options.version))) {
43
38
  return [child, 'REQUIRED'];
44
39
  }
45
40
  return [child, 'OTHER'];
@@ -49,6 +44,9 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
49
44
  }
50
45
  return [null, 'NO_ELEMENT'];
51
46
  });
47
+ if (children.some(([, type]) => type === 'BUSY')) {
48
+ return;
49
+ }
52
50
  /**
53
51
  * > Any element that will be owned by the element with this role.
54
52
  * > For example, an element with the role list
@@ -61,6 +59,30 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
61
59
  // TODO: https://github.com/markuplint/markuplint/issues/490
62
60
  return;
63
61
  }
62
+ /**
63
+ * Has mutable children
64
+ *
65
+ * Ex:
66
+ *
67
+ * ```jsx
68
+ * <table>
69
+ * <tbody>
70
+ * {list.map((item) => <tr><td>{item}</td></tr>)}
71
+ * </tbody>
72
+ * </table>
73
+ * ```
74
+ */
75
+ if (el.hasMutableChildren(true)) {
76
+ return;
77
+ }
78
+ if (mayBeBeforeCreated(el)) {
79
+ return {
80
+ scope: el,
81
+ message: t('{0}. Or, {1}', t('require {0}', role.requiredOwnedElements.length === 1
82
+ ? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
83
+ : t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`), t('require {0}', 'aria-busy="true"')),
84
+ };
85
+ }
64
86
  return {
65
87
  scope: el,
66
88
  message: t('{0} expects {1}', t('the "{0*}" {1}', role.name, 'role'), role.requiredOwnedElements.length === 1
@@ -69,3 +91,11 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
69
91
  };
70
92
  };
71
93
  exports.checkingRequiredOwnedElements = checkingRequiredOwnedElements;
94
+ function mayBeBeforeCreated(el) {
95
+ if (el.isEmpty()) {
96
+ return true;
97
+ }
98
+ return Array.from(el.children).every(child => {
99
+ return ['script', 'template'].includes(child.localName);
100
+ });
101
+ }
@@ -4,4 +4,10 @@ import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
4
4
  export declare const checkingValue: AttrChecker<boolean, Options, {
5
5
  role?: ARIARole | null;
6
6
  propSpecs: ARIAProperty[];
7
+ booleanish?: boolean;
7
8
  }>;
9
+ /**
10
+ *
11
+ * @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
12
+ */
13
+ export declare function checkAriaValue(type: string, value: string, tokenEnum: string[], booleanish?: boolean): boolean;
@@ -1,14 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkingValue = void 0;
4
- const helpers_1 = require("../../helpers");
5
- const checkingValue = ({ attr, role, propSpecs }) => t => {
3
+ exports.checkAriaValue = exports.checkingValue = void 0;
4
+ const checkingValue = ({ attr, role, propSpecs, booleanish }) => t => {
6
5
  var _a;
7
6
  if (attr.isDynamicValue) {
8
7
  return;
9
8
  }
10
9
  const propSpec = propSpecs.find(p => p.name === attr.name);
11
- const result = (0, helpers_1.checkAria)(attr.ownerMLDocument.specs, attr.name, attr.value, attr.rule.option.version, role === null || role === void 0 ? void 0 : role.name);
10
+ const result = checkAria(propSpec, attr.value, role === null || role === void 0 ? void 0 : role.name, booleanish);
12
11
  if (result.isValid) {
13
12
  return;
14
13
  }
@@ -19,3 +18,74 @@ const checkingValue = ({ attr, role, propSpecs }) => t => {
19
18
  };
20
19
  };
21
20
  exports.checkingValue = checkingValue;
21
+ function checkAria(propSpec, currentValue, role, booleanish) {
22
+ if (!propSpec) {
23
+ return {
24
+ currentValue,
25
+ // For skipping checking
26
+ isValid: true,
27
+ };
28
+ }
29
+ let valueType = propSpec.value;
30
+ if (role && propSpec.conditionalValue) {
31
+ for (const cond of propSpec.conditionalValue) {
32
+ if (cond.role.includes(role)) {
33
+ valueType = cond.value;
34
+ break;
35
+ }
36
+ }
37
+ }
38
+ const isValid = checkAriaValue(valueType, currentValue, propSpec.enum, booleanish);
39
+ return {
40
+ ...propSpec,
41
+ currentValue,
42
+ isValid,
43
+ };
44
+ }
45
+ /**
46
+ *
47
+ * @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
48
+ */
49
+ function checkAriaValue(type, value, tokenEnum, booleanish) {
50
+ switch (type) {
51
+ case 'token': {
52
+ return tokenEnum.includes(value);
53
+ }
54
+ case 'token list': {
55
+ const list = value.split(/\s+/g).map(s => s.trim());
56
+ return list.every(token => tokenEnum.includes(token));
57
+ }
58
+ case 'string':
59
+ case 'ID reference':
60
+ case 'ID reference list': {
61
+ return true;
62
+ }
63
+ case 'true/false': {
64
+ if (booleanish && value === '') {
65
+ return true;
66
+ }
67
+ return ['true', 'false'].includes(value);
68
+ }
69
+ case 'tristate': {
70
+ if (booleanish && value === '') {
71
+ return true;
72
+ }
73
+ return ['mixed', 'true', 'false', 'undefined'].includes(value);
74
+ }
75
+ case 'true/false/undefined': {
76
+ if (booleanish && value === '') {
77
+ return true;
78
+ }
79
+ return ['true', 'false', 'undefined'].includes(value);
80
+ }
81
+ case 'integer': {
82
+ return parseInt(value).toString() === value;
83
+ }
84
+ case 'number': {
85
+ return parseFloat(value).toString() === value;
86
+ }
87
+ }
88
+ // For skipping checking
89
+ return true;
90
+ }
91
+ exports.checkAriaValue = checkAriaValue;