RE: [selectors-api] Summary of Feature Requests for v2
Hi Lachlan, Another use-case for selectors, that I come across sometimes, is to be able to limit the query to first-level matches. Typically, this would be used in solutions where script wants to get the top matches, do some work that may affect the query results below these matches, then run a scoped query below each match to get the next level of matches, and so forth. Hierarchical widget expansion is an example of this. Best regards Mike Wilson Lachlan Hunt wrote on 23 september 2009: > Hi, >I'm planning to look at beginning work on Selectors API v2 soon to > add a number of requested features that didn't make it into the first > version. This e-mail is a summary of what is being > considered, and is > intended to start discussion about which ones are really > worth focussing > on, and how to ensure they address the use cases appropriately. > > > *Matches Selector* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 > > The suggestion is for being able to check if a given element > matches a > given selector. There is already similar functionality provided by > JQuery and Mozilla have begun working on an implementation for it in > Firefox. > > For the basic case, this is fairly trivial. The method just needs to > take a selector and evaluate it against the element, and > return true or > false. > > But considering the proposed :scope pseudo-class that has been > previously discussed here and in the CSS WG, it might also be nice to > check if the element matches the selector in relation to a specified > reference element. > > For example, given 2 elements, div1 and div2, you could check > if div2 is > a sibling of div1 like this: > > div2.matchesSelector(":scope~div", div1); > > In this case, the div1 would be the reference element that is > matched by > :scope. But we still need to determine how useful such functionality > would be, and whether it's worth pursuing it in this next version. > > > *Filtering NodeLists* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5864 > > The suggestion is for being able to take a NodeList, and filter the > nodes to obtain a collection of just those that match a given > selector. > > For example, being able to get a NodeList somehow, do > something with it, > and then filter it more to work with just a subset: > > e.g. > var list = document.querySelctor("div>p"); > // Do something with list, before obtaining the subset > subset = list.filterSelector(".foo"); > ... > > We need to find and document the possible use cases for this feature. > > > *Scoped Queries* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 > > This has been discussed extensively in the past. Basically, > the idea is > that the selector would be evaluated in the scope of the > element, in a > way more compatible with how libraries like JQuery work. > This slightly > different from the :scope pseudo-class proposal, see bug for details. > > > *Collective Queries on NodeLists* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=7707 > > The suggestion is to be able to run querySelector() and > querySelectorAll() on NodeList, and have the result be the union of > results in document order from running the method on each > Element in the > NodeList. > > e.g. > > list.querySelectorAll("p"); > > Would be somewhat equivalent to running > list[i].querySelectorAll("p"); > for on each element in the list, and then building an array with the > union of distinct elements from all the results. I've been told that > similar functionality for this already exists in JQuery. > > I believe the expectation is that both NodeList.querySelector() and > .querySelectorAll() would work. The difference is that > querySelector() > on a NodeList would return a NodeList (unlike on Element which just > returns a single element) containing the first matches from > each node in > the list. i.e. equivalent to running list[i].querySelector() on each > node and then combining all results into an array. > > It also seems sensible to allow the new scoped methods to be > used in an > analogous way on NodeLists. > > > *Namespace Prefix Resolution* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=6290 > > The most controversial issue of the lot. Need to clearly > document the > use cases and evaluate the problems being solved, and > determine if it's > really worth addressing in this version. > > -- > Lachlan Hunt - Opera Software > http://lachy.id.au/ > http://www.opera.com/ > >
Re: [selectors-api] Summary of Feature Requests for v2
On Fri, Sep 25, 2009 at 8:11 AM, Boris Zbarsky wrote: > On 9/25/09 1:35 AM, Garrett Smith wrote: >> >> No, you did not say it is slow. I'm saying that your laptop is >> probably a lot more powerful than a mobile device with a browser, such >> as Blackberry9000. Do you agree with that? > > Sure. It's a pretty self-evidently true claim. > It seemed like a pretty safe assumption. >>> that said, note that on a mobile device with 128 MB of RAM the RAM is a >>> lot >>> more likely to be a problem than the CPU in some ways. Running out of >>> memory is strictly worse than being a little bit slower. So a lookup >>> table >>> may be more of a loss than a win, depending. >> >> An internal cache for matchesSelector (a lookup table) would be an >> implementation detail, wouldn't it? > > Sure. Sean was just saying there probably is one already; I was saying > there isn't, along with a brief explanation of why. Thanks, I got that. You apparently objected > to part of this explanation, but at this point I'm not quite sure what your > objection was, exactly. I made two statements: > > 1) There seem to be no current parsed-selector caches in Webkit and > Gecko's querySelector implementation. > 2) On my particular hardware, parsing a particular selector in Gecko > takes approximately 5.5us. > No objection. I'm not sure what you thought I was objecting to. I wanted to point out that your year old laptop is a lot more powerful than the Blackberry browser, which has limited memory, CPU and battery resource. [...] >> The idea for QuerySelector.create is the result would be an object >> that the program could hang on to. It would not be recreated and >> garbage collected each time. > > Yes, I understand the proposal. > I never doubted that, but did want to consider garbage collection, which can also affect performance. Garrett
Re: [selectors-api] Summary of Feature Requests for v2
On Mon, Sep 28, 2009 at 2:31 AM, Lachlan Hunt wrote: > Garrett Smith wrote: >> >> On Thu, Sep 24, 2009 at 1:28 AM, Lachlan Hunt >> wrote: >>> >>> 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"). >> >> Why not use the selector text for the scope? > > I already did that 2 days ago when I dropped createSelector() and found a > way for it to work with the descendant selector. > > The spec now defines that if the selector starts with either a combinator > (>, + or ~), or an exclamation point, then it's a scoped selector, and the > processing requirements are adjusted accordingly. I also attempted to > define the processing requirements to interpret a selector like ">em" as > being equivalent to ":reference>em". > > I also defined the :reference pseudo class in the spec (formerly known as > :scope in previous discussions) to match the contextual reference elements. > http://dev.w3.org/2006/webapi/selectors-api2/#scoped-selector-string The proposal for detecting support is then try catch? As in: IS_SCOPED_SELECTOR = false; try { document.querySelector("!a"); IS_SCOPED_SELECTOR = true; } catch(ex) {} ? I don't see a form of a "createSelector" method there. Garrett
Re: [selectors-api] Summary of Feature Requests for v2
Garrett Smith wrote: On Thu, Sep 24, 2009 at 1:28 AM, Lachlan Hunt wrote: 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"). Why not use the selector text for the scope? I already did that 2 days ago when I dropped createSelector() and found a way for it to work with the descendant selector. The spec now defines that if the selector starts with either a combinator (>, + or ~), or an exclamation point, then it's a scoped selector, and the processing requirements are adjusted accordingly. I also attempted to define the processing requirements to interpret a selector like ">em" as being equivalent to ":reference>em". I also defined the :reference pseudo class in the spec (formerly known as :scope in previous discussions) to match the contextual reference elements. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 1:28 AM, Lachlan Hunt wrote: > 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"). > Why not use the selector text for the scope? > 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); > Would the boolean "impliedScope" be obvious from selector syntax to determine scope? In that way, createSelector would also allow a fair inference for feature testing the existing selectors engine. methods pretty nicely. var x = createSelector(":scope div"), IS_SCOPE_SELECTOR = x.valid; x = null; If so, the program might infer that selector syntax that passed the validity check could be used for the other selector methods. var menuItems; if(IS_SCOPE_SELECTOR) { // Get the "LI" child elements with class "menuItem" (direct, not nested). menuItems = menuList.querySelector(">.menuItem"); } else { // use hand-rolled function. menuItems = getChildNodesWithClass(menuList, "menuItem"); } This allows for: 1) effective reuse of Selector object 2) reuse of browser internal selector API code for Selector object and other selector-related methods. 3) feature detection of the implementation of supported Selector text. You also asked for a use case. Finding direct descendants, or "child elements" is not uncommon situation. The program may want to display child LI in a list, sequentially timed, and not do anything with the LI in nested UL/OL. Speaking of "child elements", there is no convenient way of getting those and it is sometimes something that a program will want to have easy access to. The issue over came up over a year and a half ago (I actually requested it). J Resig also blogged about that. Still no childElements. Why not? It should be easy to implement and it would be useful to have a widely supported "childElements" property. > 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. ECMA says the behavior of array methods is "implementation-dependent" when used with a Host object and IE throws errors. > > 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: Implementation dependent. Doesn't work in IE. Script Error: "JScript Object Expected" Garrett
Re: [selectors-api] Summary of Feature Requests for v2
On 9/25/09 1:35 AM, Garrett Smith wrote: No, you did not say it is slow. I'm saying that your laptop is probably a lot more powerful than a mobile device with a browser, such as Blackberry9000. Do you agree with that? Sure. It's a pretty self-evidently true claim. that said, note that on a mobile device with 128 MB of RAM the RAM is a lot more likely to be a problem than the CPU in some ways. Running out of memory is strictly worse than being a little bit slower. So a lookup table may be more of a loss than a win, depending. An internal cache for matchesSelector (a lookup table) would be an implementation detail, wouldn't it? Sure. Sean was just saying there probably is one already; I was saying there isn't, along with a brief explanation of why. You apparently objected to part of this explanation, but at this point I'm not quite sure what your objection was, exactly. I made two statements: 1) There seem to be no current parsed-selector caches in Webkit and Gecko's querySelector implementation. 2) On my particular hardware, parsing a particular selector in Gecko takes approximately 5.5us. Any conclusions to be drawn for other rendering engines, other selectors, or other hardware setups should be qualified appropriately (for example, Gecko on an N810 would probably end up closer to 500us for that same operation, if I recall the typical performance ratios correctly). The idea for QuerySelector.create is the result would be an object that the program could hang on to. It would not be recreated and garbage collected each time. Yes, I understand the proposal. -Boris
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 11:38 AM, Boris Zbarsky wrote: > On 9/24/09 2:17 PM, Garrett Smith wrote: >> >> On Thu, Sep 24, 2009 at 6:06 AM, Boris Zbarsky wrote: >>> >>> Gecko doesn't. Webkit doesn't. >>> >>> I just checked really quickly, and on my machine (a year-plus old laptop) >> >> That is probably many times faster, and can probably be much more >> liberal, than an optimized browser running on a mobile device with 128 >> MB RAM. > > Did I imply it's slow? I just listed approximate hardware so that the times > can be placed in some sort of context. No, you did not say it is slow. I'm saying that your laptop is probably a lot more powerful than a mobile device with a browser, such as Blackberry9000. Do you agree with that? > > that said, note that on a mobile device with 128 MB of RAM the RAM is a lot > more likely to be a problem than the CPU in some ways. Running out of > memory is strictly worse than being a little bit slower. So a lookup table > may be more of a loss than a win, depending. An internal cache for matchesSelector (a lookup table) would be an implementation detail, wouldn't it? The idea for QuerySelector.create is the result would be an object that the program could hang on to. It would not be recreated and garbage collected each time. element.matchesSelector would be recreated and collected each time. The QuerySelector puts selector-related behavior on the selector, not related to nodes. For example a match method could match a selector from a context node: selector.match( contextNode ); A hand-rolled UserPanel might want to have a delegating listener to check to see if an LI was selected from a list. So, the delegating listener would be applied to each Panel instance, checking to see when an item was selected. Garrett
Re: [selectors-api] Summary of Feature Requests for v2
Boris Zbarsky wrote: On 9/24/09 6:45 PM, Sean Hogan wrote: That is surprising. Does the CSS engine do the same? If the CSS engine doesn't store the parsed selector then it probably doesn't matter for JS calls either. In Gecko the CSS engine stores the parsed selector. In addition, it stores the selectors in various bins in a data structure to make matching faster. In practice this means that you don't have to actually match most nodes against most selectors when computing the set of rules that match a given node. This makes sense because you're guaranteed that every time a node is inserted into the DOM you will have to match it against every single one of those selectors. https://developer.mozilla.org/en/Writing_Efficient_CSS has a description of the setup. I believe Webkit has something similar. Again, I can't speak to Trident or Presto. In the querySelector(All) case, the browser has no way to know that the selector will ever be reused. In practice, the native implementations were enough faster than what they were replacing, even without any particularly fancy optimizations, that simplicity was judged more important than squeezing every bit of performance out. At least in Gecko's case. If we get to the point where they're being a bottleneck again, that will likely be revisited. Take a event-delegation system that uses matchesSelector. Every event that it handles will walk the event path trying element.matchesSelector with every registered handler. e.g. There are twenty registered click handlers and a click event occurs on an element ten levels deep. There could be 20 * 10 = 200 calls to matchesSelector. Or 400 if the system simulates capture phase as well. 200 calls would equate to ~1ms of selector parsing time in the the case of Gecko. For a click event, that's not terrible. No. It will be negligible compared to everything else that has to be done. Or take a framework that adds enhancements to HTML elements based on selectors. The framework wants to handle dynamic insertion to / removal from the page, so every DOMNodeInserted / DOMNodeRemoved (or equivalent) it will call querySelectorAll for all registered enhancements to see if there is any work to do. This could be much more of a problem. I'd want be interested in what the actual performance is like in this situation. Remember, the selector-parsing time was just the overhead; the real time usage is walking the DOM and doing the matching. For matchesSelector this is much less significant, of course, but for querySelectorAll it's likely to be the dominating factor (gut feeling; if someone wants to measure that would be welcome). I also wonder how well XBL or something like that would handle cases like this... This setup (matching every node in a subtree against a set of selectors) is really not that well served by any of the APIs described here. It's much closer to the CSS use case and would benefit from similar optimizations. XBL (and standard DOM implementations) is what we want. Note that I don't have anything against exposing "parsed selector" objects in JS. I don't think it would be that difficult to implement it. I'm just not sure whether the added complexity is really needed, and whether it's the best solution for the use cases. Maybe it is; I'm just gathering data. This is not exactly my area of expertise. -Boris Thanks for that perspective. My main concern was that we don't create parsed selectors in JS (at least not for performance reasons).
Re: [selectors-api] Summary of Feature Requests for v2
On 9/24/09 6:45 PM, Sean Hogan wrote: That is surprising. Does the CSS engine do the same? If the CSS engine doesn't store the parsed selector then it probably doesn't matter for JS calls either. In Gecko the CSS engine stores the parsed selector. In addition, it stores the selectors in various bins in a data structure to make matching faster. In practice this means that you don't have to actually match most nodes against most selectors when computing the set of rules that match a given node. This makes sense because you're guaranteed that every time a node is inserted into the DOM you will have to match it against every single one of those selectors. https://developer.mozilla.org/en/Writing_Efficient_CSS has a description of the setup. I believe Webkit has something similar. Again, I can't speak to Trident or Presto. In the querySelector(All) case, the browser has no way to know that the selector will ever be reused. In practice, the native implementations were enough faster than what they were replacing, even without any particularly fancy optimizations, that simplicity was judged more important than squeezing every bit of performance out. At least in Gecko's case. If we get to the point where they're being a bottleneck again, that will likely be revisited. Take a event-delegation system that uses matchesSelector. Every event that it handles will walk the event path trying element.matchesSelector with every registered handler. e.g. There are twenty registered click handlers and a click event occurs on an element ten levels deep. There could be 20 * 10 = 200 calls to matchesSelector. Or 400 if the system simulates capture phase as well. 200 calls would equate to ~1ms of selector parsing time in the the case of Gecko. For a click event, that's not terrible. Or take a framework that adds enhancements to HTML elements based on selectors. The framework wants to handle dynamic insertion to / removal from the page, so every DOMNodeInserted / DOMNodeRemoved (or equivalent) it will call querySelectorAll for all registered enhancements to see if there is any work to do. This could be much more of a problem. I'd want be interested in what the actual performance is like in this situation. Remember, the selector-parsing time was just the overhead; the real time usage is walking the DOM and doing the matching. For matchesSelector this is much less significant, of course, but for querySelectorAll it's likely to be the dominating factor (gut feeling; if someone wants to measure that would be welcome). I also wonder how well XBL or something like that would handle cases like this... This setup (matching every node in a subtree against a set of selectors) is really not that well served by any of the APIs described here. It's much closer to the CSS use case and would benefit from similar optimizations. Note that I don't have anything against exposing "parsed selector" objects in JS. I don't think it would be that difficult to implement it. I'm just not sure whether the added complexity is really needed, and whether it's the best solution for the use cases. Maybe it is; I'm just gathering data. This is not exactly my area of expertise. -Boris
Re: [selectors-api] Summary of Feature Requests for v2
Lachlan Hunt wrote: Mike Wilson wrote: My first priority would be "Matches Selector", and see to that it fulfills the needs for event delegation. Is there any special functionality that would be needed to achieve this? If I understand correctly, event delegation just needs to be able to check whether the event target element matches a given selector. So it would be something like: if (evt.target.matchesSelector(".foo>input.bar")) { ... } In case it isn't obvious, we may want to check every element in the event path. i.e. all ancestors of evt.target. If matchesSelector could be called with a context element then it would become a more powerful version of compareDocumentPosition(). It is also more limited because you can't do preceding-siblings. Examples I'll use the :scope pseudo-class, although :context would be a better name. elt.matchesSelector(":scope *", context); // descendant elt.matchesSelector(":scope > * *", context); // descendant but not child elt.matchesSelector(":scope ~ *", context); // following-sibling elt.matchesSelector(":scope ~ * > *", context); // nephew (child of a following-sibling) I would probably use it if it was there, but wouldn't complain if it wasn't.
Re: [selectors-api] Summary of Feature Requests for v2
Boris Zbarsky wrote: On 9/24/09 6:29 AM, Sean Hogan wrote: I would be surprised if an implementation didn't create an internal lookup table keyed off the selector text. Gecko doesn't. Webkit doesn't. I just checked really quickly, and on my machine (a year-plus old laptop) parsing the ".foo .bar .baz" selector and destroying the selector object before returning in Gecko takes about 80% of the "overhead" (that is, not walking the tree and doing selector matching) time of a querySelector() call. Or, in numbers, about 5.5us per call. Webkit's time for executing my testcase is comparable, though I can't tell how much of their time is selector parsing. That is surprising. Does the CSS engine do the same? If the CSS engine doesn't store the parsed selector then it probably doesn't matter for JS calls either. If you're doing less than 1,000 calls that involve selectors api per second, the selector-parsing time is probably not that relevant. But I don't know what the use cases are here. -Boris Take a event-delegation system that uses matchesSelector. Every event that it handles will walk the event path trying element.matchesSelector with every registered handler. e.g. There are twenty registered click handlers and a click event occurs on an element ten levels deep. There could be 20 * 10 = 200 calls to matchesSelector. Or 400 if the system simulates capture phase as well. Or take a framework that adds enhancements to HTML elements based on selectors. The framework wants to handle dynamic insertion to / removal from the page, so every DOMNodeInserted / DOMNodeRemoved (or equivalent) it will call querySelectorAll for all registered enhancements to see if there is any work to do.
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 2:41 PM, Jonas Sicking wrote: >>> > If this is how it's implemented it actually becomes really useful to >>> > have >>> > the NodeList-based element filtering. >>> > >>> > document.createNodeList([ ... some elements ... >>> > ]).filterSelector("em, >>> > strong") >>> > >>> > (Since this would be much faster than using Array.filter or some other >>> > method.) >>> >>> Are you sure that Array.filter would result in a significant perf hit? >>> What with recent jitting and stuff it would be great if we don't have >>> to rely on making everything a native method, but can rely on >>> javascript to do part of the work without taking too much of a perf >>> hit. >> >> I can guarantee that it'll be slower than doing it natively - especially so >> in Internet Explorer 8.next (the more that they do under the covers the >> faster we can provide results). > > One could argue that microsoft should just shape up and supply a > modern JS engine ;) > > In all seriousness though. It'd be nice to get data here. I'm wary of > adding APIs that are there just to work around slowness in > implementations, unless the wins are significant. Once we've added an > API we have to maintain it until the end of time, long after > performance improvements have made them obsolete. > > There's definitely cases when this makes sense to do, however it'd be > nice with data to back up that this is one of those times. Btw, i got word from our JS engine guys that using Array.map/Array.filter has bad performance behavior in firefox right now (it makes you fall off trace). So if you run any perf tests it'd probably be better not to use those functions, which is probably a good idea anyway given that I don't think they work in all browsers yet. / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 2:09 PM, John Resig wrote: > >> My concern with this API is that it forces the implementation to >> always sort the array, even if already sorted, and then do a merge >> sort on the individual results from querySelectorAll. It would be >> faster to simply run the query on each node, and then merge sort the >> results. > > That's not a huge issue - if a NodeList is coming in then we can assume that > it's already containing unique results and is in document order. It's only > if it's an array that we have to do the dance. Even in the case where the > array of results is already in document order the sort will be incredibly > fast (O(N)). Note that we'd have to do the same work that a JS implementation that uses Node.compareDocumentPosition. The only win if we have to sort is that we wouldn't be crossing the JS<->C++ bridge as much. The actual computations would be exactly the same. >> > If this is how it's implemented it actually becomes really useful to >> > have >> > the NodeList-based element filtering. >> > >> > document.createNodeList([ ... some elements ... >> > ]).filterSelector("em, >> > strong") >> > >> > (Since this would be much faster than using Array.filter or some other >> > method.) >> >> Are you sure that Array.filter would result in a significant perf hit? >> What with recent jitting and stuff it would be great if we don't have >> to rely on making everything a native method, but can rely on >> javascript to do part of the work without taking too much of a perf >> hit. > > I can guarantee that it'll be slower than doing it natively - especially so > in Internet Explorer 8.next (the more that they do under the covers the > faster we can provide results). One could argue that microsoft should just shape up and supply a modern JS engine ;) In all seriousness though. It'd be nice to get data here. I'm wary of adding APIs that are there just to work around slowness in implementations, unless the wins are significant. Once we've added an API we have to maintain it until the end of time, long after performance improvements have made them obsolete. There's definitely cases when this makes sense to do, however it'd be nice with data to back up that this is one of those times. / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
On 9/24/09 5:09 PM, John Resig wrote: It's only if it's an array that we have to do the dance. Even in the case where the array of results is already in document order the sort will be incredibly fast (O(N)). O(N) in number of nodes in the array, and that assumes that the array is not being sorted using quicksort or some such. But the "constant" here is not actually a constant. The time required to compare the DOM positions of two nodes is very much dependent on the DOM, though clearly bounded above for a given DOM. Last I checked, it's not that hard to produce situations in both Gecko and Webkit (haven't looked at the Trident and Presto source, so can't comment on those) where each such position comparison is O(N) in number of nodes in the DOM (though that usually involves having a very shallow DOM with a single node that has lots of kids). So it's not that hard to end up with O(N^2) or worse behavior for sorting an array of nodes. Of course that's true whether the sort is done in JS or in C++. But it might be worth thinking about use cases here and whether they can be addressed in ways that don't involve sorting node arrays. -Boris
Re: [selectors-api] Summary of Feature Requests for v2
> My concern with this API is that it forces the implementation to > always sort the array, even if already sorted, and then do a merge > sort on the individual results from querySelectorAll. It would be > faster to simply run the query on each node, and then merge sort the > results. > That's not a huge issue - if a NodeList is coming in then we can assume that it's already containing unique results and is in document order. It's only if it's an array that we have to do the dance. Even in the case where the array of results is already in document order the sort will be incredibly fast (O(N)). > > If this is how it's implemented it actually becomes really useful to > have > > the NodeList-based element filtering. > > > > document.createNodeList([ ... some elements ... > ]).filterSelector("em, > > strong") > > > > (Since this would be much faster than using Array.filter or some other > > method.) > > Are you sure that Array.filter would result in a significant perf hit? > What with recent jitting and stuff it would be great if we don't have > to rely on making everything a native method, but can rely on > javascript to do part of the work without taking too much of a perf > hit. > I can guarantee that it'll be slower than doing it natively - especially so in Internet Explorer 8.next (the more that they do under the covers the faster we can provide results). --John
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 8:59 AM, John Resig wrote: > Another alternative > would be to implement the merge/sort/unique method and have it return a > NodeList (which would, then, have qSA). > > For example: > document.createNodeList([ ... some elements ... ]).querySelectorAll("em, > strong"); > > createNodeList would create a NodeList holding the DOM nodes in document > order (with duplicates removed). Since it's a proper NodeList we could then > use qSA to find the elements that we want. My concern with this API is that it forces the implementation to always sort the array, even if already sorted, and then do a merge sort on the individual results from querySelectorAll. It would be faster to simply run the query on each node, and then merge sort the results. > If this is how it's implemented it actually becomes really useful to have > the NodeList-based element filtering. > > document.createNodeList([ ... some elements ... ]).filterSelector("em, > strong") > > (Since this would be much faster than using Array.filter or some other > method.) Are you sure that Array.filter would result in a significant perf hit? What with recent jitting and stuff it would be great if we don't have to rely on making everything a native method, but can rely on javascript to do part of the work without taking too much of a perf hit. / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 11:21 AM, Lachlan Hunt wrote: >>> It would be great to have a separate, standalone, function that handles these merge/sort/unique operations for collections of DOM elements (especially if they're disconnected from the document!). >>> The proposal from my previous mail falls into Option A. Would it address >>> this issue adequately? Specifically, defining document.createSelector() >>> and >>> a Selector interface that allows running a query like this: >>> >>> var elements = [...] // Some Array (or NodeList) of Elements >>> var selector = document.createSelector("em, strong"); >>> var list = selector.querySelectorAll(elements); >>> >>> This is equivalent to iterating over the elements array, running >>> elements[i].querySelectorAll("em, strong") on each, and then >>> merging/sorting >>> all of the results into a single collection. >> >> Not a huge fan of that - it seems really backwards. > > Could you elaborate? I had the same reaction as John, though quite possibly for different reasons. Currently we have an API like node.querySelector(selector). Your proposed API is selector.querySelector(node). That seems backwards compared to existing API. Quite possibly a namechange would make things better though. / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
On Sep 24, 2009, at 11:39 AM, Boris Zbarsky wrote: On 9/24/09 2:36 PM, Sam Weinig wrote: WebKit now also has an implementation of Element.matchesSelector() (we are calling ours webkitMatchesSelector for the time being). [https://bugs.webkit.org/show_bug.cgi?id=29703] Right. The Gecko one is mozMatchesSelector. I bet we'd both love to rename it... ;) Indeed. The fact that mozilla was implementing it and picked a vendor prefixed name for the time being was part of what encouraged me to implement it last night. So, thanks! -Sam
Re: [selectors-api] Summary of Feature Requests for v2
> Not quite. It depends what's being done and which steps need to be > performed and how. AIUI, there are 3 major steps involved here. > > 1. Obtain a collection of Elements. This could be in one or more > Arrays and/or NodeLists, depending on th. > 2. Iteratively execute a selector query on all elements in the > collection, saving the results from each. > 3. Merge and sort all elements into a single NodeList, removing > duplicates. > > In order to understand which of those steps need to be optimised by the > browser with new APIs, it would help if you could explain some typical > tasks, or use cases, that would need to perform any or all of those steps. > > In particular, what type of task would lead to there being more than one > Array and/or NodeList to be used as input to step 2? > var foo = document.querySelectorAll("div.foo"); // do stuff with the divs... var bar = document.querySelectorAll("div.bar"); // do stuff with the divs... var items = document.createNodeList(foo, bar).querySelectorAll("ul.items"); // do stuff with the items... Alternatively, in jQuery we would be doing something like this: var foo = $("div.foo"); // do stuff with the divs... var bar = $("div.bar"); // do stuff with the divs... var items = foo.add( bar ).find("ul.items"); // do stuff with the items... The important thing here is that: 1) There is only one sub-query being done. 2) That all the ul.items are being aggregated into a single collection, in document order. > What type of task would require executing the same selector query over a > whole collection of elements? > The most important case is where there's additional filtering being done. For example, in jQuery you can do: $("div.foo") .bind("click", function(){}) .find("span") .addClass("foo"); This reduces the total number of query operations down to two if it was possible to run it against a complete collection. > And what task would require the results of those to be merged into a single > list? The case where $("div").parents() is done, for example. This is a custom query where we return a set of ancestor elements for each of the divs. This is not something that I would expect the Selectors API to support but the case of merging those results, sorting them, and uniqueing them is taking place and is very costly. To explain what I mean, let's look at a simple DOM: $("div").parents() should return: [ html, body, div#one, div#two ] naturally if this query is being done on two elements the result set will need to be merged/sorted/uniqued before it can be returned. > It would be great to have a separate, standalone, function that handles >>> these merge/sort/unique operations for collections of DOM elements (especially if they're disconnected from the document!). The proposal from my previous mail falls into Option A. Would it >>> address >>> this issue adequately? Specifically, defining document.createSelector() >>> and >>> a Selector interface that allows running a query like this: >>> >>> var elements = [...] // Some Array (or NodeList) of Elements >>> var selector = document.createSelector("em, strong"); >>> var list = selector.querySelectorAll(elements); >>> >>> This is equivalent to iterating over the elements array, running >>> elements[i].querySelectorAll("em, strong") on each, and then >>> merging/sorting >>> all of the results into a single collection. >>> >> >> Not a huge fan of that - it seems really backwards. >> > > Could you elaborate? > Right now we have (Document|Element|DocumentFragment).querySelectorAll(selector) - this makes sense - you're going from your base root and finding sub-elements using the selector. You're proposing sticking the selector some place else and using the selector as the root, sort of, then passing the collection of elements as some sort of filter? It's completely backwards. > Another alternative would be to implement the merge/sort/unique >> method and have it return a NodeList (which would, then, have qSA). >> > > The collection of elements (step 1, above) input into the qSA step (step 2) > wouldn't need to be a sorted list. Technically, it doesn't even necessarily > have to be a merged list if the API allows multiple arrays and/or nodelists > to be provided. It will have no effect on the result. The important point > seems to be that a collection of elements can be provided somehow and that > the implementation can execute the query on each distinct element in that > collection. How exactly that is done is just an API design issue. Sure - but we can kill two birds with one API stone. Having a document.createNodeList gives us merge/sort/unique (yay!) and it makes NodeList.querySelectorAll and NodeList.matchesSelector doubly-useful (yay! - since they can now be used for normal NodeLists and for array-like collections, thanks to createNodeList). --John
Re: [selectors-api] Summary of Feature Requests for v2
On 9/24/09 2:36 PM, Sam Weinig wrote: WebKit now also has an implementation of Element.matchesSelector() (we are calling ours webkitMatchesSelector for the time being). [https://bugs.webkit.org/show_bug.cgi?id=29703] Right. The Gecko one is mozMatchesSelector. I bet we'd both love to rename it... ;) -Boris
Re: [selectors-api] Summary of Feature Requests for v2
On 9/24/09 2:17 PM, Garrett Smith wrote: On Thu, Sep 24, 2009 at 6:06 AM, Boris Zbarsky wrote: Gecko doesn't. Webkit doesn't. I just checked really quickly, and on my machine (a year-plus old laptop) That is probably many times faster, and can probably be much more liberal, than an optimized browser running on a mobile device with 128 MB RAM. Did I imply it's slow? I just listed approximate hardware so that the times can be placed in some sort of context. that said, note that on a mobile device with 128 MB of RAM the RAM is a lot more likely to be a problem than the CPU in some ways. Running out of memory is strictly worse than being a little bit slower. So a lookup table may be more of a loss than a win, depending. -Boris
Re: [selectors-api] Summary of Feature Requests for v2
On Sep 23, 2009, at 8:37 PM, Jonas Sicking wrote: On Wed, Sep 23, 2009 at 8:17 PM, John Resig wrote: Quick Summary of my opinions: Matches Selector: Super-super useful - critical, in fact. We're not able to remove jQuery's selector engine until this is implemented. I'm working with the devs at Mozilla to get an implementation landed. Already have a test suite in place. And we have a patch :) So this should be available in Firefox 3.6 I hope. WebKit now also has an implementation of Element.matchesSelector() (we are calling ours webkitMatchesSelector for the time being). [https://bugs.webkit.org/show_bug.cgi?id=29703 ] -Sam
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 6:06 AM, Boris Zbarsky wrote: > On 9/24/09 6:29 AM, Sean Hogan wrote: >> >> I would be surprised if an implementation didn't create an internal >> lookup table keyed off the selector text. > > Gecko doesn't. Webkit doesn't. > > I just checked really quickly, and on my machine (a year-plus old laptop) That is probably many times faster, and can probably be much more liberal, than an optimized browser running on a mobile device with 128 MB RAM.
Re: [selectors-api] Summary of Feature Requests for v2
John Resig wrote: So the question is, at which point in the chain do you want to address this issue? The options are: A) Have specific selectors API feauture that allowed executing a selector query on a whole collection of elements that returns a single, sorted collection of unique elements. B) A more generic API for being able to easily merge and sort NodeLists/Arrays of elements. Option A saves the step of having to run the queries on each individual element manually and just returns a merged and sorted collection of unique elements. But it's limited to running selector queries, rather than any other getElementsBy*() method to obtain the results. Option B is more generic in that it could potentially merge and sort any set of NodeLists, and those NodeLists could be obtained by any method, but would still require running the queries on each element individually to obtain the the lists that then need to be merged. B is a subset of A. You need B in order to implement A. Not quite. It depends what's being done and which steps need to be performed and how. AIUI, there are 3 major steps involved here. 1. Obtain a collection of Elements. This could be in one or more Arrays and/or NodeLists, depending on th. 2. Iteratively execute a selector query on all elements in the collection, saving the results from each. 3. Merge and sort all elements into a single NodeList, removing duplicates. In order to understand which of those steps need to be optimised by the browser with new APIs, it would help if you could explain some typical tasks, or use cases, that would need to perform any or all of those steps. In particular, what type of task would lead to there being more than one Array and/or NodeList to be used as input to step 2? What type of task would require executing the same selector query over a whole collection of elements? And what task would require the results of those to be merged into a single list? It would be great to have a separate, standalone, function that handles these merge/sort/unique operations for collections of DOM elements (especially if they're disconnected from the document!). The proposal from my previous mail falls into Option A. Would it address this issue adequately? Specifically, defining document.createSelector() and a Selector interface that allows running a query like this: var elements = [...] // Some Array (or NodeList) of Elements var selector = document.createSelector("em, strong"); var list = selector.querySelectorAll(elements); This is equivalent to iterating over the elements array, running elements[i].querySelectorAll("em, strong") on each, and then merging/sorting all of the results into a single collection. Not a huge fan of that - it seems really backwards. Could you elaborate? Another alternative would be to implement the merge/sort/unique method and have it return a NodeList (which would, then, have qSA). The collection of elements (step 1, above) input into the qSA step (step 2) wouldn't need to be a sorted list. Technically, it doesn't even necessarily have to be a merged list if the API allows multiple arrays and/or nodelists to be provided. It will have no effect on the result. The important point seems to be that a collection of elements can be provided somehow and that the implementation can execute the query on each distinct element in that collection. How exactly that is done is just an API design issue. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Re: [selectors-api] Summary of Feature Requests for v2
> > So the question is, at which point in the chain do you want to address > this issue? The options are: > > A) Have specific selectors API feauture that allowed executing a > selector query on a whole collection of elements that returns a > single, sorted collection of unique elements. > > B) A more generic API for being able to easily merge and sort > NodeLists/Arrays of elements. > > Option A saves the step of having to run the queries on each individual > element manually and just returns a merged and sorted collection of unique > elements. But it's limited to running selector queries, rather than any > other getElementsBy*() method to obtain the results. > > Option B is more generic in that it could potentially merge and sort any > set of NodeLists, and those NodeLists could be obtained by any method, but > would still require running the queries on each element individually to > obtain the the lists that then need to be merged. > > Both options present an issue with sorting, since they could result in > lists that contain both connected and disconnected elements, and the sort > order for connected elements in relation to disconnected elements would need > to be defined. > > Option B seems potentially harder to define and possibly implement, > especially if you want to be able to sort merge NodeList objects with Array > objects. Since Arrays aren't limited to just containing DOM Nodes, the > issue of what to do with other types objects and how to sort them along with > the Nodes is complicated. B is a subset of A. You need B in order to implement A. Ideally we could have both options (A for the obvious cases where you already have a NodeList and which to do another query against the results, which would be faster than manually going through the results and doing B). Whereas B is needed in its own right (as I outlined before). > It would be great to have a separate, standalone, function that handles >> these merge/sort/unique operations for collections of DOM elements >> (especially if they're disconnected from the document!). >> > > The proposal from my previous mail falls into Option A. Would it address > this issue adequately? Specifically, defining document.createSelector() and > a Selector interface that allows running a query like this: > > var elements = [...] // Some Array (or NodeList) of Elements > var selector = document.createSelector("em, strong"); > var list = selector.querySelectorAll(elements); > > This is equivalent to iterating over the elements array, running > elements[i].querySelectorAll("em, strong") on each, and then merging/sorting > all of the results into a single collection. Not a huge fan of that - it seems really backwards. Another alternative would be to implement the merge/sort/unique method and have it return a NodeList (which would, then, have qSA). For example: document.createNodeList([ ... some elements ... ]).querySelectorAll("em, strong"); createNodeList would create a NodeList holding the DOM nodes in document order (with duplicates removed). Since it's a proper NodeList we could then use qSA to find the elements that we want. If this is how it's implemented it actually becomes really useful to have the NodeList-based element filtering. document.createNodeList([ ... some elements ... ]).filterSelector("em, strong") (Since this would be much faster than using Array.filter or some other method.) > If there was a merge/sort/unique method it would drop the need for having >> a >> NodeList/Array.querySelectorAll. >> > > Whether we should go for the extra complexity required for this really > depends on the use case you're trying to address. Do you just need to merge > NodeLists that are all obtained via querySelector methods, or do you need to > merge any random NodeLists or Arrays that could be obtained via > querySelector*() or getElementsBy*(), or wherever else. The latter, absolutely. These results could be coming from anywhere - and could even be coming from non-query methods (like the aforementioned .parents() method in jQuery which does its own ancestor traversal). --John
Re: [selectors-api] Summary of Feature Requests for v2
Sean Hogan wrote: http://krijnhoetmer.nl/irc-logs/whatwg/20090922#l- I couldn't see where it was needed, only that it was possible in jQuery. I still can't think of any NodeLists that this could usefully be applied to that couldn't be achieved with a single querySelectorAll(). At least until we can create arbitrary NodeLists. It would simplify the issues that John described in his last e-mail, but the exact use cases aren't entirely clear which is making finding and determining the most appropriate solution difficult. I'm hoping John can answer this question. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Re: [selectors-api] Summary of Feature Requests for v2
John Resig wrote: Filtering NodeLists/StaticNodeLists, Queries on NodeLists/StaticNodeLists: Neither of these are useful, as is, to libraries. 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) Array.filter() will meet the need of filtering NodeLists/StaticNodeLists/Arrays of Elements - sure - but it won't meet the need of NodeList.querySelectorAll (especially if that works with an array-like collection of DOM elements). Right, but I'm dealing with that as an entirely separate issue, which I disucssed later on in that email. Basic filtering of nodelists is bug 5864, which I've resolved WONTFIX for now because the functionality doesn't seem too desirable or beneficial. http://www.w3.org/Bugs/Public/show_bug.cgi?id=5864 The issue you're discussing is bug 7707, which is still open. http://www.w3.org/Bugs/Public/show_bug.cgi?id=7707 The problem is that when you have multiple collections of DOM elements and you wish to reduce them to a single collection it ends up being a very expensive task. The steps are as follows: - The collections must be merged together into a single array of DOM elements. - The elements must be sorted to be in document order. - Duplicate elements must be removed from the collection. So the question is, at which point in the chain do you want to address this issue? The options are: A) Have specific selectors API feauture that allowed executing a selector query on a whole collection of elements that returns a single, sorted collection of unique elements. B) A more generic API for being able to easily merge and sort NodeLists/Arrays of elements. Option A saves the step of having to run the queries on each individual element manually and just returns a merged and sorted collection of unique elements. But it's limited to running selector queries, rather than any other getElementsBy*() method to obtain the results. Option B is more generic in that it could potentially merge and sort any set of NodeLists, and those NodeLists could be obtained by any method, but would still require running the queries on each element individually to obtain the the lists that then need to be merged. Both options present an issue with sorting, since they could result in lists that contain both connected and disconnected elements, and the sort order for connected elements in relation to disconnected elements would need to be defined. Option B seems potentially harder to define and possibly implement, especially if you want to be able to sort merge NodeList objects with Array objects. Since Arrays aren't limited to just containing DOM Nodes, the issue of what to do with other types objects and how to sort them along with the Nodes is complicated. It would be great to have a separate, standalone, function that handles these merge/sort/unique operations for collections of DOM elements (especially if they're disconnected from the document!). The proposal from my previous mail falls into Option A. Would it address this issue adequately? Specifically, defining document.createSelector() and a Selector interface that allows running a query like this: var elements = [...] // Some Array (or NodeList) of Elements var selector = document.createSelector("em, strong"); var list = selector.querySelectorAll(elements); This is equivalent to iterating over the elements array, running elements[i].querySelectorAll("em, strong") on each, and then merging/sorting all of the results into a single collection. If there was a merge/sort/unique method it would drop the need for having a NodeList/Array.querySelectorAll. Whether we should go for the extra complexity required for this really depends on the use case you're trying to address. Do you just need to merge NodeLists that are all obtained via querySelector methods, or do you need to merge any random NodeLists or Arrays that could be obtained via querySelector*() or getElementsBy*(), or wherever else. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Re: [selectors-api] Summary of Feature Requests for v2
> 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) > Array.filter() will meet the need of filtering NodeLists/StaticNodeLists/Arrays of Elements - sure - but it won't meet the need of NodeList.querySelectorAll (especially if that works with an array-like collection of DOM elements). The problem is that when you have multiple collections of DOM elements and you wish to reduce them to a single collection it ends up being a very expensive task. The steps are as follows: - The collections must be merged together into a single array of DOM elements. - The elements must be sorted to be in document order. - Duplicate elements must be removed from the collection. The relevant pieces of code from the Sizzle selector engine can be found here: http://github.com/jeresig/sizzle/blob/master/sizzle.js#L134 http://github.com/jeresig/sizzle/blob/master/sizzle.js#L702 As you can probably tell - those sorting functions are very, very, time-consuming - but are 100% necessary if we wish to return results in the correct order. It would be great to have a separate, standalone, function that handles these merge/sort/unique operations for collections of DOM elements (especially if they're disconnected from the document!). For example in jQuery you can do: $(".foo").parents() (this returns all ancestors of all elements that have a class of "foo") Those results must be merged/sorted/uniqued in order to be correctly returned to the user - and since .parents() (or similar) is not functionality in CSS 3 we're forced to roll our own. If there was a merge/sort/unique method it would drop the need for having a NodeList/Array.querySelectorAll. --John
Re: [selectors-api] Summary of Feature Requests for v2
On 9/24/09 6:29 AM, Sean Hogan wrote: I would be surprised if an implementation didn't create an internal lookup table keyed off the selector text. Gecko doesn't. Webkit doesn't. I just checked really quickly, and on my machine (a year-plus old laptop) parsing the ".foo .bar .baz" selector and destroying the selector object before returning in Gecko takes about 80% of the "overhead" (that is, not walking the tree and doing selector matching) time of a querySelector() call. Or, in numbers, about 5.5us per call. Webkit's time for executing my testcase is comparable, though I can't tell how much of their time is selector parsing. If you're doing less than 1,000 calls that involve selectors api per second, the selector-parsing time is probably not that relevant. But I don't know what the use cases are here. -Boris
Re: [selectors-api] Summary of Feature Requests for v2
Lachlan Hunt wrote: Lachlan Hunt wrote: 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. Sorry, I forgot to provide the link. The relevant discussion is spread out quite a bit throughout this log, beginning here. http://krijnhoetmer.nl/irc-logs/whatwg/20090922#l- I've highlighted the relevant parts. I couldn't see where it was needed, only that it was possible in jQuery. I still can't think of any NodeLists that this could usefully be applied to that couldn't be achieved with a single querySelectorAll(). At least until we can create arbitrary NodeLists.
Re: [selectors-api] Summary of Feature Requests for v2
Garrett Smith wrote: On Thu, Sep 24, 2009 at 12:02 AM, Mike Wilson wrote: Yes, the base for event delegation is certainly something like that. I just wanted to make clear that the main reason for adding this functionality (IMO) is event delegation. I'll let event delegation library creators chime in on the details on what is needed for making really efficient behavioural/delegation implementations, and judge the merits of various optimizations. There has f ex already been mention of caching "parsed" selectors. The benefit to that is that the selector text is parsed once, so something like:- document.onmouseover = function(ev) { if(ev.target.matchesSelector(".infotip")) { /*...*/ } }; could probably be made more efficient as:- var selector = QuerySelector.create(".infotip"); document.onmouseover = function(ev) { if(selector.matches(ev.target)) { /*...*/ } }; I would be surprised if an implementation didn't create an internal lookup table keyed off the selector text.
Re: [selectors-api] Summary of Feature Requests for v2
Garrett Smith wrote: QuerySelector could be extended to have properties: readonly attribute boolean valid StaticNodeList match(in HTMLElement contextNode) What's the valid property for? It seems redundant. If the selector isn't valid, then the factory method should throw an error when it tries to create it. Otherwise, it will be valid. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Re: [selectors-api] Summary of Feature Requests for v2
Lachlan Hunt wrote: 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. Sorry, I forgot to provide the link. The relevant discussion is spread out quite a bit throughout this log, beginning here. http://krijnhoetmer.nl/irc-logs/whatwg/20090922#l- I've highlighted the relevant parts. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
Re: [selectors-api] Summary of Feature Requests for v2
On Thu, Sep 24, 2009 at 12:02 AM, Mike Wilson wrote: > Yes, the base for event delegation is certainly something > like that. I just wanted to make clear that the main reason > for adding this functionality (IMO) is event delegation. > I'll let event delegation library creators chime in on the > details on what is needed for making really efficient > behavioural/delegation implementations, and judge the merits > of various optimizations. There has f ex already been mention > of caching "parsed" selectors. > The benefit to that is that the selector text is parsed once, so something like:- document.onmouseover = function(ev) { if(ev.target.matchesSelector(".infotip")) { /*...*/ } }; could probably be made more efficient as:- var selector = QuerySelector.create(".infotip"); document.onmouseover = function(ev) { if(selector.matches(ev.target)) { /*...*/ } }; The type of context where a QuerySelector object would be useful are described above. That could be abstracted to a factory pattern that uses selector to match nodes in a delegated event and lazily construct a wrapper. QuerySelector could be extended to have properties: readonly attribute boolean valid StaticNodeList match(in HTMLElement contextNode) Garrett
Re: [selectors-api] Summary of Feature Requests for v2
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/
RE: [selectors-api] Summary of Feature Requests for v2
Yes, the base for event delegation is certainly something like that. I just wanted to make clear that the main reason for adding this functionality (IMO) is event delegation. I'll let event delegation library creators chime in on the details on what is needed for making really efficient behavioural/delegation implementations, and judge the merits of various optimizations. There has f ex already been mention of caching "parsed" selectors. Best regards Mike Lachlan Hunt wrote: > Mike Wilson wrote: > > My first priority would be "Matches Selector", and see to that > > it fulfills the needs for event delegation. > > Is there any special functionality that would be needed to > achieve this? > If I understand correctly, event delegation just needs to > be able to > check whether the event target element matches a given > selector. So it > would be something like: > > if (evt.target.matchesSelector(".foo>input.bar")) { > ... > } > > -- > Lachlan Hunt - Opera Software > http://lachy.id.au/ > http://www.opera.com/ >
Re: [selectors-api] Summary of Feature Requests for v2
On Wed, Sep 23, 2009 at 9:57 PM, Maciej Stachowiak wrote: > > On Sep 23, 2009, at 5:26 PM, Jonas Sicking wrote: > >> On Wed, Sep 23, 2009 at 4:51 AM, Lachlan Hunt >> wrote: >>> >>> *Scoped Queries* >>> http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 >>> >>> This has been discussed extensively in the past. Basically, the idea is >>> that the selector would be evaluated in the scope of the element, in a >>> way >>> more compatible with how libraries like JQuery work. This slightly >>> different from the :scope pseudo-class proposal, see bug for details. >> >> Note that what makes the ">strong, >em" selector (which apparently >> some libraries support) hard to support spec-wise is that that is not >> in fact valid CSS syntax. It's certainly possible to define behavior >> for it, it's pretty clear to me how it's intended to work, but it >> would mean specifying our own syntax. >> >> However if supporting commaseparated queries is critical for libraries >> then I see no other choise. We'll one way or another have to specify >> our own syntax, though it can be heavily based on the productions in >> the Selector spec. > > I think we can define an algorithm for turning an implicitly scoped > pseudo-selector like ">strong, >em" into a proper selector using :scope -- > in this case ":scope>strong, :scope>em". We could either have an API entry > point that takes a scoped pseudo-selector, defined as transforming to a real > selector plus establishing a scope node, or just present the algorithm as an > option for libraries that want to expose pseudo-selector syntax. Indeed, it's certainly possible. I'd like to find out if we can get away with not doing that though. I'm curious to get feedback on how far just having a :scope pseudo-class gets us. / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
On Sep 23, 2009, at 5:26 PM, Jonas Sicking wrote: On Wed, Sep 23, 2009 at 4:51 AM, Lachlan Hunt > wrote: *Scoped Queries* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 This has been discussed extensively in the past. Basically, the idea is that the selector would be evaluated in the scope of the element, in a way more compatible with how libraries like JQuery work. This slightly different from the :scope pseudo-class proposal, see bug for details. Note that what makes the ">strong, >em" selector (which apparently some libraries support) hard to support spec-wise is that that is not in fact valid CSS syntax. It's certainly possible to define behavior for it, it's pretty clear to me how it's intended to work, but it would mean specifying our own syntax. However if supporting commaseparated queries is critical for libraries then I see no other choise. We'll one way or another have to specify our own syntax, though it can be heavily based on the productions in the Selector spec. I think we can define an algorithm for turning an implicitly scoped pseudo-selector like ">strong, >em" into a proper selector using :scope -- in this case ":scope>strong, :scope>em". We could either have an API entry point that takes a scoped pseudo-selector, defined as transforming to a real selector plus establishing a scope node, or just present the algorithm as an option for libraries that want to expose pseudo-selector syntax. Regards, Maciej
Re: [selectors-api] Summary of Feature Requests for v2
On Wed, Sep 23, 2009 at 8:17 PM, John Resig wrote: > Quick Summary of my opinions: > > Matches Selector: Super-super useful - critical, in fact. We're not able to > remove jQuery's selector engine until this is implemented. I'm working with > the devs at Mozilla to get an implementation landed. Already have a test > suite in place. And we have a patch :) So this should be available in Firefox 3.6 I hope. > 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. Very good input! > 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). I think filtering can easily be done using the filter function that's available in Firefox these days. Don't know what the implementation situation is for other UAs. But something like filteredArray = myArrayOfNodes.filter(function(node) { return node.matchesSelector("some>selector"); }); For "querySelectorAll on arrays" to work we'd need some function that can merge multiple nodelists. Once you have that you can easily use Array.map to get what you need. > Scoped Queries: Also critical. As it stands, in jQuery, we just punt > whenever does a query rooted to a DOM element and fallback to the old > selector engine. Does the :scope selector solve things for you? Or does it not because of selectors like "> foo, > bar", or even "foo, bar"? / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
Quick Summary of my opinions: Matches Selector: Super-super useful - critical, in fact. We're not able to remove jQuery's selector engine until this is implemented. I'm working with the devs at Mozilla to get an implementation landed. Already have a test suite in place. 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. 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). Scoped Queries: Also critical. As it stands, in jQuery, we just punt whenever does a query rooted to a DOM element and fallback to the old selector engine. Namespace Prefix Resolution: Indifferent. --John On Wed, Sep 23, 2009 at 7:51 AM, Lachlan Hunt wrote: > Hi, > I'm planning to look at beginning work on Selectors API v2 soon to add a > number of requested features that didn't make it into the first version. > This e-mail is a summary of what is being considered, and is intended to > start discussion about which ones are really worth focussing on, and how to > ensure they address the use cases appropriately. > > > *Matches Selector* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 > > The suggestion is for being able to check if a given element matches a > given selector. There is already similar functionality provided by JQuery > and Mozilla have begun working on an implementation for it in Firefox. > > For the basic case, this is fairly trivial. The method just needs to take > a selector and evaluate it against the element, and return true or false. > > But considering the proposed :scope pseudo-class that has been previously > discussed here and in the CSS WG, it might also be nice to check if the > element matches the selector in relation to a specified reference element. > > For example, given 2 elements, div1 and div2, you could check if div2 is a > sibling of div1 like this: > > div2.matchesSelector(":scope~div", div1); > > In this case, the div1 would be the reference element that is matched by > :scope. But we still need to determine how useful such functionality would > be, and whether it's worth pursuing it in this next version. > > > *Filtering NodeLists* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5864 > > The suggestion is for being able to take a NodeList, and filter the nodes > to obtain a collection of just those that match a given selector. > > For example, being able to get a NodeList somehow, do something with it, > and then filter it more to work with just a subset: > > e.g. > var list = document.querySelctor("div>p"); > // Do something with list, before obtaining the subset > subset = list.filterSelector(".foo"); > ... > > We need to find and document the possible use cases for this feature. > > > *Scoped Queries* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 > > This has been discussed extensively in the past. Basically, the idea is > that the selector would be evaluated in the scope of the element, in a way > more compatible with how libraries like JQuery work. This slightly > different from the :scope pseudo-class proposal, see bug for details. > > > *Collective Queries on NodeLists* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=7707 > > The suggestion is to be able to run querySelector() and querySelectorAll() > on NodeList, and have the result be the union of results in document order > from running the method on each Element in the NodeList. > > e.g. > > list.querySelectorAll("p"); > > Would be somewhat equivalent to running list[i].querySelectorAll("p"); for > on each element in the list, and then building an array with the union of > distinct elements from all the results. I've been told that similar > functionality for this already exists in JQuery. > > I believe the expectation is that both NodeList.querySelector() and > .querySelectorAll() would work. The difference is that querySelector() on a > NodeList would return a NodeList (unlike on Element which just returns a > single element) containing the first matches from each node in the list. > i.e. equivalent to running list[i].querySelector() on each node and then > combining all results into an array. > > It also seems sensible to allow the new scoped methods to be used in an > analogous way on NodeLists. > > > *Namespace Prefix Resolution* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=6290 > > The most controversial issue of the lot. Need to clearly document the use > cases and evaluate the problems being solved, and determine if it's really > worth addressing in this version. > > -- > Lachlan Hunt - Opera Software > http://lachy.id.au/ > http://www.opera.com/ > >
Re: [selectors-api] Summary of Feature Requests for v2
On Wed, Sep 23, 2009 at 4:51 AM, Lachlan Hunt wrote: > Hi, > I'm planning to look at beginning work on Selectors API v2 soon to add a > number of requested features that didn't make it into the first version. > This e-mail is a summary of what is being considered, and is intended to > start discussion about which ones are really worth focussing on, and how to > ensure they address the use cases appropriately. > > > *Matches Selector* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 That helps event delegation pattern. That is, adding an event handler to a container and then inspecting the event's target, to see if what the user interacted with (and what the program should do about it). This approach tends to be a much more efficient pattern than traversing through the entire document to match nodes, and then add event handler callbacks to them. The existing draft encourages less efficient programming style of traversing through the document. Pity. > > The suggestion is for being able to check if a given element matches a given > selector. There is already similar functionality provided by JQuery and > Mozilla have begun working on an implementation for it in Firefox. http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 > > For the basic case, this is fairly trivial. The method just needs to take a > selector and evaluate it against the element, and return true or false. > > But considering the proposed :scope pseudo-class that has been previously > discussed here and in the CSS WG, it might also be nice to check if the > element matches the selector in relation to a specified reference element. > > For example, given 2 elements, div1 and div2, you could check if div2 is a > sibling of div1 like this: > > 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); Garrett
Re: [selectors-api] Summary of Feature Requests for v2
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(). - Filtering NodeLists is trivial once we get matchesSelector(). Sean Lachlan Hunt wrote: Hi, I'm planning to look at beginning work on Selectors API v2 soon to add a number of requested features that didn't make it into the first version. This e-mail is a summary of what is being considered, and is intended to start discussion about which ones are really worth focussing on, and how to ensure they address the use cases appropriately. *Matches Selector* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 *Filtering NodeLists* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5864 *Scoped Queries* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 *Collective Queries on NodeLists* http://www.w3.org/Bugs/Public/show_bug.cgi?id=7707 *Namespace Prefix Resolution* http://www.w3.org/Bugs/Public/show_bug.cgi?id=6290
Re: [selectors-api] Summary of Feature Requests for v2
On Wed, Sep 23, 2009 at 4:51 AM, Lachlan Hunt wrote: > *Scoped Queries* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 > > This has been discussed extensively in the past. Basically, the idea is > that the selector would be evaluated in the scope of the element, in a way > more compatible with how libraries like JQuery work. This slightly > different from the :scope pseudo-class proposal, see bug for details. Note that what makes the ">strong, >em" selector (which apparently some libraries support) hard to support spec-wise is that that is not in fact valid CSS syntax. It's certainly possible to define behavior for it, it's pretty clear to me how it's intended to work, but it would mean specifying our own syntax. However if supporting commaseparated queries is critical for libraries then I see no other choise. We'll one way or another have to specify our own syntax, though it can be heavily based on the productions in the Selector spec. / Jonas
Re: [selectors-api] Summary of Feature Requests for v2
Mike Wilson wrote: My first priority would be "Matches Selector", and see to that it fulfills the needs for event delegation. Is there any special functionality that would be needed to achieve this? If I understand correctly, event delegation just needs to be able to check whether the event target element matches a given selector. So it would be something like: if (evt.target.matchesSelector(".foo>input.bar")) { ... } -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/
RE: [selectors-api] Summary of Feature Requests for v2
My first priority would be "Matches Selector", and see to that it fulfills the needs for event delegation. Best regards Mike Wilson Lachlan Hunt wrote: > Hi, >I'm planning to look at beginning work on Selectors API v2 soon to > add a number of requested features that didn't make it into the first > version. This e-mail is a summary of what is being > considered, and is > intended to start discussion about which ones are really > worth focussing > on, and how to ensure they address the use cases appropriately. > > > *Matches Selector* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 > > The suggestion is for being able to check if a given element > matches a > given selector. There is already similar functionality provided by > JQuery and Mozilla have begun working on an implementation for it in > Firefox. > > For the basic case, this is fairly trivial. The method just needs to > take a selector and evaluate it against the element, and > return true or > false. > > But considering the proposed :scope pseudo-class that has been > previously discussed here and in the CSS WG, it might also be nice to > check if the element matches the selector in relation to a specified > reference element. > > For example, given 2 elements, div1 and div2, you could check > if div2 is > a sibling of div1 like this: > > div2.matchesSelector(":scope~div", div1); > > In this case, the div1 would be the reference element that is > matched by > :scope. But we still need to determine how useful such functionality > would be, and whether it's worth pursuing it in this next version. > > > *Filtering NodeLists* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5864 > > The suggestion is for being able to take a NodeList, and filter the > nodes to obtain a collection of just those that match a given > selector. > > For example, being able to get a NodeList somehow, do > something with it, > and then filter it more to work with just a subset: > > e.g. > var list = document.querySelctor("div>p"); > // Do something with list, before obtaining the subset > subset = list.filterSelector(".foo"); > ... > > We need to find and document the possible use cases for this feature. > > > *Scoped Queries* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 > > This has been discussed extensively in the past. Basically, > the idea is > that the selector would be evaluated in the scope of the > element, in a > way more compatible with how libraries like JQuery work. > This slightly > different from the :scope pseudo-class proposal, see bug for details. > > > *Collective Queries on NodeLists* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=7707 > > The suggestion is to be able to run querySelector() and > querySelectorAll() on NodeList, and have the result be the union of > results in document order from running the method on each > Element in the > NodeList. > > e.g. > > list.querySelectorAll("p"); > > Would be somewhat equivalent to running > list[i].querySelectorAll("p"); > for on each element in the list, and then building an array with the > union of distinct elements from all the results. I've been told that > similar functionality for this already exists in JQuery. > > I believe the expectation is that both NodeList.querySelector() and > .querySelectorAll() would work. The difference is that > querySelector() > on a NodeList would return a NodeList (unlike on Element which just > returns a single element) containing the first matches from > each node in > the list. i.e. equivalent to running list[i].querySelector() on each > node and then combining all results into an array. > > It also seems sensible to allow the new scoped methods to be > used in an > analogous way on NodeLists. > > > *Namespace Prefix Resolution* > http://www.w3.org/Bugs/Public/show_bug.cgi?id=6290 > > The most controversial issue of the lot. Need to clearly > document the > use cases and evaluate the problems being solved, and > determine if it's > really worth addressing in this version. > > -- > Lachlan Hunt - Opera Software > http://lachy.id.au/ > http://www.opera.com/ > >
[selectors-api] Summary of Feature Requests for v2
Hi, I'm planning to look at beginning work on Selectors API v2 soon to add a number of requested features that didn't make it into the first version. This e-mail is a summary of what is being considered, and is intended to start discussion about which ones are really worth focussing on, and how to ensure they address the use cases appropriately. *Matches Selector* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5865 The suggestion is for being able to check if a given element matches a given selector. There is already similar functionality provided by JQuery and Mozilla have begun working on an implementation for it in Firefox. For the basic case, this is fairly trivial. The method just needs to take a selector and evaluate it against the element, and return true or false. But considering the proposed :scope pseudo-class that has been previously discussed here and in the CSS WG, it might also be nice to check if the element matches the selector in relation to a specified reference element. For example, given 2 elements, div1 and div2, you could check if div2 is a sibling of div1 like this: div2.matchesSelector(":scope~div", div1); In this case, the div1 would be the reference element that is matched by :scope. But we still need to determine how useful such functionality would be, and whether it's worth pursuing it in this next version. *Filtering NodeLists* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5864 The suggestion is for being able to take a NodeList, and filter the nodes to obtain a collection of just those that match a given selector. For example, being able to get a NodeList somehow, do something with it, and then filter it more to work with just a subset: e.g. var list = document.querySelctor("div>p"); // Do something with list, before obtaining the subset subset = list.filterSelector(".foo"); ... We need to find and document the possible use cases for this feature. *Scoped Queries* http://www.w3.org/Bugs/Public/show_bug.cgi?id=5860 This has been discussed extensively in the past. Basically, the idea is that the selector would be evaluated in the scope of the element, in a way more compatible with how libraries like JQuery work. This slightly different from the :scope pseudo-class proposal, see bug for details. *Collective Queries on NodeLists* http://www.w3.org/Bugs/Public/show_bug.cgi?id=7707 The suggestion is to be able to run querySelector() and querySelectorAll() on NodeList, and have the result be the union of results in document order from running the method on each Element in the NodeList. e.g. list.querySelectorAll("p"); Would be somewhat equivalent to running list[i].querySelectorAll("p"); for on each element in the list, and then building an array with the union of distinct elements from all the results. I've been told that similar functionality for this already exists in JQuery. I believe the expectation is that both NodeList.querySelector() and .querySelectorAll() would work. The difference is that querySelector() on a NodeList would return a NodeList (unlike on Element which just returns a single element) containing the first matches from each node in the list. i.e. equivalent to running list[i].querySelector() on each node and then combining all results into an array. It also seems sensible to allow the new scoped methods to be used in an analogous way on NodeLists. *Namespace Prefix Resolution* http://www.w3.org/Bugs/Public/show_bug.cgi?id=6290 The most controversial issue of the lot. Need to clearly document the use cases and evaluate the problems being solved, and determine if it's really worth addressing in this version. -- Lachlan Hunt - Opera Software http://lachy.id.au/ http://www.opera.com/