Re: QSA, the problem with ":scope", and naming

On 2011-10-18 18:42, Alex Russell wrote:
> Related and equally important, that querySelector and querySelectorAll
> are often referred to by the abbreviation "QSA" suggests that its name
> is bloated and improved versions should have shorter names.

I know the names suck.  The names we ended up with certainly weren't the 
first choice of names we were going for, but sadly ended up with after a 
long drawn out naming debate and a misguided consensus poll to override 
what should have been an editorial decision.  So, if we do introduce new 
methods, personally I'd be happy to use sensible names for any them, if 
the rest of the group will allow it this time.

> I therefore believe that this group's current design for scoped
> selection could be improved significantly. If I understand the latest
> draft (http://www.w3.org/TR/selectors-api2/#the-scope-pseudo-class)
> correctly, a scoped search for multiple elements would be written as:
>
>     element.querySelectorAll(":scope>  div>  .thinger");
>
> Both then name and the need to specify ":scope" are punitive to
> readers and writers of this code. The selector is *obviously*
> happening in relationship to "element" somehow. The only sane
> relationship (from a modern JS hacker's perspective) is that it's
> where our selector starts from.

The current design is capable of handling many more use cases than the 
single use case that you are trying to optimise for here.

> Ah, but we don't need to care what CSS thinks of our DOM-only API. We
> can live and let live by building on ":scope" and specifying find* as
> syntactic sugar, defined as:
>
>    HTMLDocument.prototype.find =
>    HTMLElement.prototype.find = function(rootedSelector) {
>       return this.querySelector(":scope " + rootedSelector);
>     }
>
>     HTMLDocument.prototype.findAll =
>     HTMLElement.prototype.findAll = function(rootedSelector) {
>       return this.querySelectorAll(":scope " + rootedSelector);
>     }

This is an incomplete way of dealing with the problem, as it doesn't 
correctly handle comma separated lists of selectors, so the parsing 
problem cannot be as trivial as prepending ":scope ".  It would also 
give a strange result if the author passed an empty string

   findAll("");

   ":scope " + "" => ":scope" => meaning to return itself.

In another email, you wrote:
> The resolution I think is most natural is to split on "," and assume
> that all selectors in the list are ":scope" prefixed and that.

Simple string processing to split on "," is also ineffective as it 
doesn't correctly deal with commas within functional notation 
pseudo-classes, attribute selectors, etc.

I have attempted to address this problem before and the algorithm for 
parsing a *scoped selector string* (basically what you're calling a 
rootedSelector) existed in an old draft [1].

That draft also allowed the flexibility of including an explicit :scope 
pseudo-class in the selector, which allows for conditional expressions 
to be built into the selector itself that can be used to check the state 
of the scope element or any of its ancestors.

(But that draft isn't perfect.  It has a few known bugs in the 
definition, including one that would also make it return the context 
node itself under certain circumstances where an explicit :scope 
selector is used.)

[1] 
http://dev.w3.org/cvsweb/~checkout~/2006/webapi/selectors-api2/Overview.html?rev=1.29;content-type=text%2Fhtml#processing-selectors

-- 
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/

Received on Wednesday, 19 October 2011 12:54:39 UTC