@markuplint/ml-spec 3.0.0-canary.5 → 3.0.0-dev.176

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +1 -1
  2. package/lib/constant/aria-version.d.ts +2 -0
  3. package/lib/constant/aria-version.js +5 -0
  4. package/lib/dom-traverse/accname-computation.js +3 -1
  5. package/lib/dom-traverse/get-attr-specs.d.ts +1 -1
  6. package/lib/dom-traverse/get-attr-specs.js +3 -1
  7. package/lib/dom-traverse/get-computed-aria-props.d.ts +6 -6
  8. package/lib/dom-traverse/get-computed-aria-props.js +4 -2
  9. package/lib/dom-traverse/get-computed-role.d.ts +6 -1
  10. package/lib/dom-traverse/get-computed-role.js +41 -10
  11. package/lib/dom-traverse/get-content-model.d.ts +28 -2
  12. package/lib/dom-traverse/get-content-model.js +4 -2
  13. package/lib/dom-traverse/get-explicit-role.js +9 -4
  14. package/lib/dom-traverse/get-implicit-role.d.ts +6 -2
  15. package/lib/dom-traverse/get-implicit-role.js +6 -2
  16. package/lib/dom-traverse/get-non-presentational-ancestor.d.ts +10 -4
  17. package/lib/dom-traverse/get-non-presentational-ancestor.js +10 -2
  18. package/lib/dom-traverse/get-permitted-roles.d.ts +7 -3
  19. package/lib/dom-traverse/get-permitted-roles.js +3 -1
  20. package/lib/dom-traverse/get-spec.d.ts +4 -1
  21. package/lib/dom-traverse/get-spec.js +3 -1
  22. package/lib/dom-traverse/has-required-owned-elements.d.ts +8 -2
  23. package/lib/dom-traverse/has-required-owned-elements.js +14 -8
  24. package/lib/dom-traverse/is-exposed.d.ts +1 -1
  25. package/lib/dom-traverse/is-exposed.js +43 -7
  26. package/lib/dom-traverse/matches-context-role.d.ts +7 -0
  27. package/lib/dom-traverse/matches-context-role.js +27 -0
  28. package/lib/dom-traverse/may-be-focusable.d.ts +1 -1
  29. package/lib/dom-traverse/may-be-focusable.js +3 -1
  30. package/lib/index.d.ts +4 -0
  31. package/lib/index.js +4 -0
  32. package/lib/specs/aria-specs.d.ts +7 -4
  33. package/lib/specs/content-model-category-to-tag-names.d.ts +4 -1
  34. package/lib/specs/get-aria.d.ts +8 -1
  35. package/lib/specs/get-aria.js +8 -2
  36. package/lib/specs/get-attr-specs.d.ts +6 -2
  37. package/lib/specs/get-attr-specs.js +2 -14
  38. package/lib/specs/get-implicit-role.d.ts +7 -1
  39. package/lib/specs/get-permitted-roles.d.ts +9 -3
  40. package/lib/specs/get-permitted-roles.js +19 -15
  41. package/lib/specs/get-role-spec.d.ts +10 -3
  42. package/lib/specs/get-role-spec.js +2 -2
  43. package/lib/specs/get-selectors-by-content-model-category.d.ts +1 -1
  44. package/lib/specs/get-selectors-by-content-model-category.js +1 -1
  45. package/lib/specs/get-spec-by-tag-name.d.ts +5 -1
  46. package/lib/specs/get-spec-by-tag-name.js +3 -2
  47. package/lib/specs/is-nothing-content-model.d.ts +5 -0
  48. package/lib/specs/is-nothing-content-model.js +14 -0
  49. package/lib/specs/is-palpable-elements.d.ts +8 -4
  50. package/lib/specs/is-palpable-elements.js +6 -4
  51. package/lib/specs/is-void-element.js +3 -1
  52. package/lib/specs/resolve-version.d.ts +5 -1
  53. package/lib/specs/resolve-version.js +1 -1
  54. package/lib/specs/schema-to-spec.d.ts +4 -4
  55. package/lib/specs/schema-to-spec.js +29 -18
  56. package/lib/types/aria.d.ts +149 -114
  57. package/lib/types/attributes.d.ts +1490 -111
  58. package/lib/types/index.d.ts +178 -149
  59. package/lib/types/permitted-structures.d.ts +74 -31
  60. package/lib/utils/merge-array.d.ts +9 -4
  61. package/lib/utils/resolve-namespace.d.ts +4 -4
  62. package/lib/utils/resolve-namespace.js +3 -2
  63. package/lib/utils/validateAriaVersion.d.ts +2 -0
  64. package/lib/utils/validateAriaVersion.js +8 -0
  65. package/package.json +13 -8
  66. package/{src/dom-traverse/accname-computation.spec.ts → test/dom-traverse/accname-computation.spec.js} +4 -4
  67. package/test/dom-traverse/get-computed-aria-props.spec.js +758 -0
  68. package/test/dom-traverse/get-computed-role.spec.js +294 -0
  69. package/test/dom-traverse/get-implicit-role.spec.js +40 -0
  70. package/{src/dom-traverse/has-required-owned-elements.spec.ts → test/dom-traverse/has-required-owned-elements.spec.js} +7 -9
  71. package/{src/dom-traverse/is-exposed.spec.ts → test/dom-traverse/is-exposed.spec.js} +29 -9
  72. package/test/dom-traverse/matches-context-role.spec.js +60 -0
  73. package/{src/specs/get-attr-specs.spec.ts → test/specs/get-attr-specs.spec.js} +2 -8
  74. package/{src/specs/get-implicit-role.spec.ts → test/specs/get-implicit-role.spec.js} +9 -11
  75. package/{src/specs/get-permitted-roles.spec.ts → test/specs/get-permitted-roles.spec.js} +8 -10
  76. package/{src/specs/get-role-spec.spec.ts → test/specs/get-role-spec.spec.js} +4 -4
  77. package/{src/specs/get-spec-by-tag-name.spec.ts → test/specs/get-spec-by-tag-name.spec.js} +2 -2
  78. package/test/specs/resolve-version.spec.js +34 -0
  79. package/test/specs/schema-to-spec.spec.js +61 -0
  80. package/{src/utils/resolve-namespace.spec.ts → test/utils/resolve-namespace.spec.js} +1 -1
  81. package/lib/types/permitted-structres.d.ts +0 -58
  82. package/lib/types/permitted-structres.js +0 -8
  83. package/schemas/aria.schema.json +0 -258
  84. package/schemas/attributes.schema.json +0 -204
  85. package/schemas/content-models.schema.json +0 -199
  86. package/schemas/element.schema.json +0 -11
  87. package/schemas/global-attributes.schema.json +0 -761
  88. package/src/dom-traverse/accname-computation.ts +0 -5
  89. package/src/dom-traverse/get-attr-specs.ts +0 -8
  90. package/src/dom-traverse/get-computed-aria-props.spec.ts +0 -368
  91. package/src/dom-traverse/get-computed-aria-props.ts +0 -130
  92. package/src/dom-traverse/get-computed-role.spec.ts +0 -134
  93. package/src/dom-traverse/get-computed-role.ts +0 -181
  94. package/src/dom-traverse/get-content-model.ts +0 -32
  95. package/src/dom-traverse/get-explicit-role.ts +0 -112
  96. package/src/dom-traverse/get-implicit-role.ts +0 -36
  97. package/src/dom-traverse/get-non-presentational-ancestor.ts +0 -20
  98. package/src/dom-traverse/get-permitted-roles.ts +0 -7
  99. package/src/dom-traverse/get-spec.ts +0 -7
  100. package/src/dom-traverse/has-required-owned-elements.ts +0 -85
  101. package/src/dom-traverse/is-exposed.ts +0 -196
  102. package/src/dom-traverse/may-be-focusable.ts +0 -21
  103. package/src/index.ts +0 -23
  104. package/src/specs/aria-specs.ts +0 -6
  105. package/src/specs/content-model-category-to-tag-names.ts +0 -15
  106. package/src/specs/get-aria.ts +0 -85
  107. package/src/specs/get-attr-specs.ts +0 -116
  108. package/src/specs/get-implicit-role.ts +0 -17
  109. package/src/specs/get-permitted-roles.ts +0 -87
  110. package/src/specs/get-role-spec.ts +0 -72
  111. package/src/specs/get-selectors-by-content-model-category.ts +0 -10
  112. package/src/specs/get-spec-by-tag-name.ts +0 -20
  113. package/src/specs/is-palpable-elements.ts +0 -55
  114. package/src/specs/is-presentational.ts +0 -6
  115. package/src/specs/is-void-element.ts +0 -22
  116. package/src/specs/resolve-version.ts +0 -20
  117. package/src/specs/schema-to-spec.spec.ts +0 -39
  118. package/src/specs/schema-to-spec.ts +0 -103
  119. package/src/types/aria.ts +0 -153
  120. package/src/types/attributes.ts +0 -1473
  121. package/src/types/index.ts +0 -255
  122. package/src/types/permitted-structres.ts +0 -100
  123. package/src/types/permitted-structures.ts +0 -96
  124. package/src/utils/get-ns.ts +0 -18
  125. package/src/utils/merge-array.ts +0 -35
  126. package/src/utils/resolve-namespace.ts +0 -40
  127. package/tsconfig.test.json +0 -3
  128. package/tsconfig.tsbuildinfo +0 -1
@@ -1,21 +0,0 @@
1
- import type { MLMLSpec } from '../types';
2
-
3
- import { getSelectorsByContentModelCategory } from '../specs/get-selectors-by-content-model-category';
4
-
5
- export function mayBeFocusable(el: Element, specs: Readonly<MLMLSpec>): boolean {
6
- return [
7
- /**
8
- * Interactive content
9
- *
10
- * @see https://html.spec.whatwg.org/multipage/dom.html#interactive-content
11
- */
12
- ...getSelectorsByContentModelCategory(specs, '#interactive'),
13
- /**
14
- * Interaction
15
- *
16
- * @see https://html.spec.whatwg.org/multipage/interaction.html
17
- */
18
- '[tabindex]',
19
- '[contenteditable]:not([contenteditable="false" i])',
20
- ].some(selector => el.matches(selector));
21
- }
package/src/index.ts DELETED
@@ -1,23 +0,0 @@
1
- export * from './dom-traverse/accname-computation';
2
- export * from './dom-traverse/get-attr-specs';
3
- export * from './dom-traverse/get-computed-aria-props';
4
- export * from './dom-traverse/get-computed-role';
5
- export * from './dom-traverse/get-content-model';
6
- export * from './dom-traverse/get-implicit-role';
7
- export * from './dom-traverse/get-permitted-roles';
8
- export * from './dom-traverse/get-spec';
9
- export * from './dom-traverse/has-required-owned-elements';
10
- export * from './dom-traverse/is-exposed';
11
- export * from './dom-traverse/may-be-focusable';
12
- export * from './specs/aria-specs';
13
- export * from './specs/content-model-category-to-tag-names';
14
- export * from './specs/get-role-spec';
15
- export * from './specs/get-spec-by-tag-name';
16
- export * from './specs/is-palpable-elements';
17
- export * from './specs/is-void-element';
18
- export * from './specs/schema-to-spec';
19
- export * from './types';
20
- export * from './types/aria';
21
- export * from './types/attributes';
22
- export * from './types/permitted-structures';
23
- export * from './utils/resolve-namespace';
@@ -1,6 +0,0 @@
1
- import type { ARIAVersion, MLMLSpec } from '../types';
2
-
3
- export function ariaSpecs(specs: Readonly<MLMLSpec>, version: ARIAVersion) {
4
- const aria = specs.def['#aria'];
5
- return aria[version];
6
- }
@@ -1,15 +0,0 @@
1
- import type { MLMLSpec } from '../types';
2
- import type { Category } from '../types/permitted-structures';
3
-
4
- const cache = new Map<Category, ReadonlyArray<string>>();
5
-
6
- export function contentModelCategoryToTagNames(contentModel: Category, def: MLMLSpec['def']): ReadonlyArray<string> {
7
- const cached = cache.get(contentModel);
8
- if (cached) {
9
- return cached;
10
- }
11
- const tags: string[] | undefined = def['#contentModels'][contentModel];
12
- const sortedTag = Object.freeze(tags && Array.isArray(tags) ? tags.sort() : []);
13
- cache.set(contentModel, sortedTag);
14
- return sortedTag;
15
- }
@@ -1,85 +0,0 @@
1
- import type { ARIAVersion, Matches, MLMLSpec } from '../types';
2
- import type { ARIA, PermittedRoles } from '../types/aria';
3
-
4
- import { getSpecByTagName } from './get-spec-by-tag-name';
5
- import { resolveVersion } from './resolve-version';
6
-
7
- const cache = new Map<string, Omit<ARIA, ARIAVersion> | null>();
8
-
9
- export function getARIA(
10
- specs: Readonly<MLMLSpec>,
11
- localName: string,
12
- namespace: string | null,
13
- version: ARIAVersion,
14
- matches: Matches,
15
- ): Omit<ARIA, ARIAVersion | 'conditions'> | null {
16
- const aria = getVersionResolvedARIA(specs, localName, namespace, version);
17
- if (!aria) {
18
- return null;
19
- }
20
- const conditions = aria.conditions;
21
- if (!conditions) {
22
- return aria;
23
- }
24
- const conditionKeys = Object.keys(conditions);
25
- let { implicitRole, permittedRoles, implicitProperties, properties, namingProhibited } = aria;
26
- for (const cond of conditionKeys) {
27
- if (!matches(cond)) {
28
- continue;
29
- }
30
- const condARIA = conditions[cond];
31
- implicitRole = condARIA.implicitRole ?? implicitRole;
32
- permittedRoles = condARIA.permittedRoles ?? permittedRoles;
33
- implicitProperties = condARIA.implicitProperties ?? implicitProperties;
34
- properties = condARIA.properties ?? properties;
35
- namingProhibited = condARIA.namingProhibited ?? namingProhibited;
36
- }
37
- return {
38
- implicitRole,
39
- permittedRoles,
40
- implicitProperties,
41
- properties,
42
- namingProhibited,
43
- };
44
- }
45
-
46
- function getVersionResolvedARIA(
47
- specs: Readonly<MLMLSpec>,
48
- localName: string,
49
- namespace: string | null,
50
- version: ARIAVersion,
51
- ) {
52
- const key = localName + namespace + version;
53
- let aria = cache.get(key);
54
- if (aria !== undefined) {
55
- return aria;
56
- }
57
- const spec = getSpecByTagName(specs.specs, localName, namespace)?.aria;
58
- if (!spec) {
59
- cache.set(key, null);
60
- return null;
61
- }
62
- aria = resolveVersion(spec, version);
63
- if (aria.permittedRoles) {
64
- aria.permittedRoles = optimizePermittedRoles(aria.permittedRoles);
65
- }
66
- cache.set(key, aria);
67
- return aria;
68
- }
69
-
70
- function optimizePermittedRoles(permittedRoles: PermittedRoles) {
71
- if (!Array.isArray(permittedRoles)) {
72
- return permittedRoles;
73
- }
74
- const unique = new Set(permittedRoles);
75
-
76
- // https://www.w3.org/TR/wai-aria-1.2/#note-regarding-the-aria-1-1-none-role
77
- if (unique.has('presentation')) {
78
- unique.add('none');
79
- }
80
- if (unique.has('none')) {
81
- unique.add('presentation');
82
- }
83
-
84
- return Array.from(unique).sort();
85
- }
@@ -1,116 +0,0 @@
1
- import type { MLMLSpec, Attribute } from '../types';
2
- import type { NamespaceURI } from '@markuplint/ml-ast';
3
-
4
- import { resolveNamespace } from '../utils/resolve-namespace';
5
-
6
- const cacheMap = new Map<string, Attribute[] | null>();
7
- const schemaCache = new WeakSet<MLMLSpec>();
8
-
9
- export function getAttrSpecs(localName: string, namespace: NamespaceURI | null, schema: MLMLSpec) {
10
- if (!schemaCache.has(schema)) {
11
- cacheMap.clear();
12
- }
13
-
14
- const { localNameWithNS } = resolveNamespace(localName, namespace || undefined);
15
-
16
- const cache = cacheMap.get(localNameWithNS);
17
-
18
- if (cache !== undefined) {
19
- return cache;
20
- }
21
-
22
- schemaCache.add(schema);
23
-
24
- const elSpec = schema.specs.find(spec => spec.name === localNameWithNS);
25
- if (!elSpec) {
26
- cacheMap.set(localNameWithNS, null);
27
- return null;
28
- }
29
-
30
- const globalAttrs = schema.def['#globalAttrs'];
31
- let attrs: Record<string, Partial<Attribute>> = {};
32
-
33
- for (const catName in elSpec.globalAttrs) {
34
- // @ts-ignore
35
- const catAttrs: boolean | string[] = elSpec.globalAttrs[catName];
36
- if (!catAttrs) {
37
- continue;
38
- }
39
- if (typeof catAttrs === 'boolean') {
40
- const global = globalAttrs[catName];
41
- attrs = {
42
- ...attrs,
43
- ...global,
44
- };
45
- continue;
46
- }
47
- if (Array.isArray(catAttrs)) {
48
- const global = globalAttrs[catName];
49
- if (!global) {
50
- continue;
51
- }
52
- catAttrs.forEach(selectedName => {
53
- const selected = global[selectedName];
54
- attrs[selectedName] = {
55
- ...attrs[selectedName],
56
- ...selected,
57
- };
58
- });
59
- continue;
60
- }
61
- }
62
-
63
- for (const attrName in elSpec.attributes) {
64
- const attr = elSpec.attributes[attrName];
65
- if (!attr) {
66
- continue;
67
- }
68
-
69
- const current = attrs[attrName] as Omit<Attribute, 'name'> | undefined;
70
-
71
- attrs[attrName] = {
72
- description: '',
73
- ...current,
74
- ...attr,
75
- };
76
- }
77
-
78
- const attrList: Attribute[] = Object.keys(attrs).map<Attribute>(name => {
79
- const attr = attrs[name];
80
- return { name, type: 'Any', ...attr };
81
- });
82
-
83
- for (const attr of attrList) {
84
- if (!attr.type) {
85
- throw new Error(
86
- `The type is empty in the ${attr.name} attribute of the ${localName} element,
87
- 'packages',
88
- '@markuplint',
89
- 'html-spec',
90
- 'src',
91
- 'attributes',
92
- nameWithNS.replace(':', '_') + '.json',
93
- )})`,
94
- );
95
- }
96
- }
97
-
98
- attrList.sort(nameCompare);
99
-
100
- cacheMap.set(localNameWithNS, attrList);
101
- return attrList;
102
- }
103
-
104
- type HasName = { name: string };
105
-
106
- export function nameCompare(a: HasName | string, b: HasName | string) {
107
- const nameA = typeof a === 'string' ? a : a.name.toUpperCase();
108
- const nameB = typeof b === 'string' ? b : b.name.toUpperCase();
109
- if (nameA < nameB) {
110
- return -1;
111
- }
112
- if (nameA > nameB) {
113
- return 1;
114
- }
115
- return 0;
116
- }
@@ -1,17 +0,0 @@
1
- import type { ARIAVersion, Matches, MLMLSpec } from '../types';
2
-
3
- import { getARIA } from './get-aria';
4
-
5
- export function getImplicitRole(
6
- specs: Readonly<MLMLSpec>,
7
- localName: string,
8
- namespace: string | null,
9
- version: ARIAVersion,
10
- matches: Matches,
11
- ) {
12
- const aria = getARIA(specs, localName, namespace, version, matches);
13
- if (!aria) {
14
- return false;
15
- }
16
- return aria.implicitRole;
17
- }
@@ -1,87 +0,0 @@
1
- import type { ARIAVersion, Matches, MLMLSpec } from '../types';
2
-
3
- import { mergeArray } from '../utils/merge-array';
4
-
5
- import { ariaSpecs } from './aria-specs';
6
- import { getARIA } from './get-aria';
7
-
8
- /**
9
- * Getting permitted ARIA roles.
10
- *
11
- * - If an array, it is role list.
12
- * - If `true`, this mean is "Any".
13
- * - If `false`, this mean is "No".
14
- */
15
- export function getPermittedRoles(
16
- specs: Readonly<MLMLSpec>,
17
- localName: string,
18
- namespace: string | null,
19
- version: ARIAVersion,
20
- matches: Matches,
21
- ): { name: string; deprecated?: boolean }[] {
22
- const aria = getARIA(specs, localName, namespace, version, matches);
23
- if (!aria) {
24
- return [];
25
- }
26
- const { implicitRole, permittedRoles } = aria;
27
- const { roles, graphicsRoles } = ariaSpecs(specs, version);
28
-
29
- let permittedRoleList: { name: string }[] = [];
30
-
31
- if (permittedRoles === true) {
32
- permittedRoleList = mergeArray(
33
- permittedRoleList,
34
- roles
35
- .filter(role => !role.isAbstract)
36
- .map(role => ({
37
- name: role.name,
38
- })),
39
- );
40
- }
41
-
42
- if (Array.isArray(permittedRoles)) {
43
- permittedRoleList = mergeArray(
44
- permittedRoleList,
45
- permittedRoles.map(role => {
46
- if (typeof role === 'string') {
47
- return {
48
- name: role,
49
- };
50
- }
51
- return role;
52
- }),
53
- );
54
- } else if (!(typeof permittedRoles === 'boolean')) {
55
- if (permittedRoles['core-aam']) {
56
- permittedRoleList = mergeArray(
57
- permittedRoleList,
58
- roles
59
- .filter(role => !role.isAbstract)
60
- .map(role => ({
61
- name: role.name,
62
- })),
63
- );
64
- }
65
- if (permittedRoles['graphics-aam']) {
66
- permittedRoleList = mergeArray(
67
- permittedRoleList,
68
- graphicsRoles
69
- .filter(role => !role.isAbstract)
70
- .map(role => ({
71
- name: role.name,
72
- })),
73
- );
74
- }
75
- }
76
-
77
- if (implicitRole) {
78
- const implicitRoles =
79
- implicitRole === 'presentation' || implicitRole === 'none' ? ['none', 'presentation'] : [implicitRole];
80
- return mergeArray(
81
- implicitRoles.map(r => ({ name: r })),
82
- permittedRoleList,
83
- );
84
- }
85
-
86
- return permittedRoleList;
87
- }
@@ -1,72 +0,0 @@
1
- import type { ARIAVersion, ARIARoleInSchema, MLMLSpec, ARIARole } from '../types';
2
- import type { NamespaceURI } from '@markuplint/ml-ast';
3
-
4
- import { ariaSpecs } from './aria-specs';
5
-
6
- export function getRoleSpec(
7
- specs: Readonly<MLMLSpec>,
8
- roleName: string,
9
- namespace: NamespaceURI,
10
- version: ARIAVersion,
11
- ): (ARIARole & { superClassRoles: ARIARoleInSchema[] }) | null {
12
- const role = getRoleByName(specs, roleName, namespace, version);
13
- if (!role) {
14
- return null;
15
- }
16
- const superClassRoles = recursiveTraverseSuperClassRoles(specs, roleName, namespace, version);
17
- return {
18
- name: role.name,
19
- isAbstract: !!role.isAbstract,
20
- requiredContextRole: role.requiredContextRole ?? [],
21
- requiredOwnedElements: role.requiredOwnedElements ?? [],
22
- accessibleNameRequired: !!role.accessibleNameRequired,
23
- accessibleNameFromAuthor: !!role.accessibleNameFromAuthor,
24
- accessibleNameFromContent: !!role.accessibleNameFromContent,
25
- accessibleNameProhibited: !!role.accessibleNameProhibited,
26
- childrenPresentational: !!role.childrenPresentational,
27
- ownedProperties: role.ownedProperties ?? [],
28
- prohibitedProperties: role.prohibitedProperties ?? [],
29
- superClassRoles,
30
- };
31
- }
32
-
33
- function recursiveTraverseSuperClassRoles(
34
- specs: Readonly<MLMLSpec>,
35
- roleName: string,
36
- namespace: NamespaceURI,
37
- version: ARIAVersion,
38
- ) {
39
- const roles: ARIARoleInSchema[] = [];
40
- const superClassRoles = getSuperClassRoles(specs, roleName, namespace, version);
41
- if (superClassRoles) {
42
- roles.push(...superClassRoles);
43
- for (const superClassRole of superClassRoles) {
44
- const ancestorRoles = recursiveTraverseSuperClassRoles(specs, superClassRole.name, namespace, version);
45
- roles.push(...ancestorRoles);
46
- }
47
- }
48
- return roles;
49
- }
50
-
51
- function getSuperClassRoles(
52
- specs: Readonly<MLMLSpec>,
53
- roleName: string,
54
- namespace: NamespaceURI,
55
- version: ARIAVersion,
56
- ) {
57
- const role = getRoleByName(specs, roleName, namespace, version);
58
- return (
59
- role?.generalization
60
- ?.map(roleName => getRoleByName(specs, roleName, namespace, version))
61
- .filter((role): role is ARIARoleInSchema => !!role) || null
62
- );
63
- }
64
-
65
- function getRoleByName(specs: Readonly<MLMLSpec>, roleName: string, namespace: NamespaceURI, version: ARIAVersion) {
66
- const { roles, graphicsRoles } = ariaSpecs(specs, version);
67
- let role = roles.find(r => r.name === roleName);
68
- if (!role && namespace === 'http://www.w3.org/2000/svg') {
69
- role = graphicsRoles.find(r => r.name === roleName);
70
- }
71
- return role;
72
- }
@@ -1,10 +0,0 @@
1
- import type { MLMLSpec } from '../types';
2
- import type { Category } from '../types/permitted-structures';
3
-
4
- export function getSelectorsByContentModelCategory(
5
- specs: Readonly<MLMLSpec>,
6
- category: Category,
7
- ): ReadonlyArray<string> {
8
- const selectors = specs.def['#contentModels'][category];
9
- return selectors || [];
10
- }
@@ -1,20 +0,0 @@
1
- import type { ElementSpec } from '../types';
2
-
3
- import { resolveNamespace } from '../utils/resolve-namespace';
4
-
5
- const cache = new Map<string, any>();
6
-
7
- export function getSpecByTagName<K extends keyof ElementSpec = keyof ElementSpec>(
8
- specs: Readonly<Pick<ElementSpec, 'name' | K>[]>,
9
- localName: string,
10
- namespace: string | null,
11
- ) {
12
- const { localNameWithNS } = resolveNamespace(localName, namespace || undefined);
13
- let spec: Pick<ElementSpec, 'name' | K> | null | undefined = cache.get(localNameWithNS);
14
- if (spec !== undefined) {
15
- return spec;
16
- }
17
- spec = specs.find(spec => spec.name === localNameWithNS) || null;
18
- cache.set(localNameWithNS, spec);
19
- return spec;
20
- }
@@ -1,55 +0,0 @@
1
- import type { MLMLSpec } from '../types';
2
-
3
- /**
4
- * Exposable content models and elements
5
- *
6
- * **WARNING**:
7
- * This implementation is through the author's interpretation.
8
- * Want a issue request.
9
- * https://github.com/markuplint/markuplint/issues/new
10
- *
11
- * @see https://html.spec.whatwg.org/multipage/indices.html#elements-3
12
- */
13
- const exposableElementsThatAreNoBelongingAModel: string[] = [
14
- 'body',
15
- 'dd',
16
- 'dt',
17
- 'figcaption',
18
- 'html',
19
- 'legend',
20
- 'li',
21
- 'optgroup',
22
- 'option',
23
- 'rp',
24
- 'rt',
25
- 'summary',
26
- 'tbody',
27
- 'td',
28
- 'tfoot',
29
- 'th',
30
- 'thead',
31
- 'tr',
32
- ];
33
-
34
- export function isPalpableElement(
35
- el: Element,
36
- specs: Readonly<MLMLSpec>,
37
- options?: {
38
- extendsSvg?: boolean;
39
- extendsExposableElements?: boolean;
40
- },
41
- ) {
42
- const conditions = [specs.def['#contentModels']['#palpable']?.join(',') || ''];
43
-
44
- if (options?.extendsSvg !== false /* default true */) {
45
- conditions.push(specs.def['#contentModels']['#SVGRenderable']?.join(',') || '');
46
- }
47
-
48
- if (options?.extendsExposableElements /* default false */) {
49
- conditions.push(exposableElementsThatAreNoBelongingAModel.join(','));
50
- }
51
-
52
- return conditions.some(condition => {
53
- return el.matches(condition);
54
- });
55
- }
@@ -1,6 +0,0 @@
1
- export function isPresentational(roleName?: string) {
2
- if (!roleName) {
3
- return false;
4
- }
5
- return ['presentation', 'none'].includes(roleName);
6
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * @see https://html.spec.whatwg.org/multipage/syntax.html#void-elements
3
- */
4
- const voidElements = [
5
- 'area',
6
- 'base',
7
- 'br',
8
- 'col',
9
- 'embed',
10
- 'hr',
11
- 'img',
12
- 'input',
13
- 'link',
14
- 'meta',
15
- 'source',
16
- 'track',
17
- 'wbr',
18
- ];
19
-
20
- export function isVoidElement(el: Element) {
21
- return voidElements.includes(el.localName);
22
- }
@@ -1,20 +0,0 @@
1
- import type { ARIAVersion } from '../types';
2
- import type { ARIA } from '../types/aria';
3
-
4
- export function resolveVersion(aria: ARIA, version: ARIAVersion): Omit<ARIA, ARIAVersion> {
5
- const implicitRole = aria[version]?.implicitRole ?? aria.implicitRole;
6
- const permittedRoles = aria[version]?.permittedRoles ?? aria.permittedRoles;
7
- const implicitProperties = aria[version]?.implicitProperties ?? aria.implicitProperties;
8
- const properties = aria[version]?.properties ?? aria.properties;
9
- const namingProhibited =
10
- version === '1.2' ? aria[version]?.namingProhibited ?? aria.namingProhibited : aria.namingProhibited;
11
- const conditions = aria[version]?.conditions ?? aria.conditions;
12
- return {
13
- implicitRole,
14
- permittedRoles,
15
- implicitProperties,
16
- properties,
17
- namingProhibited,
18
- conditions,
19
- };
20
- }
@@ -1,39 +0,0 @@
1
- import htmlSpec from '@markuplint/html-spec';
2
-
3
- import { schemaToSpec } from './schema-to-spec';
4
-
5
- describe('getSpec', () => {
6
- test('Overriding', () => {
7
- const exAttr = {
8
- ref: 'N/A',
9
- type: 'Boolean',
10
- description: 'For the unit test.',
11
- } as const;
12
- const exAttr2 = {
13
- ref: 'N/A',
14
- type: 'Boolean',
15
- description: 'For the unit test. Override.',
16
- } as const;
17
- const mergedSpec = schemaToSpec([
18
- htmlSpec,
19
- {
20
- specs: [
21
- {
22
- name: 'a',
23
- attributes: { 'extended-attr': exAttr },
24
- },
25
- ],
26
- },
27
- {
28
- specs: [
29
- {
30
- name: 'a',
31
- attributes: { 'extended-attr': exAttr2 },
32
- },
33
- ],
34
- },
35
- ]);
36
- const aElAttrs = mergedSpec.specs.find(el => el.name === 'a')!.attributes;
37
- expect(aElAttrs['extended-attr']).toStrictEqual(exAttr2);
38
- });
39
- });