@markuplint/ml-spec 1.7.0 → 2.0.0-dev.20211213.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.
- package/lib/attributes.d.ts +97 -0
- package/lib/attributes.js +8 -0
- package/lib/get-attr-specs.d.ts +7 -0
- package/lib/get-attr-specs.js +78 -0
- package/lib/get-ns.d.ts +1 -0
- package/lib/get-ns.js +17 -0
- package/lib/get-spec-by-tag-name.d.ts +2 -2
- package/lib/get-spec-by-tag-name.js +7 -6
- package/lib/get-spec.d.ts +3 -3
- package/lib/get-spec.js +30 -4
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -4
- package/lib/permitted-structres.d.ts +13 -1
- package/lib/types.d.ts +26 -19
- package/lib/utils.js +4 -1
- package/package.json +9 -5
- package/schemas/attributes.schema.json +202 -74
- package/schemas/global-attributes.schema.json +741 -0
- package/schemas/permitted-structures.schema.json +53 -9
- package/src/attributes.ts +1418 -0
- package/src/get-attr-specs.spec.ts +44 -0
- package/src/get-attr-specs.ts +97 -0
- package/src/get-ns.ts +13 -0
- package/src/get-spec-by-tag-name.ts +9 -9
- package/src/get-spec.spec.ts +12 -16
- package/src/get-spec.ts +29 -4
- package/src/index.ts +3 -0
- package/src/permitted-structres.ts +33 -1
- package/src/types.ts +30 -57
- package/tsconfig.test.json +1 -6
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import htmlSpec from '@markuplint/html-spec';
|
|
2
|
+
|
|
3
|
+
import { getAttrSpecs } from './get-attr-specs';
|
|
4
|
+
|
|
5
|
+
describe('getSpec', () => {
|
|
6
|
+
test('svg:image[x]', () => {
|
|
7
|
+
const specs = getAttrSpecs('svg:image', htmlSpec);
|
|
8
|
+
const x = specs?.find(spec => spec.name === 'x');
|
|
9
|
+
expect(x).toStrictEqual({
|
|
10
|
+
ref: 'https://svgwg.org/svg2-draft/geometry.html#XProperty',
|
|
11
|
+
defaultValue: '0',
|
|
12
|
+
name: 'x',
|
|
13
|
+
type: ['<svg-length>', '<percentage>'],
|
|
14
|
+
animatable: true,
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('svg:foreignObject[x]', () => {
|
|
19
|
+
const specs = getAttrSpecs('svg:foreignObject', htmlSpec);
|
|
20
|
+
const x = specs?.find(spec => spec.name === 'x');
|
|
21
|
+
expect(x).toStrictEqual({
|
|
22
|
+
ref: 'https://svgwg.org/svg2-draft/geometry.html#XProperty',
|
|
23
|
+
defaultValue: '0',
|
|
24
|
+
description:
|
|
25
|
+
'The x coordinate of the foreignObject. Value type: <length>|<percentage> ; Default value: 0; Animatable: yes',
|
|
26
|
+
name: 'x',
|
|
27
|
+
type: ['<svg-length>', '<percentage>'],
|
|
28
|
+
animatable: true,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('svg:linearGradient[xlink:href]', () => {
|
|
33
|
+
const specs = getAttrSpecs('svg:linearGradient', htmlSpec);
|
|
34
|
+
const x = specs?.find(spec => spec.name === 'xlink:href');
|
|
35
|
+
expect(x).toStrictEqual({
|
|
36
|
+
ref: 'https://www.w3.org/TR/xlink11/#link-locators',
|
|
37
|
+
description:
|
|
38
|
+
'Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.An <IRI> reference to another <linearGradient> element that will be used as a template. Value type: <IRI> ; Default value: none; Animatable: yes',
|
|
39
|
+
name: 'xlink:href',
|
|
40
|
+
type: 'URL',
|
|
41
|
+
deprecated: true,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { MLMLSpec, Attribute } from './types';
|
|
2
|
+
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
export function getAttrSpecs(nameWithNS: string, { specs, def }: MLMLSpec) {
|
|
6
|
+
const elSpec = specs.find(spec => spec.name === nameWithNS);
|
|
7
|
+
|
|
8
|
+
if (!elSpec) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const globalAttrs = def['#globalAttrs'];
|
|
12
|
+
let attrs: Record<string, Partial<Attribute>> = {};
|
|
13
|
+
|
|
14
|
+
for (const catName in elSpec.globalAttrs) {
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
const catAttrs: boolean | string[] = elSpec.globalAttrs[catName];
|
|
17
|
+
if (!catAttrs) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (typeof catAttrs === 'boolean') {
|
|
21
|
+
const global = globalAttrs[catName];
|
|
22
|
+
attrs = {
|
|
23
|
+
...attrs,
|
|
24
|
+
...global,
|
|
25
|
+
};
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(catAttrs)) {
|
|
29
|
+
const global = globalAttrs[catName];
|
|
30
|
+
if (!global) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
catAttrs.forEach(selectedName => {
|
|
34
|
+
const selected = global[selectedName];
|
|
35
|
+
attrs[selectedName] = {
|
|
36
|
+
...attrs[selectedName],
|
|
37
|
+
...selected,
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const attrName in elSpec.attributes) {
|
|
45
|
+
const attr = elSpec.attributes[attrName];
|
|
46
|
+
if (!attr) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const current = attrs[attrName] as Omit<Attribute, 'name'> | undefined;
|
|
51
|
+
|
|
52
|
+
attrs[attrName] = {
|
|
53
|
+
description: '',
|
|
54
|
+
...current,
|
|
55
|
+
...attr,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const attrList: Attribute[] = Object.keys(attrs).map<Attribute>(name => {
|
|
60
|
+
const attr = attrs[name];
|
|
61
|
+
return { name, type: 'Any', ...attr };
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
for (const attr of attrList) {
|
|
65
|
+
if (!attr.type) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`The type is empty in the ${attr.name} attribute of the ${nameWithNS} element (${path.resolve(
|
|
68
|
+
process.cwd(),
|
|
69
|
+
'packages',
|
|
70
|
+
'@markuplint',
|
|
71
|
+
'html-spec',
|
|
72
|
+
'src',
|
|
73
|
+
'attributes',
|
|
74
|
+
nameWithNS.replace(':', '_') + '.json',
|
|
75
|
+
)})`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
attrList.sort(nameCompare);
|
|
81
|
+
|
|
82
|
+
return attrList;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type HasName = { name: string };
|
|
86
|
+
|
|
87
|
+
export function nameCompare(a: HasName | string, b: HasName | string) {
|
|
88
|
+
const nameA = typeof a === 'string' ? a : a.name.toUpperCase();
|
|
89
|
+
const nameB = typeof b === 'string' ? b : b.name.toUpperCase();
|
|
90
|
+
if (nameA < nameB) {
|
|
91
|
+
return -1;
|
|
92
|
+
}
|
|
93
|
+
if (nameA > nameB) {
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
package/src/get-ns.ts
ADDED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { MLDOMElementSpec, MLMLSpec, SpecOM } from './types';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { getAttrSpecs } from './get-attr-specs';
|
|
4
|
+
|
|
5
|
+
function getSpecOM(spec: MLMLSpec): SpecOM {
|
|
4
6
|
const som: SpecOM = {};
|
|
5
|
-
for (const el of specs) {
|
|
7
|
+
for (const el of spec.specs) {
|
|
8
|
+
const attributes = getAttrSpecs(el.name, spec);
|
|
6
9
|
som[el.name] = {
|
|
7
10
|
experimental: !!el.experimental,
|
|
8
11
|
obsolete: typeof el.obsolete === 'boolean' ? !!el.obsolete : el.obsolete ? el.obsolete.alt : false,
|
|
@@ -10,16 +13,13 @@ function getSpecOM({ specs }: MLMLSpec): SpecOM {
|
|
|
10
13
|
nonStandard: !!el.nonStandard,
|
|
11
14
|
categories: el.categories,
|
|
12
15
|
permittedStructures: el.permittedStructures,
|
|
13
|
-
attributes:
|
|
14
|
-
(attr: Attribute | string): attr is Attribute => !(typeof attr === 'string'),
|
|
15
|
-
),
|
|
16
|
+
attributes: Object.values(attributes || {}),
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
return som;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export function getSpecByTagName(
|
|
22
|
+
export function getSpecByTagName(nameWithNS: string, specs: MLMLSpec): MLDOMElementSpec | null {
|
|
22
23
|
const specOM = getSpecOM(specs);
|
|
23
|
-
|
|
24
|
-
return specOM[tagName] || null;
|
|
24
|
+
return specOM[nameWithNS] || null;
|
|
25
25
|
}
|
package/src/get-spec.spec.ts
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import htmlSpec
|
|
1
|
+
import htmlSpec from '@markuplint/html-spec';
|
|
2
|
+
|
|
2
3
|
import { getSpec } from './get-spec';
|
|
3
4
|
|
|
4
5
|
describe('getSpec', () => {
|
|
5
|
-
test('', () => {
|
|
6
|
-
const exAttr
|
|
7
|
-
|
|
6
|
+
test('Overriding', () => {
|
|
7
|
+
const exAttr = {
|
|
8
|
+
ref: 'N/A',
|
|
8
9
|
type: 'Boolean',
|
|
9
10
|
description: 'For the unit test.',
|
|
10
|
-
};
|
|
11
|
-
const exAttr2
|
|
12
|
-
|
|
11
|
+
} as const;
|
|
12
|
+
const exAttr2 = {
|
|
13
|
+
ref: 'N/A',
|
|
13
14
|
type: 'Boolean',
|
|
14
15
|
description: 'For the unit test. Override.',
|
|
15
|
-
};
|
|
16
|
+
} as const;
|
|
16
17
|
const mergedSpec = getSpec([
|
|
17
18
|
htmlSpec,
|
|
18
19
|
{
|
|
19
20
|
specs: [
|
|
20
21
|
{
|
|
21
22
|
name: 'a',
|
|
22
|
-
attributes:
|
|
23
|
+
attributes: { 'extended-attr': exAttr },
|
|
23
24
|
},
|
|
24
25
|
],
|
|
25
26
|
},
|
|
@@ -27,17 +28,12 @@ describe('getSpec', () => {
|
|
|
27
28
|
specs: [
|
|
28
29
|
{
|
|
29
30
|
name: 'a',
|
|
30
|
-
attributes:
|
|
31
|
+
attributes: { 'extended-attr': exAttr2 },
|
|
31
32
|
},
|
|
32
33
|
],
|
|
33
34
|
},
|
|
34
35
|
]);
|
|
35
36
|
const aElAttrs = mergedSpec.specs.find(el => el.name === 'a')!.attributes;
|
|
36
|
-
expect(
|
|
37
|
-
aElAttrs.find((attr): attr is Attribute => !(typeof attr === 'string') && attr.name === 'href')!.name,
|
|
38
|
-
).toBe('href');
|
|
39
|
-
expect(
|
|
40
|
-
aElAttrs.find((attr): attr is Attribute => !(typeof attr === 'string') && attr.name === exAttr.name),
|
|
41
|
-
).toStrictEqual(exAttr2);
|
|
37
|
+
expect(aElAttrs['extended-attr']).toStrictEqual(exAttr2);
|
|
42
38
|
});
|
|
43
39
|
});
|
package/src/get-spec.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ElementSpec, ExtendedSpec, MLMLSpec } from '
|
|
1
|
+
import type { ElementSpec, ExtendedSpec, MLMLSpec, Attribute } from './types';
|
|
2
|
+
|
|
2
3
|
import { mergeArray } from './utils';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -19,8 +20,11 @@ export function getSpec(schemas: readonly [MLMLSpec, ...ExtendedSpec[]]) {
|
|
|
19
20
|
if (extendedSpec.def['#ariaAttrs']) {
|
|
20
21
|
result.def['#ariaAttrs'] = [...result.def['#ariaAttrs'], ...extendedSpec.def['#ariaAttrs']];
|
|
21
22
|
}
|
|
22
|
-
if (extendedSpec.def['#globalAttrs']) {
|
|
23
|
-
result.def['#globalAttrs']
|
|
23
|
+
if (extendedSpec.def['#globalAttrs']?.['#extends']) {
|
|
24
|
+
result.def['#globalAttrs']['#HTMLGlobalAttrs'] = {
|
|
25
|
+
...(result.def['#globalAttrs']?.['#HTMLGlobalAttrs'] || {}),
|
|
26
|
+
...(extendedSpec.def['#globalAttrs']?.['#extends'] || {}),
|
|
27
|
+
};
|
|
24
28
|
}
|
|
25
29
|
if (extendedSpec.def['#roles']) {
|
|
26
30
|
result.def['#roles'] = [...result.def['#roles'], ...extendedSpec.def['#roles']];
|
|
@@ -51,7 +55,11 @@ export function getSpec(schemas: readonly [MLMLSpec, ...ExtendedSpec[]]) {
|
|
|
51
55
|
specs.push({
|
|
52
56
|
...elSpec,
|
|
53
57
|
...exSpec,
|
|
54
|
-
|
|
58
|
+
globalAttrs: {
|
|
59
|
+
...elSpec.globalAttrs,
|
|
60
|
+
...exSpec.globalAttrs,
|
|
61
|
+
},
|
|
62
|
+
attributes: mergeAttrSpec(elSpec.attributes, exSpec.attributes),
|
|
55
63
|
categories: mergeArray(elSpec.categories, exSpec.categories),
|
|
56
64
|
});
|
|
57
65
|
}
|
|
@@ -62,3 +70,20 @@ export function getSpec(schemas: readonly [MLMLSpec, ...ExtendedSpec[]]) {
|
|
|
62
70
|
|
|
63
71
|
return result;
|
|
64
72
|
}
|
|
73
|
+
|
|
74
|
+
function mergeAttrSpec(
|
|
75
|
+
std: Record<string, Attribute>,
|
|
76
|
+
ex: Record<string, Partial<Attribute>> = {},
|
|
77
|
+
): Record<string, Attribute> {
|
|
78
|
+
const result: Record<string, Attribute> = {};
|
|
79
|
+
const keys = Array.from(new Set([...Object.keys(std), ...Object.keys(ex)]));
|
|
80
|
+
for (const key of keys) {
|
|
81
|
+
const _std = std[key];
|
|
82
|
+
const _ex = ex[key];
|
|
83
|
+
result[key] = {
|
|
84
|
+
..._std,
|
|
85
|
+
..._ex,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -24,7 +24,27 @@ export type ContentModel =
|
|
|
24
24
|
| '#transparent'
|
|
25
25
|
| '#embedded'
|
|
26
26
|
| '#palpable'
|
|
27
|
-
| '#script-supporting'
|
|
27
|
+
| '#script-supporting'
|
|
28
|
+
| '#SVGAnimation'
|
|
29
|
+
| '#SVGBasicShapes'
|
|
30
|
+
| '#SVGContainer'
|
|
31
|
+
| '#SVGDescriptive'
|
|
32
|
+
| '#SVGFilterPrimitive'
|
|
33
|
+
| '#SVGFont'
|
|
34
|
+
| '#SVGGradient'
|
|
35
|
+
| '#SVGGraphics'
|
|
36
|
+
| '#SVGGraphicsReferencing'
|
|
37
|
+
| '#SVGLightSource'
|
|
38
|
+
| '#SVGNeverRendered'
|
|
39
|
+
| '#SVGNone'
|
|
40
|
+
| '#SVGPaintServer'
|
|
41
|
+
| '#SVGRenderable'
|
|
42
|
+
| '#SVGShape'
|
|
43
|
+
| '#SVGStructural'
|
|
44
|
+
| '#SVGStructurallyExternal'
|
|
45
|
+
| '#SVGTextContent'
|
|
46
|
+
| '#SVGTextContentChild'
|
|
47
|
+
| '#SVGOtherXMLNamespace';
|
|
28
48
|
export type PermittedContentSpec = PermittedContent[];
|
|
29
49
|
|
|
30
50
|
export interface PermittedStructuresSchema {
|
|
@@ -37,6 +57,12 @@ export interface PermittedStructuresSchema {
|
|
|
37
57
|
}
|
|
38
58
|
| {
|
|
39
59
|
parent: string;
|
|
60
|
+
/**
|
|
61
|
+
* Not support yet
|
|
62
|
+
*/
|
|
63
|
+
hasNotAttr?: string;
|
|
64
|
+
_TODO_?: string;
|
|
65
|
+
_parent?: string;
|
|
40
66
|
};
|
|
41
67
|
contents: PermittedContentSpec | boolean;
|
|
42
68
|
}[];
|
|
@@ -49,24 +75,28 @@ export interface PermittedContentRequire {
|
|
|
49
75
|
notAllowedDescendants?: Node[];
|
|
50
76
|
max?: number;
|
|
51
77
|
min?: number;
|
|
78
|
+
_TODO_?: string;
|
|
52
79
|
}
|
|
53
80
|
export interface PermittedContentOptional {
|
|
54
81
|
optional: Target;
|
|
55
82
|
ignore?: Target;
|
|
56
83
|
notAllowedDescendants?: Node[];
|
|
57
84
|
max?: number;
|
|
85
|
+
_TODO_?: string;
|
|
58
86
|
}
|
|
59
87
|
export interface PermittedContentOneOrMore {
|
|
60
88
|
oneOrMore: Target | PermittedContentSpec;
|
|
61
89
|
ignore?: Target;
|
|
62
90
|
notAllowedDescendants?: Node[];
|
|
63
91
|
max?: number;
|
|
92
|
+
_TODO_?: string;
|
|
64
93
|
}
|
|
65
94
|
export interface PermittedContentZeroOrMore {
|
|
66
95
|
zeroOrMore: Target | PermittedContentSpec;
|
|
67
96
|
ignore?: Target;
|
|
68
97
|
notAllowedDescendants?: Node[];
|
|
69
98
|
max?: number;
|
|
99
|
+
_TODO_?: string;
|
|
70
100
|
}
|
|
71
101
|
export interface PermittedContentChoice {
|
|
72
102
|
choice:
|
|
@@ -80,7 +110,9 @@ export interface PermittedContentChoice {
|
|
|
80
110
|
PermittedContentSpec,
|
|
81
111
|
PermittedContentSpec,
|
|
82
112
|
];
|
|
113
|
+
_TODO_?: string;
|
|
83
114
|
}
|
|
84
115
|
export interface PermittedContentInterleave {
|
|
85
116
|
interleave: [PermittedContentSpec, PermittedContentSpec, ...PermittedContentSpec[]];
|
|
117
|
+
_TODO_?: string;
|
|
86
118
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AttributeJSON } from '.';
|
|
2
|
+
import type { AttributeType, GlobalAttributes } from './attributes';
|
|
3
|
+
import type { ContentModel, PermittedStructuresSchema } from './permitted-structres';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* markuplit Markup-language spec
|
|
@@ -9,7 +11,10 @@ export interface MLMLSpec {
|
|
|
9
11
|
specs: ElementSpec[];
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
type ExtendedElementSpec = Partial<ElementSpec
|
|
14
|
+
export type ExtendedElementSpec = Partial<Omit<ElementSpec, 'name' | 'attributes'>> & {
|
|
15
|
+
name: ElementSpec['name'];
|
|
16
|
+
attributes?: Record<string, Partial<Attribute>>;
|
|
17
|
+
};
|
|
13
18
|
|
|
14
19
|
export type ExtendedSpec = {
|
|
15
20
|
cites?: Cites;
|
|
@@ -23,9 +28,13 @@ export type ExtendedSpec = {
|
|
|
23
28
|
export type Cites = string[];
|
|
24
29
|
|
|
25
30
|
export type SpecDefs = {
|
|
26
|
-
'#globalAttrs':
|
|
27
|
-
|
|
31
|
+
'#globalAttrs': Partial<{
|
|
32
|
+
'#extends': Record<string, Partial<Attribute>>;
|
|
33
|
+
'#HTMLGlobalAttrs': Record<string, Partial<Attribute>>;
|
|
34
|
+
[OtherGlobalAttrs: string]: Record<string, Partial<Attribute>>;
|
|
35
|
+
}>;
|
|
28
36
|
'#ariaAttrs': ARIAAttribute[];
|
|
37
|
+
'#roles': ARIRRoleAttribute[];
|
|
29
38
|
'#contentModels': { [model in ContentModel]?: string[] };
|
|
30
39
|
};
|
|
31
40
|
|
|
@@ -38,6 +47,12 @@ export type ElementSpec = {
|
|
|
38
47
|
*/
|
|
39
48
|
name: string;
|
|
40
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Namespaces in XML
|
|
52
|
+
* @see https://www.w3.org/TR/xml-names/
|
|
53
|
+
*/
|
|
54
|
+
namespace?: 'http://www.w3.org/1999/xhtml' | 'http://www.w3.org/2000/svg' | 'http://www.w3.org/1998/Math/MathML';
|
|
55
|
+
|
|
41
56
|
/**
|
|
42
57
|
* Reference URL
|
|
43
58
|
*/
|
|
@@ -111,10 +126,15 @@ export type ElementSpec = {
|
|
|
111
126
|
*/
|
|
112
127
|
omittion: ElementSpecOmittion;
|
|
113
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Global Attributes
|
|
131
|
+
*/
|
|
132
|
+
globalAttrs: GlobalAttributes;
|
|
133
|
+
|
|
114
134
|
/**
|
|
115
135
|
* Attributes
|
|
116
136
|
*/
|
|
117
|
-
attributes:
|
|
137
|
+
attributes: Record<string, Attribute>;
|
|
118
138
|
};
|
|
119
139
|
|
|
120
140
|
/**
|
|
@@ -141,63 +161,16 @@ type ElementCondition = {
|
|
|
141
161
|
|
|
142
162
|
export type Attribute = {
|
|
143
163
|
name: string;
|
|
144
|
-
type: AttributeType;
|
|
145
|
-
description
|
|
164
|
+
type: AttributeType | AttributeType[];
|
|
165
|
+
description?: string;
|
|
146
166
|
caseSensitive?: true;
|
|
147
167
|
experimental?: true;
|
|
148
168
|
obsolete?: true;
|
|
149
|
-
deprecated?:
|
|
169
|
+
deprecated?: boolean;
|
|
150
170
|
nonStandard?: true;
|
|
151
|
-
|
|
152
|
-
requiredEither?: string[];
|
|
153
|
-
enum?: string[];
|
|
154
|
-
noUse?: boolean;
|
|
155
|
-
condition?: AttributeCondition;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export type AttributeCondition = {
|
|
159
|
-
ancestor?: string;
|
|
160
|
-
self?: string | string[];
|
|
161
|
-
};
|
|
171
|
+
} & ExtendableAttributeSpec;
|
|
162
172
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
export type AttributeType =
|
|
166
|
-
| 'String'
|
|
167
|
-
| 'NonEmptyString'
|
|
168
|
-
| 'Boolean'
|
|
169
|
-
| 'Function' // JavaScript function body
|
|
170
|
-
| 'Date'
|
|
171
|
-
| 'Int' // Integer
|
|
172
|
-
| 'Uint' // Non-negative integer
|
|
173
|
-
| 'Float' // Floating-point number
|
|
174
|
-
| 'NonZeroUint' // Non-negative integer greater than zero
|
|
175
|
-
| 'AcceptList' // https://html.spec.whatwg.org/multipage/input.html#attr-input-accept
|
|
176
|
-
| 'AutoComplete' // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens
|
|
177
|
-
| 'BCP47' // https://tools.ietf.org/html/bcp47
|
|
178
|
-
| 'Color' // https://drafts.csswg.org/css-color/#typedef-color
|
|
179
|
-
| 'ColSpan' // https://html.spec.whatwg.org/multipage/tables.html#attr-tdth-colspan
|
|
180
|
-
| 'Coords' // https://html.spec.whatwg.org/multipage/image-maps.html#attr-area-coords
|
|
181
|
-
| 'DateTime' // https://html.spec.whatwg.org/multipage/text-level-semantics.html#datetime-value
|
|
182
|
-
| 'Destination' // https://html.spec.whatwg.org/multipage/semantics.html#attr-link-as
|
|
183
|
-
| 'DOMID'
|
|
184
|
-
| 'DOMIDList'
|
|
185
|
-
| 'ItemType' // https://html.spec.whatwg.org/multipage/microdata.html#attr-itemtype
|
|
186
|
-
| 'LinkSizes' // https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes
|
|
187
|
-
| 'LinkType' // https://html.spec.whatwg.org/multipage/links.html#linkTypes
|
|
188
|
-
| 'LinkTypeList' // https://html.spec.whatwg.org/multipage/links.html#linkTypes
|
|
189
|
-
| 'MediaQuery' // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-media-query-list
|
|
190
|
-
| 'MediaQueryList' // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-media-query-list
|
|
191
|
-
| 'MIMEType' // https://mimesniff.spec.whatwg.org/#valid-mime-type
|
|
192
|
-
| 'ReferrerPolicy' // https://html.spec.whatwg.org/multipage/urls-and-fetching.html#referrer-policy-attributes
|
|
193
|
-
| 'RowSpan' // https://html.spec.whatwg.org/multipage/tables.html#attr-tdth-rowspan
|
|
194
|
-
| 'SourceSizeList' // https://html.spec.whatwg.org/multipage/images.html#sizes-attributes
|
|
195
|
-
| 'SrcSet' // https://html.spec.whatwg.org/multipage/images.html#srcset-attribute
|
|
196
|
-
| 'TabIndex' // https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
|
|
197
|
-
| 'Target' // https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target
|
|
198
|
-
| 'URL' // https://html.spec.whatwg.org/multipage/urls-and-fetching.html#valid-url-potentially-surrounded-by-spaces
|
|
199
|
-
| 'URLHash' // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-hash-name-reference
|
|
200
|
-
| 'URLList'; // https://html.spec.whatwg.org/multipage/urls-and-fetching.html#valid-url-potentially-surrounded-by-spaces
|
|
173
|
+
type ExtendableAttributeSpec = Omit<AttributeJSON, 'ref' | '_TODO_' | 'type'>;
|
|
201
174
|
|
|
202
175
|
export type ARIRRoleAttribute = {
|
|
203
176
|
name: string;
|