W3C home > Mailing lists > Public > public-webapps@w3.org > July to September 2009

Re: [selectors-api] Summary of Feature Requests for v2

From: Lachlan Hunt <lachlan.hunt@lachy.id.au>
Date: Thu, 24 Sep 2009 10:28:27 +0200
Message-ID: <4ABB2DAB.2040604@lachy.id.au>
To: Sean Hogan <shogun70@westnet.com.au>
Cc: public-webapps <public-webapps@w3.org>, Garrett Smith <dhtmlkitchen@gmail.com>, John Resig <jresig@mozilla.com>, Jonas Sicking <jonas@sicking.cc>
Sean Hogan wrote:
> I think a couple of those features are pretty low priority:
>
> - I don't see the point of collective queries on NodeLists.
> Are there any references for the proposal?
> Otherwise I can't think of any useful queries that can't already be
> achieved with a single querySelectorAll().

It was discussed a couple of days ago in IRC.  It's based on the 
functionality provided and needed by javascript libraries.

Garrett Smith wrote:
> Lachlan Hunt wrote:
>> div2.matchesSelector(":scope~div", div1);
>
> The matching seems backwards. Should be on the matcher, instead of the
> element? I don't see the role of the element being something that does
> matching. The matching should be something left to some sort of a
> Matcher.
>
> A function to get an actual Selector object would allow the program to
> creating a cached matcher.
>
> var selector = QuerySelector.create("div.panel");
> var isPanel = selector.matches(event.target);

That's an interesting concept.  We could perhaps define something like this:

Interface DocumentSelector {
   Selector createSelector(DOMString selector, [Element scopeElement, 
[boolean impliedScope]]);
}
Interface Selector {
   boolean matches(Node element);
}

And overload the querySelector() and querySelectorAll() methods to also 
accept a Selector object as the selector parameter.

createSelector would allow the browser to parse and compile the selector 
and store it, much like createExpression does in DOM 3 XPath.  If a 
contextElement is provided, then that element is defined as the Scope 
Element that matches the :scope pseudo-class.  If impliedScope is set to 
false, the the browser treats it as an ordinary selector.  If it's set 
to true, then it's treated as an implicitly scoped selector that needs 
to be pre-parsed into a valid selector and imply the presence of :scope 
(like ">em, >strong").

A possible extension to consider would be to also allow scopeElement to 
be specified as an array or NodeList of elements, such that :scope will 
match any of the elements in the elements in the array, instead of 
limiting it to just one.

Scripts can then do this:

var selector = document.createSelector(">em,>strong", elm, true);

Or this:

var selector = document.createSelector("h1+:scope>a", [elm1, elm2, 
elm3], false);

And then pass that selector to querySelector*() like

document.querySelectorAll(selector)

And matchesSelector is handled like this:

document.createSelector("input[type=checkbox]").matches(evt.target);

John Resig wrote:
> Filtering NodeLists/StaticNodeLists, Queries on NodeLists/StaticNodeLists:
> Neither of these are useful, as is, to libraries. What is actually useful is
> the ability to run these against an array (or array-like collection) of DOM
> nodes.

I believe this would be handled using the Array.filter() method, with a 
callback that checks if the selector matches the element, as Jonas 
pointed out:

> filteredArray = myArrayOfNodes.filter(function(node) { return
> node.matchesSelector("some>selector"); });

(That could also work with the above Selector.matches() proposal)

> If I can do:
> document.querySelectorAll.call([document.getElementById("node1"),
> document.getElementById("node2")], "div > span"); then yes, this proposal is
> useful. Rarely do libraries store raw NodeLists (they need to be converted
> into an array or array-like collection first).

So this means that defining the API directly on NodeLists wouldn't 
handle the use cases dealing with arrays of elements, so the 
NodeList.querySelectorAll() idea is out.

Perhaps on the Selector interface described above, we could also define:

Interface Selector {
   boolean  matches(Node element);
   NodeList querySelector(DOMArray nodes)
   NodeList querySelectorAll(DOMArray nodes)
}

(where nodes either accepts an Array or a NodeList containing a 
collection of Document, Element or DocumentFragment nodes)

Then when these methods are run, they iteratively run querySelector() or 
querySelectorAll() on each of the nodes in the collection, using the 
selector and then return the result as a NodeList containing the union 
of unique elemenets in document order.

e.g.
var selector = document.createSelector("input");
selector.querySelectorAll([elm1, elm2, elm3]);

-- 
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/
Received on Thursday, 24 September 2009 08:29:08 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:33 GMT