- From: Lachlan Hunt <lachlan.hunt@lachy.id.au>
- Date: Thu, 24 Sep 2009 10:28:27 +0200
- 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 UTC