Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ARIA IDL updates: enumerated attribute conversions, new "enumerated" wai-aria type, IDL examples #2484

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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

rahimabdi
Copy link
Contributor

@rahimabdi rahimabdi commented Mar 23, 2025

Closes #2281
Closes #2279

If helpful, I also created this tool to simulate how the new ARIA IDL works for enumerated attributes: https://rahimabdi.github.io/aria-idl-simulator/.

  • add enumerated attribute definitions for the following attributes including missing value default, invalid value default, keywords/states:
    • aria-atomic
    • aria-autocomplete
    • aria-busy
    • aria-checked
    • aria-current
    • aria-disabled
    • aria-expanded
    • aria-haspopup
    • aria-hidden
    • aria-invalid
    • aria-live
    • aria-modal
    • aria-multiline
    • aria-multiselectable
    • aria-orientation
    • aria-pressed
    • aria-readonly
    • aria-required
    • aria-selected
    • aria-sort
  • Revise "A. Mapping WAI-ARIA Value types to languages" to include enumerated attributes
  • Revise "6.2.4 Value" for permissible values (remove all other types except "enumerated"?)
  • Update "6.3 ARIA Attributes"
    • Remove obsolete note in "6.3.4 ARIA nullable DOMString Attributes" about ARIA transitioning to non-nullable DOMString?
    • Remote spec guidance around getting/setting to only apply to non-enumerated attributes
    • Provide updated examples for "6.3.4.1 Example Attribute Usage"
  • Visual styling
    • Remove <strong> style from old "defaults" values
    • Confirm and apply style for new “State” column, state descriptions

Test, Documentation and Implementation tracking

Once this PR has been reviewed and has consensus from the working group, tests should be written and issues should be opened on browsers. Add N/A and check when not applicable.

  • "author MUST" tests:
  • "user agent MUST" tests:
  • Browser implementations (link to issue or commit):
    • WebKit:
    • Gecko:
    • Blink:
  • Does this need AT implementations?
  • Related APG Issue/PR:
  • MDN Issue/PR:

Preview | Diff

Copy link

netlify bot commented Mar 23, 2025

Deploy Preview for wai-aria ready!

Name Link
🔨 Latest commit b2ba05c
🔍 Latest deploy log https://app.netlify.com/sites/wai-aria/deploys/680e623f1c81250008bd9810
😎 Deploy Preview https://deploy-preview-2484--wai-aria.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

index.html Outdated
<td class="value-description">The element does not support being checked.</td>
</tr>
</tbody>
</table>
<p>The attribute's <a data-cite="html/common-microsyntaxes.html#missing-value-default">missing value default</a> and <a data-cite="html/common-microsyntaxes.html#invalid-value-default">invalid value default</a> are both the Undefined state.</p>
Copy link
Contributor Author

@rahimabdi rahimabdi Mar 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migrated comment from @keithamus (original):

I don't think we want the missing value default here to return the Undefined state, that will mean the .ariaChecked property will return "undefined" when aria-checked isn't on the element. I presume we want to return null instead? Browsers currently return null, so missing should be "no state", i.e. removed:

Suggested change
<p>The attribute's <a data-cite="html/common-microsyntaxes.html#missing-value-default">missing value default</a> and <a data-cite="html/common-microsyntaxes.html#invalid-value-default">invalid value default</a> are both the Undefined state.</p>
<p>The attribute has no <a data-cite="html/common-microsyntaxes.html#missing-value-default">missing value default</a> and its <a data-cite="html/common-microsyntaxes.html#invalid-value-default">invalid value default</a> is the Undefined state.</p>

@rahimabdi
Copy link
Contributor Author

@keithamus:

@rahimabdi I've left a couple of review notes which I think apply in a lot of places, but rather than inundating you with review comments hopefully you can take the couple here and pattern match across the rest of the spec.

Thanks! I'll review those comments (which are migrated to this PR now) and respond.

@rahimabdi
Copy link
Contributor Author

Re-added reviewers @pkra @spectranaut @cookiecrook @keithamus @scottaohara.

@rahimabdi rahimabdi marked this pull request as draft March 27, 2025 17:23
@rahimabdi rahimabdi marked this pull request as ready for review April 27, 2025 17:03
@rahimabdi
Copy link
Contributor Author

rahimabdi commented Apr 27, 2025

CC @pkra @spectranaut @cookiecrook @keithamus @scottaohara @annevk

This PR is ready for review! I've made a number of updates, mainly:

  • Cleaned up enumerated attribute keywords/states per @keithamus's feedback
  • Changed aria-atomic's Missing state to Undefined, to align with other ARIA attributes that have an "Undefined" state
  • Added more IDL usage examples
  • Added a note clarifying that Undefined state is equivalent to "no state"

If helpful, I also created this tool to simulate how the new ARIA IDL works for enumerated attributes: https://rahimabdi.github.io/aria-idl-simulator/.

@rahimabdi rahimabdi requested review from keithamus, annevk, cookiecrook, pkra, spectranaut and scottaohara and removed request for annevk April 27, 2025 17:08
Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that's nice in HTML is that all the states are a <dfn> and therefore also can be linked. But maybe that's best addressed in a follow-up.

Comment on lines +11941 to +11942
Some ARIA attributes support an Undefined state, which is equivalent to having no state (i.e., null). User agent implementations may omit the Undefined state since the lack of an explicit
state results in the same behavior. For more information about determining the state of enumerated attributes, see
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this sentence adds more confusion than it resolves. Especially since you cannot just leave it out at the moment without hitting an assert.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of this could be an informative note for authors/implementors, rather than in the normative text of the Enumerated Attribute definition.

Do we ever anticipate a time where the explicit "undefined" content attribute values would need to map to an Undefined state, separately than the Null state? For example, I think the only scenarios where an undefined is allowed are with the undefined/true/false/[/mixed] enumerated values, but since the Missing Default and Invalid Default are the same one those, there is no impact... Can we foresee any scenario where those would be different? For example, if undefined was an allowed token value of aria-invalid? (Presumably we just need to always avoid that, which seems okay.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default values from the ARIA values tables MUST NOT reflect to IDL as the <a data-cite="html/common-microsyntaxes.html#missing-value-default">missing value default</a> or the
<a data-cite="html/common-microsyntaxes.html#invalid-value-default">invalid value default</a> for the attribute. On getting, a missing ARIA attribute will return <code>null</code>. ARIA
attributes are not validated on get. If an ARIA value is invalid, on getting, it will return its set value as a literal string, and will not return an invalid value default.
For non-enumerated attributes, default values from the ARIA values tables MUST NOT reflect to IDL as the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems okay to state as a note, but it shouldn't be a requirement. HTML already requires this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

informative note

@@ -12761,7 +12802,7 @@ <h2>Definitions of States and Properties (all aria-* attributes)</h2>
</tr>
<tr>
<th class="state-value-head" scope="row">Value:</th>
<td class="state-value"><a href="#valuetype_tristate">tristate</a></td>
<a href="#valuetype_enumerated">enumerated</a>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems better

Suggested change
<a href="#valuetype_enumerated">enumerated</a>
<td class="state-value"><a href="#valuetype_enumerated">enumerated</a></td>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch @pkra

@cyns
Copy link
Contributor

cyns commented May 8, 2025

@aleventhal you may want to review this

@cyns cyns self-requested a review May 8, 2025 17:40
<td class="value-description">
When a user is providing input, an element containing a collection of values that could complete the provided input might be displayed. If displayed, one value in the collection is
automatically selected, and the text needed to complete the automatically selected value appears after the caret in the input.
</td>
</tr>
<tr>
<th class="value-name" scope="row"><strong class="default">none (default)</strong></th>
<th class="value-name" scope="row">none</th>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional that (default) is dropped here? (And in 18 other instances.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a future enhancement for ARIA editors to avoid value error contradictions, perhaps the values table could be generated from the IDL? Or generate both the IDL and the values tables from the same pre-ReSpec source? (Not in this patch though. It's already massive.)

@spectranaut
Copy link
Contributor

Discussed in today's meeting: https://www.w3.org/2025/05/08-aria-minutes.html#7d9a

Copy link
Contributor

@cyns cyns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! this is much more clear, thank you

<p>
For <a data-cite="html/common-dom-interfaces.html#reflect">reflection</a> purposes, the attribute's
<a data-cite="html/common-microsyntaxes.html#missing-value-default">missing value default</a> is the Undefined state (null) that has no associated keyword, and its
<a data-cite="html/common-microsyntaxes.html#invalid-value-default">invalid value default</a> is the False state.
Copy link
Member

@keithamus keithamus May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Blocking) So I believe this kind of change to the spec is web observable, which means it will need changes to the implementations and we need to ensure compatibility for web developers who may depend on the existing behaviour. Unless I am missing that somewhere we clarify that reflected enumerated properties should only return the value of the content attribute?

In this example the web observable piece is that the "invalid value default" is the False state, which means that any invalid value would map to the False (for which I presume the keyword is "false" - see above).

This means pasting this HTML into your URL bar:

data:text/html,<body id=b><div id=d aria-atomic=foo><script>b.append(d.ariaAtomic)</script>

Should render false on the page. But right now it renders foo.

I think this will be the same for all of these properties, e.g. aria-autocomplete, aria-checked and so on.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we should have tests for this and such, but this is very much the motivation for making this change. This makes these IDL attributes more meaningful and enables them to be used for feature testing going forward.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure, I appreciate the motivation for it, I just want us to be cautious about introducing changes to the spec without getting tests & approval from the various engines.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we should add the tentative WPT tests, and implement in engines behind a runtime flag to review potential impact on the Salesforce polyfill (Keith recalled this example) and any other places this might affect webcompat. @nolanlawson FYI ^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed Nolan is no longer at SalesForce. Please copy any relevant contact if you know who should review. Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @divmain @wjhsf ^

Thanks for the heads-up!

<td class="value-description">The element is checked.</td>
</tr>
<tr>
<th class="value-name" scope="row"><strong class="default">undefined</strong> (default)</th>
<th class="value-name" scope="row">undefined, empty string ("")</th>
Copy link
Member

@keithamus keithamus May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Non-blocking) We could reasonably drop the undefined keyword here:

Suggested change
<th class="value-name" scope="row">undefined, empty string ("")</th>
<th class="value-name" scope="row">empty string ("")</th>

If someone set "undefined" then it would map to the invalid value default, which is the undefined state. The only reason not to do this is if you want the canonicalization steps to explicitly return undefined rather than the empty string.

The same is true for other properties, e.g. aria-current, and so on.

Copy link
Contributor Author

@rahimabdi rahimabdi Aug 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great callout! We can simplify many attributes, i.e., empty value and/or undefined map to an invalid value default:

I've also included the "empty value default" which is helpful for boolean-like declaration of ARIA attrs (e.g., <div someAttr>; this could be a WebIDL extended attribute like [EmptyValueDefault] and where it's not null, it could provide an extra state for the attribute.

Simplifying enumeration for attributes:

  • aria-atomic
    • Remove empty string keyword as it maps to “false” state
    • Empty value default = “false”
  • aria-busy
    • Remove empty string keyword as it maps to “false” state
    • Empty value default = “false”
  • aria-checked
    • Remove empty string and undefined keywords as they maps to null (invalid value default)
    • Empty value default = null
  • aria-current
    • Can’t remove empty string because IVD = “true”
    • Empty value default = “false”
    • Undefined string maps to “true”
    • For implementation, this one needs manual reflection (i.e., can't use a nice WebIDL extended attribute like [ReflectEnum]
  • aria-disabled
    • Remove empty string keyword as it maps to “false” state
    • Empty value default = “false”
  • aria-expanded
    • Both empty value and undefined map to null (invalid value default)
    • Empty value default = null
  • aria-hidden
    • Both empty value and undefined map to false state "invalid value default”
    • Empty value default = “false”
    • Undefined maps to “false” which is IVD
  • aria-invalid
    • Empty value default = “false”
  • aria-modal
    • Empty value default is “false”, however it’s also covered by invalid value default so can be removed
  • aria-multiline
    • Empty value default is “false”, however it’s also covered by invalid value default
  • aria-multiselectable
    • Empty value default is “false”, however it’s also covered by invalid value default
  • aria-orientation
    • Both “” and undefined could be covered by invalid value default (null)
    • Empty value default = null
  • aria-pressed
    • Both empty string and undefined could be covered by invalid value default (null)
    • Empty value default = null
  • aria-readonly
    • Empty value default is “false”, however it’s also covered by invalid value default
  • aria-required
    • Empty value default is “false”, however it’s also covered by invalid value default
  • aria-selected
    • Both “” and undefined could be covered by invalid value default
    • Empty value default = null

@spectranaut spectranaut moved this from All PRS to Needs Consensus/Review in ARIA Normative PR Tracking Jun 13, 2025
@spectranaut
Copy link
Contributor

Discussed briefly: https://www.w3.org/2025/06/26-aria-minutes.html#768c

Next step to write tentative tests?

@pkra pkra mentioned this pull request Jul 4, 2025
<a href="#valuetype_true-false">true/false</a>, <a href="#valuetype_true-false-undefined">true/false/undefined</a>, <a href="#valuetype_tristate">tristate (true/false/mixed)</a>, a
single named <a href="#valuetype_token">token</a>, or a <a href="#valuetype_token_list">token list</a>.
Used in an attribute description to denote that the value <a href="#propcharacteristic_value">type</a> is a named token or otherwise token-like, including a single named
<a href="#valuetype_token">token</a>, a <a href="#valuetype_token_list">token list</a>, or <a href="#valuetype_enumerated">enumerated</a>.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to leave a note about token true/false being Boolean-like but not a true Boolean? I recall adding this adjective to the above removal because some implementors and web devs assumed/wanted/thought the true/false values would/should behave like HTML boolean attributes.

I agree with your shorter definition as you have it, but consider whether an additional editorial note may head-off future questions.. For example, from @sideshowbarker regarding the LadyBird implementation.

Comment on lines +11941 to +11942
Some ARIA attributes support an Undefined state, which is equivalent to having no state (i.e., null). User agent implementations may omit the Undefined state since the lack of an explicit
state results in the same behavior. For more information about determining the state of enumerated attributes, see
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of this could be an informative note for authors/implementors, rather than in the normative text of the Enumerated Attribute definition.

Do we ever anticipate a time where the explicit "undefined" content attribute values would need to map to an Undefined state, separately than the Null state? For example, I think the only scenarios where an undefined is allowed are with the undefined/true/false/[/mixed] enumerated values, but since the Missing Default and Invalid Default are the same one those, there is no impact... Can we foresee any scenario where those would be different? For example, if undefined was an allowed token value of aria-invalid? (Presumably we just need to always avoid that, which seems okay.)

<p>
All ARIA attributes reflect in IDL as [=nullable type|nullable=] {{DOMString}} attributes. This includes the boolean-like <a href="#valuetype_true-false">true/false</a> type, and all other
ARIA attributes.
An ARIA attribute may reflect as one of several IDL attribute types such as [=nullable type|nullable=] {{DOMString}}, [=nullable type|nullable=] {{FrozenArray}} or [=nullable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
An ARIA attribute may reflect as one of several IDL attribute types such as [=nullable type|nullable=] {{DOMString}}, [=nullable type|nullable=] {{FrozenArray}} or [=nullable
An ARIA attribute may reflect as one of several IDL attribute types, such as [=nullable type|nullable=] {{DOMString}}, [=nullable type|nullable=] {{FrozenArray}} or [=nullable

Default values from the ARIA values tables MUST NOT reflect to IDL as the <a data-cite="html/common-microsyntaxes.html#missing-value-default">missing value default</a> or the
<a data-cite="html/common-microsyntaxes.html#invalid-value-default">invalid value default</a> for the attribute. On getting, a missing ARIA attribute will return <code>null</code>. ARIA
attributes are not validated on get. If an ARIA value is invalid, on getting, it will return its set value as a literal string, and will not return an invalid value default.
For non-enumerated attributes, default values from the ARIA values tables MUST NOT reflect to IDL as the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

informative note

<section class="informative" id="enumeration-example">
<h4>Example Attribute Usage</h4>
<aside class="example">
<!-- ReSpec needs these examples to be unindented. -->
<pre class="example highlight javascript">
<pre>
// aria-label example (non-enumerated attribute)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// aria-label example (non-enumerated attribute)
// aria-label example (non-enumerated nullable DOMString attribute)

// aria-busy example
// true/false ~ boolean-like nullable string; returns null unless set
<pre>
// aria-busy example (enumerated attribute)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// aria-busy example (enumerated attribute)
// aria-busy example (enumerated attribute)
// the initial example's true/false tokens here are not true Boolean values.

<td class="value-description">
When a user is providing input, an element containing a collection of values that could complete the provided input might be displayed. If displayed, one value in the collection is
automatically selected, and the text needed to complete the automatically selected value appears after the caret in the input.
</td>
</tr>
<tr>
<th class="value-name" scope="row"><strong class="default">none (default)</strong></th>
<th class="value-name" scope="row">none</th>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a future enhancement for ARIA editors to avoid value error contradictions, perhaps the values table could be generated from the IDL? Or generate both the IDL and the values tables from the same pre-ReSpec source? (Not in this patch though. It's already massive.)

@@ -12761,7 +12802,7 @@ <h2>Definitions of States and Properties (all aria-* attributes)</h2>
</tr>
<tr>
<th class="state-value-head" scope="row">Value:</th>
<td class="state-value"><a href="#valuetype_tristate">tristate</a></td>
<a href="#valuetype_enumerated">enumerated</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch @pkra

Comment on lines +11941 to +11942
Some ARIA attributes support an Undefined state, which is equivalent to having no state (i.e., null). User agent implementations may omit the Undefined state since the lack of an explicit
state results in the same behavior. For more information about determining the state of enumerated attributes, see
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Needs Review
8 participants