@markuplint/rules 4.0.0-dev.28 → 4.0.0-rc.0

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 (42) hide show
  1. package/.eslintrc +5 -0
  2. package/LICENSE +1 -1
  3. package/lib/attr-duplication/index.js +3 -0
  4. package/lib/attr-value-quotes/index.js +3 -1
  5. package/lib/case-sensitive-attr-name/index.js +3 -0
  6. package/lib/case-sensitive-tag-name/index.js +3 -0
  7. package/lib/character-reference/index.js +3 -0
  8. package/lib/class-naming/index.js +4 -1
  9. package/lib/deprecated-attr/index.js +3 -0
  10. package/lib/deprecated-element/index.js +3 -0
  11. package/lib/disallowed-element/index.js +3 -0
  12. package/lib/doctype/index.js +3 -0
  13. package/lib/end-tag/index.js +3 -0
  14. package/lib/id-duplication/index.js +3 -0
  15. package/lib/index.d.ts +4 -0
  16. package/lib/ineffective-attr/index.js +3 -0
  17. package/lib/invalid-attr/index.js +3 -0
  18. package/lib/label-has-control/index.js +3 -0
  19. package/lib/landmark-roles/index.js +3 -0
  20. package/lib/no-boolean-attr-value/index.js +3 -0
  21. package/lib/no-default-value/index.js +3 -0
  22. package/lib/no-empty-palpable-content/index.js +3 -0
  23. package/lib/no-hard-code-id/index.js +3 -0
  24. package/lib/no-refer-to-non-existent-id/index.js +3 -0
  25. package/lib/no-use-event-handler-attr/index.js +3 -0
  26. package/lib/permitted-contents/content-model.js +6 -3
  27. package/lib/permitted-contents/debug.browser.d.ts +2 -2
  28. package/lib/permitted-contents/debug.d.ts +2 -2
  29. package/lib/permitted-contents/index.js +3 -0
  30. package/lib/permitted-contents/matches-selector.js +2 -2
  31. package/lib/placeholder-label-option/index.js +3 -0
  32. package/lib/require-accessible-name/index.js +3 -3
  33. package/lib/require-datetime/index.js +3 -0
  34. package/lib/required-attr/index.js +3 -0
  35. package/lib/required-element/index.js +3 -0
  36. package/lib/required-h1/index.js +3 -0
  37. package/lib/use-list/index.d.ts +4 -0
  38. package/lib/use-list/index.js +46 -26
  39. package/lib/wai-aria/checkings/required-owned-elements.js +1 -1
  40. package/lib/wai-aria/checkings/value.js +1 -1
  41. package/lib/wai-aria/index.js +3 -0
  42. package/package.json +11 -11
package/.eslintrc ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "rules": {
3
+ "import/no-default-export": 0
4
+ }
5
+ }
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2019 Yusuke Hirao
3
+ Copyright (c) 2017-2024 Yusuke Hirao
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  async verify({ document, report, t }) {
4
7
  const message = t('{0} is {1:c}', t('the {0}', 'attribute name'), 'duplicated');
5
8
  await document.walkOn('Element', node => {
@@ -4,6 +4,9 @@ const quoteList = {
4
4
  single: "'",
5
5
  };
6
6
  export default createRule({
7
+ meta: {
8
+ category: 'style',
9
+ },
7
10
  defaultSeverity: 'warning',
8
11
  defaultValue: 'double',
9
12
  async verify({ document, report, t }) {
@@ -26,7 +29,6 @@ export default createRule({
26
29
  const quote = quoteList[attr.rule.value];
27
30
  if (quote && attr.startQuote && attr.startQuote.raw !== quote) {
28
31
  attr.startQuote.fix(quote);
29
- // TODO: attr.endQuote = new MLToken(quote);
30
32
  attr.endQuote?.fix(quote);
31
33
  }
32
34
  });
@@ -1,5 +1,8 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'style',
5
+ },
3
6
  defaultSeverity: 'warning',
4
7
  defaultValue: 'lower',
5
8
  async verify({ document, report, t }) {
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'style',
5
+ },
3
6
  defaultSeverity: 'warning',
4
7
  defaultValue: 'lower',
5
8
  async verify({ document, report, t }) {
@@ -2,6 +2,9 @@ import { createRule, getLocationFromChars } from '@markuplint/ml-core';
2
2
  const defaultChars = ['"', '&', '<', '>'];
3
3
  const ignoreParentElement = new Set(['script', 'style']);
4
4
  export default createRule({
5
+ meta: {
6
+ category: 'style',
7
+ },
5
8
  async verify({ document, report, t }) {
6
9
  const targetNodes = [];
7
10
  await document.walkOn('Text', node => {
@@ -2,6 +2,9 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared';
3
3
  import { match } from '../helpers.js';
4
4
  export default createRule({
5
+ meta: {
6
+ category: 'naming-convention',
7
+ },
5
8
  defaultSeverity: 'warning',
6
9
  defaultValue: null,
7
10
  async verify({ document, report, t }) {
@@ -14,7 +17,7 @@ export default createRule({
14
17
  }
15
18
  const classAttr = attr.valueNode;
16
19
  const classList = attr.value
17
- .split(/\s+/g)
20
+ .split(/\s+/)
18
21
  .map(c => c.trim())
19
22
  .filter(Boolean);
20
23
  for (const className of classList) {
@@ -1,5 +1,8 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  async verify({ document, report, t }) {
4
7
  await document.walkOn('Attr', attr => {
5
8
  const attrSpecs = getAttrSpecs(attr.ownerElement, document.specs);
@@ -1,5 +1,8 @@
1
1
  import { createRule, getSpec } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  async verify({ document, report, t }) {
4
7
  await document.walkOn('Element', el => {
5
8
  if (!(el.namespaceURI === 'http://www.w3.org/1999/xhtml' ||
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  defaultValue: [],
4
7
  async verify({ document, report, t }) {
5
8
  for (const query of document.rule.value) {
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  defaultValue: 'always',
4
7
  defaultOptions: {
5
8
  denyObsoleteType: true,
@@ -1,6 +1,9 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import { isVoidElement } from '@markuplint/ml-spec';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'style',
6
+ },
4
7
  defaultSeverity: 'warning',
5
8
  async verify({ document, report, t }) {
6
9
  if (document.endTag === 'never') {
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  async verify({ document, report, t }) {
4
7
  const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'value'), t('the "{0*}" {1}', 'id', 'attribute')), 'duplicated');
5
8
  const idStack = [];
package/lib/index.d.ts CHANGED
@@ -96,6 +96,10 @@ declare const rules: {
96
96
  readonly 'required-h1': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, import("./required-h1/index.js").Options>>;
97
97
  readonly 'use-list': Readonly<import("@markuplint/ml-core").RuleSeed<readonly string[], {
98
98
  spaceNeededBullets?: string[] | undefined;
99
+ noPrev?: boolean | undefined;
100
+ prevElement?: boolean | undefined;
101
+ prevComment?: boolean | undefined;
102
+ prevCodeBlock?: boolean | undefined;
99
103
  }>>;
100
104
  readonly 'wai-aria': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, import("./wai-aria/types.js").Options>>;
101
105
  };
@@ -1,6 +1,9 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import { toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'style',
6
+ },
4
7
  defaultSeverity: 'warning',
5
8
  async verify({ document, report, t }) {
6
9
  await document.walkOn('Attr', attr => {
@@ -4,6 +4,9 @@ import { log as ruleLog } from '../debug.js';
4
4
  import { isValidAttr, match } from '../helpers.js';
5
5
  const log = ruleLog.extend('invalid-attr');
6
6
  export default createRule({
7
+ meta: {
8
+ category: 'validation',
9
+ },
7
10
  defaultOptions: {},
8
11
  async verify({ document, report, t }) {
9
12
  await document.walkOn('Attr', attr => {
@@ -1,6 +1,9 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  const controlSelector = ["input:not([type='hidden' i])", 'select', 'textarea'].join(',');
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'a11y',
6
+ },
4
7
  defaultSeverity: 'warning',
5
8
  async verify({ document, report, t }) {
6
9
  await document.walkOn('Element', el => {
@@ -10,6 +10,9 @@ const selectors = {
10
10
  };
11
11
  const topLevelRoles = ['banner', 'main', 'complementary', 'contentinfo'];
12
12
  export default createRule({
13
+ meta: {
14
+ category: 'a11y',
15
+ },
13
16
  defaultSeverity: 'warning',
14
17
  defaultOptions: {
15
18
  ignoreRoles: [],
@@ -1,5 +1,8 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'style',
5
+ },
3
6
  defaultSeverity: 'warning',
4
7
  async verify({ document, report, t }) {
5
8
  await document.walkOn('Attr', attr => {
@@ -1,6 +1,9 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import { toNormalizedValue } from '../helpers.js';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'style',
6
+ },
4
7
  defaultSeverity: 'warning',
5
8
  async verify({ document, report, t }) {
6
9
  await document.walkOn('Attr', attr => {
@@ -1,6 +1,9 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import { isNothingContentModel, isPalpableElement } from '@markuplint/ml-spec';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'validation',
6
+ },
4
7
  defaultSeverity: 'warning',
5
8
  defaultOptions: {
6
9
  extendsExposableElements: true,
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'maintainability',
5
+ },
3
6
  defaultSeverity: 'warning',
4
7
  async verify({ document, report, t }) {
5
8
  if (!document.isFragment) {
@@ -3,6 +3,9 @@ import { ARIA_RECOMMENDED_VERSION } from '@markuplint/ml-spec';
3
3
  import { decodeEntities, decodeHref } from '@markuplint/shared';
4
4
  const HYPERLINK_SELECTOR = 'a[href], area[href]';
5
5
  export default createRule({
6
+ meta: {
7
+ category: 'a11y',
8
+ },
6
9
  defaultOptions: {
7
10
  ariaVersion: ARIA_RECOMMENDED_VERSION,
8
11
  fragmentRefersNameAttr: false,
@@ -1,6 +1,9 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import { match } from '../helpers.js';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'maintainability',
6
+ },
4
7
  defaultSeverity: 'warning',
5
8
  defaultOptions: {},
6
9
  async verify({ document, report, t }) {
@@ -3,7 +3,7 @@ import { start } from './start.js';
3
3
  export function contentModel(
4
4
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
5
5
  el, rules, options) {
6
- const model = createModel(el, rules);
6
+ const { model, specs } = createModel(el, rules);
7
7
  if (model == null) {
8
8
  return [
9
9
  {
@@ -14,7 +14,7 @@ el, rules, options) {
14
14
  },
15
15
  ];
16
16
  }
17
- const result = start(model, el, el.ownerMLDocument.specs, options);
17
+ const result = start(model, el, specs, options);
18
18
  return result;
19
19
  }
20
20
  function createModel(
@@ -22,7 +22,10 @@ function createModel(
22
22
  el, rules) {
23
23
  const specs = cachedSpecs(el.ownerMLDocument.specs, rules);
24
24
  const model = getContentModel(el, specs.specs);
25
- return model;
25
+ return {
26
+ model,
27
+ specs,
28
+ };
26
29
  }
27
30
  const caches = new Map();
28
31
  function cachedSpecs(specs, rules) {
@@ -1,5 +1,5 @@
1
- /// <reference types="debug" />
2
- export declare const cmLog: import("debug").Debugger;
1
+ import type { Log } from '../debug.js';
2
+ export declare const cmLog: Log;
3
3
  export declare const bgGreen: {
4
4
  (): void;
5
5
  bold(): void;
@@ -1,6 +1,6 @@
1
- /// <reference types="debug" />
1
+ import type { Log } from '../debug.js';
2
2
  import color from 'ansi-colors';
3
- export declare const cmLog: import("debug").Debugger;
3
+ export declare const cmLog: Log;
4
4
  export declare const bgGreen: color.StyleFunction;
5
5
  export declare const green: color.StyleFunction;
6
6
  export declare const bgRed: color.StyleFunction;
@@ -2,6 +2,9 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { contentModel } from './content-model.js';
3
3
  import { transparentMode } from './represent-transparent-nodes.js';
4
4
  export default createRule({
5
+ meta: {
6
+ category: 'validation',
7
+ },
5
8
  defaultValue: [],
6
9
  defaultOptions: {
7
10
  ignoreHasMutableChildren: true,
@@ -152,7 +152,7 @@ function optCondition(query, specs) {
152
152
  }
153
153
  let hasCustom = false;
154
154
  let hasText = false;
155
- const selector = query.replace(/^(?::model\(([^)]+)\)|#([a-z-]+))(.*)$/, (_, $model, _model, $last) => {
155
+ const selector = query.replace(/^:model\(([^)]+)\)|^#([a-z-]+)/, (_, $model, _model) => {
156
156
  const _selectors = contentModelCategoryToTagNames(`#${$model ?? _model}`, specs.def);
157
157
  if (_selectors.length === 0) {
158
158
  throw new Error(`${$model ?? _model} is empty`);
@@ -169,7 +169,7 @@ function optCondition(query, specs) {
169
169
  }
170
170
  selectors.push(selector);
171
171
  }
172
- return `:is(${selectors.join(',')})${$last ?? ''}`;
172
+ return `:is(${selectors.join(',')})`;
173
173
  });
174
174
  const result = {
175
175
  selector,
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  verify({ document, report, t }) {
4
7
  for (const select of document.querySelectorAll('select')) {
5
8
  if (hasPlaceholderLabelOption(select)) {
@@ -2,14 +2,14 @@ import { createRule, getRoleSpec, getComputedRole } from '@markuplint/ml-core';
2
2
  import { ARIA_RECOMMENDED_VERSION, isExposed } from '@markuplint/ml-spec';
3
3
  import { accnameMayBeMutable } from '../helpers.js';
4
4
  export default createRule({
5
+ meta: {
6
+ category: 'a11y',
7
+ },
5
8
  defaultOptions: {
6
9
  ariaVersion: ARIA_RECOMMENDED_VERSION,
7
10
  },
8
11
  async verify({ document, report, t }) {
9
12
  await document.walkOn('Element', el => {
10
- if (el.pretenderContext?.type === 'pretender') {
11
- return;
12
- }
13
13
  if (accnameMayBeMutable(el, document)) {
14
14
  return;
15
15
  }
@@ -2,6 +2,9 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { check } from '@markuplint/types';
3
3
  import { getCandidateDatetimeString } from './utils.js';
4
4
  export default createRule({
5
+ meta: {
6
+ category: 'validation',
7
+ },
5
8
  defaultOptions: {
6
9
  langs: undefined,
7
10
  },
@@ -1,6 +1,9 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import { attrMatches, match } from '../helpers.js';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'validation',
6
+ },
4
7
  defaultValue: [],
5
8
  async verify({ document, report, t }) {
6
9
  await document.walkOn('Element', el => {
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'validation',
5
+ },
3
6
  defaultValue: [],
4
7
  defaultOptions: {
5
8
  ignoreHasMutableContents: true,
@@ -1,5 +1,8 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  export default createRule({
3
+ meta: {
4
+ category: 'a11y',
5
+ },
3
6
  defaultOptions: {
4
7
  'expected-once': true,
5
8
  'in-document-fragment': false,
@@ -1,6 +1,10 @@
1
1
  type Bullets = readonly string[];
2
2
  type Options = {
3
3
  spaceNeededBullets?: string[];
4
+ noPrev?: boolean;
5
+ prevElement?: boolean;
6
+ prevComment?: boolean;
7
+ prevCodeBlock?: boolean;
4
8
  };
5
9
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<Bullets, Options>>;
6
10
  export default _default;
@@ -1,36 +1,39 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import { decodeEntities } from '@markuplint/shared';
3
3
  export default createRule({
4
+ meta: {
5
+ category: 'a11y',
6
+ },
4
7
  defaultValue: [
5
8
  /**
6
9
  * @see https://en.wikipedia.org/wiki/Bullet_(typography)#In_Unicode
7
10
  */
8
- '\u2022',
9
- '\u2023',
10
- '\u2043',
11
- '\u204C',
12
- '\u204D',
13
- '\u2219',
14
- '\u25CB',
15
- '\u25CF',
16
- '\u25D8',
17
- '\u25E6',
18
- '\u2619',
19
- '\u2765',
20
- '\u2767',
21
- '\u29BE',
22
- '\u29BF',
11
+ '\u2022', // • BULLET (HTML &#8226; · &bull;, &bullet;)
12
+ '\u2023', // ‣ TRIANGULAR BULLET (HTML &#8227;)
13
+ '\u2043', // ⁃ HYPHEN BULLET (HTML &#8259; · &hybull;)
14
+ '\u204C', // ⁌ BLACK LEFTWARDS BULLET (HTML &#8268;)
15
+ '\u204D', // ⁍ BLACK RIGHTWARDS BULLET (HTML &#8269;)
16
+ '\u2219', // ∙ BULLET OPERATOR (HTML &#8729;) for use in mathematical notation primarily as a dot product instead of interupt.
17
+ '\u25CB', // ○ WHITE CIRCLE (HTML &#9675; · &cir;)
18
+ '\u25CF', // ● BLACK CIRCLE (HTML &#9679;)
19
+ '\u25D8', // ◘ INVERSE BULLET (HTML &#9688;)
20
+ '\u25E6', // ◦ WHITE BULLET (HTML &#9702;)
21
+ '\u2619', // ☙ REVERSED ROTATED FLORAL HEART BULLET (HTML &#9753;); see Fleuron (typography)
22
+ '\u2765', // ❥ ROTATED HEAVY BLACK HEART BULLET (HTML &#10085;)
23
+ '\u2767', // ❧ ROTATED FLORAL HEART BULLET (HTML &#10087;); see Fleuron (typography)
24
+ '\u29BE', // ⦾ CIRCLED WHITE BULLET (HTML &#10686; · &olcir;)
25
+ '\u29BF', // ⦿ CIRCLED BULLET (HTML &#10687; · &ofcir;)
23
26
  /**
24
27
  * In Japanese
25
28
  * @see https://ja.wikipedia.org/wiki/中黒#符号位置
26
29
  */
27
- '\u00B7',
28
- '\u0387',
29
- '\u2022',
30
- '\u2219',
31
- '\u22C5',
32
- '\u30FB',
33
- '\uFF65',
30
+ '\u00B7', // MIDDLE DOT
31
+ '\u0387', // GREEK ANO TELIA
32
+ '\u2022', // BULLET
33
+ '\u2219', // BULLET OPERATOR
34
+ '\u22C5', // DOT OPERATOR
35
+ '\u30FB', // KATAKANA MIDDLE DOT
36
+ '\uFF65', // HALFWIDTH KATAKANA MIDDLE DOT
34
37
  /**
35
38
  * In Other Languages
36
39
  */
@@ -38,8 +41,8 @@ export default createRule({
38
41
  /**
39
42
  * From Markdown
40
43
  */
41
- '-',
42
- '*',
44
+ '-', // dashes
45
+ '*', // asterisks
43
46
  '+', // plus signs
44
47
  ],
45
48
  defaultOptions: {
@@ -47,10 +50,14 @@ export default createRule({
47
50
  /**
48
51
  * From Markdown
49
52
  */
50
- '-',
51
- '*',
53
+ '-', // dashes
54
+ '*', // asterisks
52
55
  '+', // plus signs
53
56
  ],
57
+ noPrev: true,
58
+ prevElement: true,
59
+ prevComment: true,
60
+ prevCodeBlock: false,
54
61
  },
55
62
  defaultSeverity: 'warning',
56
63
  async verify({ document, report, t }) {
@@ -64,6 +71,19 @@ export default createRule({
64
71
  // character only
65
72
  return;
66
73
  }
74
+ if (textNode.rule.options.noPrev === false && !textNode.prevNode) {
75
+ return;
76
+ }
77
+ if (textNode.rule.options.prevElement === false && textNode.prevNode?.is(textNode.ELEMENT_NODE)) {
78
+ return;
79
+ }
80
+ if (textNode.rule.options.prevComment === false && textNode.prevNode?.is(textNode.COMMENT_NODE)) {
81
+ return;
82
+ }
83
+ if (textNode.rule.options.prevCodeBlock === false &&
84
+ textNode.prevNode?.is(textNode.MARKUPLINT_PREPROCESSOR_BLOCK)) {
85
+ return;
86
+ }
67
87
  const bullets = textNode.rule.value;
68
88
  const spaceNeededBullets = textNode.rule.options.spaceNeededBullets ?? [];
69
89
  if (isMayListItem(text, bullets, spaceNeededBullets)) {
@@ -75,7 +75,7 @@ export const checkingRequiredOwnedElements = ({ el, role }) => t => {
75
75
  if (mayBeBeforeCreated(el)) {
76
76
  return {
77
77
  scope: el,
78
- message: t('{0}. Or, {1}', t('require {0}', role.requiredOwnedElements.length === 1 && role.requiredOwnedElements[0]
78
+ message: t('{0}. Or, {1}', t('{0} requires {1}', t('the {0}', 'child element'), role.requiredOwnedElements.length === 1 && role.requiredOwnedElements[0]
79
79
  ? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
80
80
  : t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`), t('require {0}', 'aria-busy="true"')),
81
81
  };
@@ -49,7 +49,7 @@ export function checkAriaValue(type, value, tokenEnum, booleanish) {
49
49
  return tokenEnum.includes(value);
50
50
  }
51
51
  case 'token list': {
52
- const list = value.split(/\s+/g).map(s => s.trim());
52
+ const list = value.split(/\s+/).map(s => s.trim());
53
53
  return list.every(token => tokenEnum.includes(token));
54
54
  }
55
55
  case 'string':
@@ -16,6 +16,9 @@ import { checkingRequiredOwnedElements } from './checkings/required-owned-elemen
16
16
  import { checkingRequiredProp } from './checkings/required-prop.js';
17
17
  import { checkingValue } from './checkings/value.js';
18
18
  export default createRule({
19
+ meta: {
20
+ category: 'a11y',
21
+ },
19
22
  defaultOptions: {
20
23
  checkingValue: true,
21
24
  checkingDeprecatedProps: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/rules",
3
- "version": "4.0.0-dev.28+0131de5e",
3
+ "version": "4.0.0-rc.0",
4
4
  "description": "Built-in rules of markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -25,18 +25,18 @@
25
25
  "./lib/permitted-contents/debug.js": "./lib/permitted-contents/debug.browser.js"
26
26
  },
27
27
  "dependencies": {
28
- "@markuplint/html-spec": "4.0.0-dev.28+0131de5e",
29
- "@markuplint/ml-core": "4.0.0-dev.28+0131de5e",
30
- "@markuplint/ml-spec": "4.0.0-dev.28+0131de5e",
31
- "@markuplint/selector": "4.0.0-dev.28+0131de5e",
32
- "@markuplint/shared": "4.0.0-dev.28+0131de5e",
33
- "@markuplint/types": "4.0.0-dev.28+0131de5e",
34
- "@types/debug": "^4.1.10",
28
+ "@markuplint/html-spec": "4.0.0-rc.0",
29
+ "@markuplint/ml-core": "4.0.0-rc.0",
30
+ "@markuplint/ml-spec": "4.0.0-rc.0",
31
+ "@markuplint/selector": "4.0.0-rc.0",
32
+ "@markuplint/shared": "4.0.0-rc.0",
33
+ "@markuplint/types": "4.0.0-rc.0",
34
+ "@types/debug": "^4.1.12",
35
35
  "@ungap/structured-clone": "^1.2.0",
36
36
  "ansi-colors": "^4.1.3",
37
- "chrono-node": "^2.7.0",
37
+ "chrono-node": "^2.7.5",
38
38
  "debug": "^4.3.4",
39
- "type-fest": "^4.5.0"
39
+ "type-fest": "^4.10.2"
40
40
  },
41
- "gitHead": "0131de5ea9dd6d3fd5472d7b414b66644c758881"
41
+ "gitHead": "3fdeb45cb69ed52b3a215a7520cea1181601443f"
42
42
  }