aom icon indicating copy to clipboard operation
aom copied to clipboard

Need to figure out what the iterable<Foo> attributes should actually be

Open bzbarsky opened this issue 8 years ago • 12 comments

Specifically, the question is what the backend storage is and what the actual return value should look like. Want to avoid two things:

  1. Having the browser's accessibility backend need to examine JS objects all the time. In other words, the setter should snapshot the incoming value somehow and that internal snapshot should be what the backend actually looks at.
  2. Having an attribute getter that returns a new object every time. This is generally considered a bad practice.

One option is to replace attributes with explicit get/set methods, where both would accept sequences. But maybe something involving FrozenArray is doable too. Really, need to figure out the right behavior and then we can figure out how to express that in IDL (possibly including changes to IDL).

//cc @cookiecrook

bzbarsky avatar Sep 21 '16 12:09 bzbarsky

I'm not following what iterable<Foo> is referring to here - could you clarify?

alice avatar Sep 22 '16 08:09 alice

This bit in http://a11y-api.github.io/a11y-api/spec/:

attribute iterable<AccessibleNode> controls;

and similar.

bzbarsky avatar Sep 22 '16 08:09 bzbarsky

Got it, thanks - so, the relationship attributes, more or less?

I had a discussion with James about this yesterday - I believe for phase 1 these should actually be Element or Node references.

@minorninth, @cookiecrook what do you think?

alice avatar Sep 22 '16 09:09 alice

If we want to eventually support a list of nodes, need to think a bit about how that evolution will happen...

bzbarsky avatar Sep 22 '16 09:09 bzbarsky

Agreed, clearly this will become more complicated in V3 when it's possible to create non-Node-backed accessibility node objects.

alice avatar Sep 22 '16 09:09 alice

Hm - perhaps we're talking at slightly cross purposes, actually.

Is your issue the choice of Array<...> rather than, e.g., NodeList?

alice avatar Sep 22 '16 09:09 alice

My issue, and to be clear it's a minor one if we're still deciding on the overall API shape, is that the IDL construct being used doesn't actually exist. I don't have any strong feelings about whether this thing should be a NodeList or an Array or something else; those are tradeoffs that depend on how this API will be used in practice and I don't have a good enough understanding of that yet to comment on it intelligently. :)

bzbarsky avatar Sep 22 '16 09:09 bzbarsky

Right, with you now, thanks! Checking into it.

alice avatar Sep 22 '16 09:09 alice

I think what we want to support here is assignment of (NodeList or Array), and make the return value FrozenArray, so these constructs could work:

n.controls = e.querySelectorAll("...")
n.controls = [a, b, c];
if (n.controls.include(a))
  return ...;

I'm not sure how we express that in webidl today, per discussion of a new syntax yesterday I think maybe:

class AccessibleNode {
   get FrozenArray<Element> controls();
   set controls((NodeList or Array) elements);
}

And then we define the snapshot behavior in the algorithm. Should there be a webidl attribute like [Snapshot] to express this?

@domenic

esprehn avatar Sep 22 '16 10:09 esprehn

@esprehn my understanding is that FrozenArray is special so that the existing syntax will already give you that behavior, i.e.

interface AccessibleNode {
  attribute FrozenArray<Element> controls;
}

The JS-value-to-WebIDL-FrozenArray will convert any iterable (including arrays and NodeLists) to a WebIDL FrozenArray. And of course converting a WebIDL FrozenArray to a JS value will give you a frozen JS array.

In this setup, it's up to the spec author to be explicit about when the FrozenArray gets reset. (That is, when accessibleNode.controls starts returning a new value.) In this case it would be any time the tree mutates---which is a bit strange, but if tree mutations are rare, I guess it's OK. The alternative is getControls/setControls methods, or maybe just getControls + other tree mutation methods (like clear, append, etc.).

domenic avatar Sep 22 '16 10:09 domenic

FrozenArray is special so that the existing syntax will already give you that behavior

Yep.

In this case it would be any time the tree mutates

My understanding is that it would only change when explicitly set; these are not the computed values but the caller-set values being exposed here.

The main issue with FrozenArray is that the thing it exposes to the browser implementation is the JS frozen Array object, per spec. But I think that gets of .length and indices from 0 to length on a frozen array with no holes are not observable in ES (@domenic is that true?). So if the specification said that UAs get the data out of the FrozenArray via getting .length and then indexing then the UA impl could in fact stash the thing it cares about into a separate list at set time and not have to worry about touching JS objects from the accessibility code and this would be black-box identical to reading from the frozen Array. This seems like a viable approach at first glance.

bzbarsky avatar Sep 22 '16 10:09 bzbarsky

One thing to note is that originally the spec/explainer made it seem like this would be a list of DOM nodes or elements, but it really should be a list of other AccessibleNodes, that makes it possible to use virtual AccessibleNodes too.

So NodeList isn't needed.

FrozenArray<AccessibleNode> sounds right if that exists.

minorninth avatar Mar 20 '17 06:03 minorninth