@markuplint/ml-spec 2.1.1 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/lib/dom-traverse/accname-computation.d.ts +1 -0
  2. package/lib/dom-traverse/accname-computation.js +8 -0
  3. package/lib/dom-traverse/get-attr-specs.d.ts +2 -0
  4. package/lib/dom-traverse/get-attr-specs.js +8 -0
  5. package/lib/dom-traverse/get-computed-role.d.ts +2 -0
  6. package/lib/dom-traverse/get-computed-role.js +170 -0
  7. package/lib/dom-traverse/get-content-model.d.ts +3 -0
  8. package/lib/dom-traverse/get-content-model.js +28 -0
  9. package/lib/dom-traverse/get-explicit-role.d.ts +2 -0
  10. package/lib/dom-traverse/get-explicit-role.js +102 -0
  11. package/lib/dom-traverse/get-implicit-role.d.ts +3 -0
  12. package/lib/dom-traverse/get-implicit-role.js +37 -0
  13. package/lib/dom-traverse/get-non-presentational-ancestor.d.ts +5 -0
  14. package/lib/dom-traverse/get-non-presentational-ancestor.js +21 -0
  15. package/lib/dom-traverse/get-permitted-roles.d.ts +5 -0
  16. package/lib/dom-traverse/get-permitted-roles.js +8 -0
  17. package/lib/dom-traverse/get-spec.d.ts +2 -0
  18. package/lib/dom-traverse/get-spec.js +8 -0
  19. package/lib/dom-traverse/has-required-owned-elements.d.ts +3 -0
  20. package/lib/dom-traverse/has-required-owned-elements.js +81 -0
  21. package/lib/dom-traverse/may-be-focusable.d.ts +2 -0
  22. package/lib/dom-traverse/may-be-focusable.js +22 -0
  23. package/lib/index.d.ts +18 -6
  24. package/lib/index.js +18 -6
  25. package/lib/specs/aria-specs.d.ts +6 -0
  26. package/lib/specs/aria-specs.js +8 -0
  27. package/lib/specs/content-model-category-to-tag-names.d.ts +3 -0
  28. package/lib/specs/content-model-category-to-tag-names.js +15 -0
  29. package/lib/specs/get-aria.d.ts +3 -0
  30. package/lib/specs/get-aria.js +71 -0
  31. package/lib/specs/get-attr-specs.d.ts +8 -0
  32. package/lib/{get-attr-specs.js → specs/get-attr-specs.js} +8 -6
  33. package/lib/specs/get-implicit-role.d.ts +2 -0
  34. package/lib/specs/get-implicit-role.js +12 -0
  35. package/lib/specs/get-permitted-roles.d.ts +12 -0
  36. package/lib/specs/get-permitted-roles.js +61 -0
  37. package/lib/specs/get-role-spec.d.ts +5 -0
  38. package/lib/specs/get-role-spec.js +52 -0
  39. package/lib/specs/get-selectors-by-content-model-category.d.ts +3 -0
  40. package/lib/specs/get-selectors-by-content-model-category.js +8 -0
  41. package/lib/specs/get-spec-by-tag-name.d.ts +2 -0
  42. package/lib/specs/get-spec-by-tag-name.js +16 -0
  43. package/lib/specs/is-presentational.d.ts +1 -0
  44. package/lib/specs/is-presentational.js +10 -0
  45. package/lib/specs/resolve-version.d.ts +3 -0
  46. package/lib/specs/resolve-version.js +21 -0
  47. package/lib/specs/schema-to-spec.d.ts +13 -0
  48. package/lib/{get-spec.js → specs/schema-to-spec.js} +19 -11
  49. package/lib/types/aria.d.ts +136 -0
  50. package/lib/{attributes.js → types/aria.js} +0 -0
  51. package/lib/{attributes.d.ts → types/attributes.d.ts} +95 -48
  52. package/lib/{permitted-structres.js → types/attributes.js} +0 -0
  53. package/lib/{types.d.ts → types/index.d.ts} +55 -70
  54. package/lib/{types.js → types/index.js} +0 -0
  55. package/lib/types/permitted-structres.d.ts +58 -0
  56. package/lib/types/permitted-structres.js +8 -0
  57. package/lib/types/permitted-structures.d.ts +54 -0
  58. package/lib/types/permitted-structures.js +8 -0
  59. package/lib/utils/get-ns.d.ts +2 -0
  60. package/lib/{get-ns.js → utils/get-ns.js} +3 -0
  61. package/lib/{utils.d.ts → utils/merge-array.d.ts} +0 -0
  62. package/lib/{utils.js → utils/merge-array.js} +0 -0
  63. package/lib/utils/resolve-namespace.d.ts +9 -0
  64. package/lib/utils/resolve-namespace.js +31 -0
  65. package/package.json +12 -8
  66. package/schema.json +6 -6
  67. package/schemas/aria.schema.json +258 -0
  68. package/schemas/attributes.schema.json +3 -22
  69. package/schemas/content-models.schema.json +200 -0
  70. package/schemas/element.schema.json +11 -0
  71. package/src/dom-traverse/accname-computation.spec.ts +69 -0
  72. package/src/dom-traverse/accname-computation.ts +5 -0
  73. package/src/dom-traverse/get-attr-specs.ts +8 -0
  74. package/src/dom-traverse/get-computed-role.spec.ts +134 -0
  75. package/src/dom-traverse/get-computed-role.ts +181 -0
  76. package/src/dom-traverse/get-content-model.ts +32 -0
  77. package/src/dom-traverse/get-explicit-role.ts +112 -0
  78. package/src/dom-traverse/get-implicit-role.ts +36 -0
  79. package/src/dom-traverse/get-non-presentational-ancestor.ts +20 -0
  80. package/src/dom-traverse/get-permitted-roles.ts +7 -0
  81. package/src/dom-traverse/get-spec.ts +7 -0
  82. package/src/dom-traverse/has-required-owned-elements.spec.ts +36 -0
  83. package/src/dom-traverse/has-required-owned-elements.ts +85 -0
  84. package/src/dom-traverse/may-be-focusable.ts +21 -0
  85. package/src/index.ts +18 -6
  86. package/src/specs/aria-specs.ts +6 -0
  87. package/src/specs/content-model-category-to-tag-names.ts +15 -0
  88. package/src/specs/get-aria.ts +85 -0
  89. package/src/{get-attr-specs.spec.ts → specs/get-attr-specs.spec.ts} +4 -7
  90. package/src/{get-attr-specs.ts → specs/get-attr-specs.ts} +12 -7
  91. package/src/specs/get-implicit-role.spec.ts +81 -0
  92. package/src/specs/get-implicit-role.ts +17 -0
  93. package/src/specs/get-permitted-roles.spec.ts +420 -0
  94. package/src/specs/get-permitted-roles.ts +87 -0
  95. package/src/specs/get-role-spec.spec.ts +67 -0
  96. package/src/specs/get-role-spec.ts +72 -0
  97. package/src/specs/get-selectors-by-content-model-category.ts +10 -0
  98. package/src/specs/get-spec-by-tag-name.spec.ts +68 -0
  99. package/src/specs/get-spec-by-tag-name.ts +20 -0
  100. package/src/specs/is-presentational.ts +6 -0
  101. package/src/specs/resolve-version.ts +20 -0
  102. package/src/{get-spec.spec.ts → specs/schema-to-spec.spec.ts} +2 -2
  103. package/src/{get-spec.ts → specs/schema-to-spec.ts} +23 -9
  104. package/src/types/aria.ts +153 -0
  105. package/src/{attributes.ts → types/attributes.ts} +162 -117
  106. package/src/{types.ts → types/index.ts} +75 -74
  107. package/src/types/permitted-structres.ts +101 -0
  108. package/src/types/permitted-structures.ts +97 -0
  109. package/src/{get-ns.ts → utils/get-ns.ts} +6 -1
  110. package/src/{utils.ts → utils/merge-array.ts} +0 -0
  111. package/src/utils/resolve-namespace.spec.ts +37 -0
  112. package/src/utils/resolve-namespace.ts +40 -0
  113. package/tsconfig.tsbuildinfo +1 -1
  114. package/lib/get-attr-specs.d.ts +0 -7
  115. package/lib/get-ns.d.ts +0 -1
  116. package/lib/get-spec-by-tag-name.d.ts +0 -2
  117. package/lib/get-spec-by-tag-name.js +0 -31
  118. package/lib/get-spec.d.ts +0 -13
  119. package/lib/permitted-structres.d.ts +0 -73
  120. package/schemas/permitted-structures.schema.json +0 -244
  121. package/schemas/wai-aria.schema.json +0 -87
  122. package/src/get-spec-by-tag-name.ts +0 -32
  123. package/src/permitted-structres.ts +0 -118
@@ -0,0 +1,68 @@
1
+ import { specs } from '@markuplint/html-spec';
2
+
3
+ import { getSpecByTagName } from './get-spec-by-tag-name';
4
+
5
+ const divSpec = {
6
+ conditional: [
7
+ {
8
+ condition: 'dl > div',
9
+ contents: [
10
+ {
11
+ zeroOrMore: ':model(script-supporting)',
12
+ },
13
+ {
14
+ oneOrMore: 'dt',
15
+ },
16
+ {
17
+ zeroOrMore: ':model(script-supporting)',
18
+ },
19
+ {
20
+ oneOrMore: 'dd',
21
+ },
22
+ {
23
+ zeroOrMore: ':model(script-supporting)',
24
+ },
25
+ ],
26
+ },
27
+ ],
28
+ contents: [
29
+ {
30
+ oneOrMore: ':model(flow)',
31
+ },
32
+ ],
33
+ };
34
+
35
+ test('html:div', () => {
36
+ expect(getSpecByTagName(specs, 'div', null)?.contentModel).toStrictEqual(divSpec);
37
+ expect(getSpecByTagName(specs, 'div', 'unknown-namespace')?.contentModel).toStrictEqual(divSpec);
38
+ expect(getSpecByTagName(specs, 'div', 'http://www.w3.org/1999/xhtml')?.contentModel).toStrictEqual(divSpec);
39
+ });
40
+
41
+ test('svg:svg', () => {
42
+ expect(getSpecByTagName(specs, 'svg', 'http://www.w3.org/2000/svg')?.contentModel).toStrictEqual({
43
+ contents: [
44
+ {
45
+ zeroOrMore: [
46
+ ':model(SVGAnimation)',
47
+ ':model(SVGDescriptive)',
48
+ ':model(SVGPaintServer)',
49
+ ':model(SVGShape)',
50
+ ':model(SVGStructural)',
51
+ 'svg|a',
52
+ 'svg|clipPath',
53
+ 'svg|filter',
54
+ 'svg|foreignObject',
55
+ 'svg|image',
56
+ 'svg|marker',
57
+ 'svg|mask',
58
+ 'svg|script',
59
+ 'svg|style',
60
+ 'svg|switch',
61
+ 'svg|text',
62
+ 'svg|view',
63
+ ],
64
+ },
65
+ ],
66
+ });
67
+ expect(getSpecByTagName(specs, 'svg', null)).toBe(null);
68
+ });
@@ -0,0 +1,20 @@
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
+ }
@@ -0,0 +1,6 @@
1
+ export function isPresentational(roleName?: string) {
2
+ if (!roleName) {
3
+ return false;
4
+ }
5
+ return ['presentation', 'none'].includes(roleName);
6
+ }
@@ -0,0 +1,20 @@
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,6 +1,6 @@
1
1
  import htmlSpec from '@markuplint/html-spec';
2
2
 
3
- import { getSpec } from './get-spec';
3
+ import { schemaToSpec } from './schema-to-spec';
4
4
 
5
5
  describe('getSpec', () => {
6
6
  test('Overriding', () => {
@@ -14,7 +14,7 @@ describe('getSpec', () => {
14
14
  type: 'Boolean',
15
15
  description: 'For the unit test. Override.',
16
16
  } as const;
17
- const mergedSpec = getSpec([
17
+ const mergedSpec = schemaToSpec([
18
18
  htmlSpec,
19
19
  {
20
20
  specs: [
@@ -1,15 +1,15 @@
1
- import type { ElementSpec, ExtendedSpec, MLMLSpec, Attribute } from './types';
1
+ import type { ElementSpec, ExtendedSpec, MLMLSpec, Attribute } from '../types';
2
2
 
3
- import { mergeArray } from './utils';
3
+ import { mergeArray } from '../utils/merge-array';
4
4
 
5
5
  /**
6
6
  * Merging HTML-spec schema and extended spec schemas
7
7
  *
8
- * Ex: `@markuplint/html-spec` + `{ specs: ["@markuplint/vue-spec"] }` in cofigure files.
8
+ * Ex: `@markuplint/html-spec` + `{ specs: ["@markuplint/vue-spec"] }` in configure files.
9
9
  *
10
10
  * @param schemas `MLDocument.schemas`
11
11
  */
12
- export function getSpec(schemas: readonly [MLMLSpec, ...ExtendedSpec[]]) {
12
+ export function schemaToSpec(schemas: readonly [MLMLSpec, ...ExtendedSpec[]]) {
13
13
  const [main, ...extendedSpecs] = schemas;
14
14
  const result = { ...main };
15
15
  for (const extendedSpec of extendedSpecs) {
@@ -17,17 +17,31 @@ export function getSpec(schemas: readonly [MLMLSpec, ...ExtendedSpec[]]) {
17
17
  result.cites = [...result.cites, ...extendedSpec.cites];
18
18
  }
19
19
  if (extendedSpec.def) {
20
- if (extendedSpec.def['#ariaAttrs']) {
21
- result.def['#ariaAttrs'] = [...result.def['#ariaAttrs'], ...extendedSpec.def['#ariaAttrs']];
22
- }
23
20
  if (extendedSpec.def['#globalAttrs']?.['#extends']) {
24
21
  result.def['#globalAttrs']['#HTMLGlobalAttrs'] = {
25
22
  ...(result.def['#globalAttrs']?.['#HTMLGlobalAttrs'] || {}),
26
23
  ...(extendedSpec.def['#globalAttrs']?.['#extends'] || {}),
27
24
  };
28
25
  }
29
- if (extendedSpec.def['#roles']) {
30
- result.def['#roles'] = [...result.def['#roles'], ...extendedSpec.def['#roles']];
26
+ if (extendedSpec.def['#aria']) {
27
+ result.def['#aria'] = {
28
+ '1.1': {
29
+ roles: mergeArray(result.def['#aria']['1.1'].roles, extendedSpec.def['#aria']['1.1'].roles),
30
+ props: mergeArray(result.def['#aria']['1.1'].props, extendedSpec.def['#aria']['1.1'].props),
31
+ graphicsRoles: mergeArray(
32
+ result.def['#aria']['1.1'].graphicsRoles,
33
+ extendedSpec.def['#aria']['1.1'].graphicsRoles,
34
+ ),
35
+ },
36
+ '1.2': {
37
+ roles: mergeArray(result.def['#aria']['1.2'].roles, extendedSpec.def['#aria']['1.2'].roles),
38
+ props: mergeArray(result.def['#aria']['1.2'].props, extendedSpec.def['#aria']['1.2'].props),
39
+ graphicsRoles: mergeArray(
40
+ result.def['#aria']['1.2'].graphicsRoles,
41
+ extendedSpec.def['#aria']['1.2'].graphicsRoles,
42
+ ),
43
+ },
44
+ };
31
45
  }
32
46
  if (extendedSpec.def['#contentModels']) {
33
47
  const keys = new Set([
@@ -0,0 +1,153 @@
1
+ /* tslint:disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ /**
9
+ * If `false`, this mean is "No corresponding role".
10
+ */
11
+ export type ImplicitRole = false | string;
12
+ /**
13
+ * If `true`, this mean is "Any". If `false`, this mean is "No".
14
+ */
15
+ export type PermittedRoles =
16
+ | boolean
17
+ | (
18
+ | string
19
+ | {
20
+ name: string;
21
+ deprecated?: true;
22
+ [k: string]: unknown;
23
+ }
24
+ )[]
25
+ | {
26
+ 'core-aam'?: true;
27
+ 'graphics-aam'?: true;
28
+ };
29
+ /**
30
+ * If set false:
31
+ * > No role or aria-* attributes
32
+ */
33
+ export type PermittedARIAProperties =
34
+ | false
35
+ | {
36
+ global?: true;
37
+ /**
38
+ * Set true if the spec says "and any aria-* attributes applicable to the allowed roles."
39
+ */
40
+ role?: true | string | [string, ...string[]];
41
+ /**
42
+ * @minItems 1
43
+ */
44
+ only?: [
45
+ (
46
+ | string
47
+ | {
48
+ name: string;
49
+ value?: string;
50
+ }
51
+ ),
52
+ ...(
53
+ | string
54
+ | {
55
+ name: string;
56
+ value?: string;
57
+ }
58
+ )[],
59
+ ];
60
+ /**
61
+ * @minItems 1
62
+ */
63
+ without?: [
64
+ {
65
+ type: 'not-recommended' | 'should-not' | 'must-not';
66
+ name: string;
67
+ value?: string;
68
+ alt?: {
69
+ method: 'remove-attr' | 'set-attr';
70
+ target: string;
71
+ };
72
+ },
73
+ ...{
74
+ type: 'not-recommended' | 'should-not' | 'must-not';
75
+ name: string;
76
+ value?: string;
77
+ alt?: {
78
+ method: 'remove-attr' | 'set-attr';
79
+ target: string;
80
+ };
81
+ }[],
82
+ ];
83
+ };
84
+
85
+ export interface AriaSchema {
86
+ _?: ARIA;
87
+ [k: string]: unknown;
88
+ }
89
+ export interface ARIA {
90
+ implicitRole: ImplicitRole;
91
+ permittedRoles: PermittedRoles;
92
+ namingProhibited?: true;
93
+ implicitProperties?: ImplicitProperties;
94
+ properties?: PermittedARIAProperties;
95
+ conditions?: {
96
+ /**
97
+ * This interface was referenced by `undefined`'s JSON-Schema definition
98
+ * via the `patternProperty` ".+".
99
+ */
100
+ [k: string]: {
101
+ implicitRole?: ImplicitRole;
102
+ permittedRoles?: PermittedRoles;
103
+ namingProhibited?: true;
104
+ implicitProperties?: ImplicitProperties;
105
+ properties?: PermittedARIAProperties;
106
+ };
107
+ };
108
+ '1.2'?: {
109
+ implicitRole?: ImplicitRole;
110
+ permittedRoles?: PermittedRoles;
111
+ namingProhibited?: true;
112
+ implicitProperties?: ImplicitProperties;
113
+ properties?: PermittedARIAProperties;
114
+ conditions?: {
115
+ /**
116
+ * This interface was referenced by `undefined`'s JSON-Schema definition
117
+ * via the `patternProperty` ".+".
118
+ */
119
+ [k: string]: {
120
+ implicitRole?: ImplicitRole;
121
+ permittedRoles?: PermittedRoles;
122
+ namingProhibited?: true;
123
+ implicitProperties?: ImplicitProperties;
124
+ properties?: PermittedARIAProperties;
125
+ };
126
+ };
127
+ };
128
+ '1.1'?: {
129
+ implicitRole?: ImplicitRole;
130
+ permittedRoles?: PermittedRoles;
131
+ implicitProperties?: ImplicitProperties;
132
+ properties?: PermittedARIAProperties;
133
+ conditions?: {
134
+ /**
135
+ * This interface was referenced by `undefined`'s JSON-Schema definition
136
+ * via the `patternProperty` ".+".
137
+ */
138
+ [k: string]: {
139
+ implicitRole?: ImplicitRole;
140
+ permittedRoles?: PermittedRoles;
141
+ implicitProperties?: ImplicitProperties;
142
+ properties?: PermittedARIAProperties;
143
+ };
144
+ };
145
+ };
146
+ }
147
+ export interface ImplicitProperties {
148
+ /**
149
+ * This interface was referenced by `ImplicitProperties`'s JSON-Schema definition
150
+ * via the `patternProperty` "^aria-.+".
151
+ */
152
+ [k: string]: string;
153
+ }