BREAKING: change attribute metadata to object
Problem description
It is difficult to handle corner-cases when listing known attributes. Today the attributes
property is a list of allowed values but it is not flexible enough yet to handle all cases and in some cases hard to understand.
Supported but hard-to-understand:
- Boolean via
attributes: []
- Allow omitted value via
attributes: [""]
(which also enables the empty string) - Disallow omitted but allow empty requires regexp
attributes: ["/^$/"]
or similar. - Required and deprecated attributes use separate
requiredAttributes
anddeprecatedAttributes
properties.
Unsupported:
- Space-separated tokens, some attributes can hold multiple tokens which each should be validated separately.
- Just making an attribute known without validating allowed values.
- A distinction between omitted
my-attr
and empty valuesmy-attr=""
(which is a cosmetic preference, standard defines omitted value as the empty string). (the cosmetic ruleattribute-empty-style
should still manage the preference but I would be useful if the attribute could define it omitted is allowed at all)
Using the current semantics implementing #68 is difficult.
Suggested solution
Define a new type MetaAttribute
holding all the properties:
interface MetaAttribute {
/* true if attribute is a boolean */
boolean?: boolean;
/* true if value can be omitted */
omit?: boolean;
/* list of allowed values, if unset anything can be used */
enum?: string[];
/* true if the value is a space-separated DOMTokenList */
list?: boolean;
/* true if this attribute is required */
required?: boolean;
/* true if this attribute is deprecated */
deprecated?: boolean;
}
The attribute
property would be replaced with Record<string, MetaAttribute>
:
{
"my-element": {
"attributes": {
"foo": {},
"bar": {
"boolean": true
},
"baz": {
"enum": ["a", "b", "/\\d+/"]
"required": true
}
}
}
}
Since this changes the type of an existing property this would be a breaking change. It would be preferable if v3 would still accept the old array and migrate the property and not remove it until a later release.
Pros
- Better semantics
- Easier to extend with future use-cases
- All properties are optional, makes it easy to just make attribute known without validating
- Makes implementing support for #68 a breeze
Cons
- Breaking change
- Need to maintain support for the deprecated properties/types.