Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARIA attribute reflection uses DOMString? but they are not enumerated attributes #10037

Open
domenic opened this issue Jan 5, 2024 · 3 comments
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. topic: reflect For issues with reflected IDL attributes and friends.

Comments

@domenic
Copy link
Member

domenic commented Jan 5, 2024

What is the issue with the HTML Standard?

ARIAMixin on Element says:

The ARIAMixin getter steps given element, idlAttribute, and contentAttribute are to return the result of the getter algorithm for idlAttribute reflecting contentAttribute on element.

The ARIAMixin setter steps given element, idlAttribute, contentAttribute, and value are to perform the setter algorithm for idlAttribute reflecting contentAttribute on element, given value.

So, let's go look at what the getter algorithm for, say, ariaLive reflecting aria-live="" would be. ariaLive is defined as

[CEReactions] attribute DOMString? ariaLive;

i.e. it's a DOMString?. But HTML's DOMString? getter reflection says:

Assert: attributeDefinition indicates it is an enumerated attribute.

Assert: the reflected IDL attribute is limited to only known values.

Assert: contentAttributeValue corresponds to a state of attributeDefinition.

These asserts generally fail.

The spec might imply that the first succeeds: the definition for aria-live="" states that its "Value:" is "token", and the ARIA type mapping states that "token" "Value:" should somehow map to HTML's Keywords and enumerated attributes section. (With what invalid value default and missing value default? What keyword vs. state mapping, exactly?)

For the second assert (and thus the third as well), there's no evidence that the attributes are limited to only known values. Testing in browsers, it's certainly not the case: document.body.ariaLive = "foo" will happily work, with document.body.ariaLive === "foo" on the next line succeeding.

And of course, picking ariaLive was already stacking the deck in our favor. If we did ariaDescription, which corresponds to the "string"-"Value:"d `aria-description="" attribute, then certainly it would not be an enumerated attribute.

Note that this seems to be implemented in all browsers, according to WPTs.


I see a few paths forward here:

  • 1A. Allow DOMString? reflection for all attributes. Try to avoid using it in the future for such unrestricted cases.

  • 1B Allow DOMString? reflection for attributes starting with aria-* only, as a legacy exception.

  • 2A Decide that DOMString? is a nicer way of doing string reflection than DOMString (since it distinguishes between the attribute being missing and it being present as the empty string), and going forward use it for all new HTML attributes that reflect as strings.

  • 2B Decide that DOMString? is a nicer way of doing string reflection than DOMString, and try to not only use it going forward, but to also change the behavior of existing HTML attributes.

  • 3 Try to change away from DOMString? to instead just DOMString. The behavior change here is that absent attributes would return the empty string, and setting the value to null would no longer remove the attribute but would instead set the attribute's value to the string "null".

  • 4 On a case-by-case basis, update the ARIA IDL attributes to have the best possible reflection semantics, including possibly "limited to only known values" enumerated attribute behavior.

There are some previous issues tracking this on the ARIA side, most notably w3c/aria#1110, but I wanted to summarize the current state of things. Especially since the easiest path, like 1A or 1B, would involve changes solely to HTML.

/cc @annevk @cookiecrook @alice

@domenic domenic added a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. topic: reflect For issues with reflected IDL attributes and friends. labels Jan 5, 2024
@nolanlawson
Copy link

1B Allow DOMString? reflection for attributes starting with aria-* only, as a legacy exception.

Should this include role as well? role is the only prop in ARIAMixin which does not start with aria, but it does behave like the others in browsers.

@keithamus
Copy link
Contributor

On pursuing number 4, I presume it would consist of the following:

For ARIA's token, tristate, true/false and true/false/undefined, I think we can tweak the ARIA specs to more clearly assert on what the missing value/invalid value states are.

Depending on implementer appetite we could also make a change to ensure the reflections are limited to only known values. I suppose this would be a breaking change but I don't know what the impact would be.

Am I correct in saying that we could/should alter freeform reflected properties such as ariaDescription to be USVString? Again is this something that is possible? (I'm vaguely aware of there being some differences between USVString and Strings, but I'm not well versed enough to know if this is breaking).

@domenic
Copy link
Member Author

domenic commented Jan 12, 2024

For ARIA's token, tristate, true/false and true/false/undefined, I think we can tweak the ARIA specs to more clearly assert on what the missing value/invalid value states are.

Depending on implementer appetite we could also make a change to ensure the reflections are limited to only known values. I suppose this would be a breaking change but I don't know what the impact would be.

This is mostly right. However, there's a dilemma which makes it more annoying: currently in HTML DOMString? is always limited to only known values. So if we go down the 4 route, either:

  • ARIA has to change to DOMString. This is a somewhat breaking change, e.g. el.ariaLive = null would no longer remove the attribute, but instead set it to "null". Similar to 3. (And thus, would trigger the invalid value default instead of the missing value default... which is maybe fine, if they're the same. But still a breaking change for anyone reading the values back in JS.)

  • We have to loosen up HTML to allow DOMString? enumerated attribute reflection that is not limited to only known values. This ends up looking like some version of 1 or 2, i.e., we have to decide the scope of this change and what precedent it sets.

Am I correct in saying that we could/should alter freeform reflected properties such as ariaDescription to be USVString? Again is this something that is possible? (I'm vaguely aware of there being some differences between USVString and Strings, but I'm not well versed enough to know if this is breaking).

No. USVString in this context is generally used for URLs. More info at https://w3ctag.github.io/design-principles/#idl-string-types .

The question is whether we should change them from DOMString? to DOMString. To be consistent with our freeform reflected properties such as HTML's existing title="", abbr="", content="", etc., they should just be DOMString. But that's again a backward-incompatible change, so we need to decide whether we value consistency or compatibility for these.

Mguiteria referenced this issue Jan 12, 2024
Helps with #9832, by consistently using "(the empty string)" and placing such rows in the same place in the enumerated attribute tables.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. topic: reflect For issues with reflected IDL attributes and friends.
Development

No branches or pull requests

3 participants