Re: ARIA relationships via selector (Was: Agenda: March 24, 2014 WAI-PF ARIA Caucus)

On Wed, Mar 26, 2014 at 12:31 AM, James Craig <jcraig@apple.com> wrote:

> >> You could still use IDREFs.
> >>
> >>     tree.ariaActiveDescendant = tree.querySelector('#foo');
> >>
> >> But it’d be possible to point to elements that did not have a defined
> ID.
> >>
> >>     tree.ariaActiveDescendant =
> tree.querySelector('[aria-selected="true"]');
> >
> > I hadn't thought about it this way. I was assuming that we'd have to
> solve this with declarative markup, so I was assuming we'd do something
> like <input
> aria-activedescendant="querySelector('[aria-selected="true"]')">, but we
> certainly don't have to. Considering that most of the cases where we'd need
> this are in dynamic content and not static, it's less important to expose
> ARIA in an attribute.
>
> A declarative approach assumes you either want the querySelector context
> to be global (document.querySelector) or on the current element
> (this.querySelector), and I don't think we should assume that. Short of
> those two contexts, there'd be no way to keep or declare the scope
> consistently. For example, what if I want to set the relationship to the
> value of a property maintained by some instance of a view controller?
> aria-owns="this.viewController.someElement"? To do that, we'd either have
> to use the DOM nodes to hold application state, or resolve the execution
> scope some other way. I feel a new declarative syntax for computed values
> might be a step backwards, like specifying a new standard to rely on inline
> event handlers or eval().
>

I think we'd have to have something like elementSelect(foo) vs
docSelect(foo) to provide for both options.

There's nothing you couldn't select for with a document selector, it'd be
quite a bit more flexible than idref - and I really like the idea that the
element it point to could dynamically change with no required JavaScript.

Still, I'm open to both ideas. I'm hoping for broad consensus here - would
you be open to the declarative idea if there's more support for that
approach?

I'd rather go all the way and just make these non-reflected properties, or
> make the reflection be that the content attributes are removed or otherwise
> unset when you assign a relationship. Developer tools are constantly
> improving, so I think it'd be okay for these to be missing from content
> attributes if they can be accessed as DOM attributes or methods.
>

I think removing the content attributes when you set an explicit
relationship would be the simplest.

> How about setAccessibleRelation?
>
> This concept shouldn't have to be limited to accessibility contexts. This
> could be useful for any attribute that accepts IDREF or IDREFS values.
>

The only other idrefs I could find in the html5 spec are <label
for="IDREF"> and <td headers="IDREFs">. What did I miss?

I don't think we should try to overgeneralize a concept if we can't think
of a specific use case for it in the future. Either we should include other
uses of idrefs now, or assume we won't need them for anything other than
accessibility in the future.


myElement.setRelationship("aria-controls", [
> document.QuerySelectorAll(".results"),
> myElement.querySelector(":role(region)") ]);
> myElement.getRelationship("aria-controls"); // returns Element Collection
>

It doesn't feel very DOM-like to me. This seems more consistent with the
rest of the Element API:

  myElement.ariaControls =
document.QuerySelectorAll(".results").concat(myElement.querySelector(":role(region)");
  myElement.ariaControls; // returns Element Collection

> The advantage of this approach is that the selector would update
> automatically, with no JavaScript required. For example, I could implement
> a listbox like this:
> >
> > <div role="listbox" aria-activedescendant="select([tabindex="0"])">
> >   <div role="option" tabindex=0>Apple</div>
> >   <div role="option" tabindex=-1>Orange</div>
> >   <div role="option" tabindex=-1>Banana</div>
> > </div>
>
> I don't see a lot of benefit to avoid JavaScript for the active
> descendant, since you're already forced to change the roaming tabindex with
> JavaScript. It's just one extra line in the JavaScript using a
> well-established convention that works in all browsers today. The
> declarative approach seems like a neat shorthand, but also like you're
> trying to avoid one line of JavaScript for not a lot of benefit.
>

Several reasons:
* The code that changes the selected item might not even be your code - it
might be in a library or other widget. The declarative approach allows you
to just decorate it with some attributes and leave the code alone.
* As a specific case of this, the developer might be using a framework like
AngularJS, Ember, or Backbone, all of which provide facilities to
dynamically bind JavaScript variables to attributes. Changing ARIA
attributes at the same time forces you to give up some of the advantages of
these frameworks, but declarative ARIA would simplify things again and let
you use pure data binding.
* If running the selector or otherwise determining the right element
requires some computation, it potentially slows down the code for all
users. A declarative selector would allow the browser to skip the
computation entirely unless accessibility is enabled.

- Dominic

Received on Wednesday, 26 March 2014 15:56:17 UTC