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

2009-10-16 Thread Mike Wilson
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

2009-09-30 Thread Garrett Smith
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

2009-09-28 Thread Garrett Smith
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

2009-09-28 Thread Lachlan Hunt

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

2009-09-27 Thread Garrett Smith
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

2009-09-25 Thread Boris Zbarsky

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

2009-09-24 Thread Garrett Smith
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

2009-09-24 Thread Sean Hogan

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

2009-09-24 Thread Boris Zbarsky

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

2009-09-24 Thread Sean Hogan

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

2009-09-24 Thread Sean Hogan

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

2009-09-24 Thread Jonas Sicking
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

2009-09-24 Thread Jonas Sicking
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

2009-09-24 Thread Boris Zbarsky

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

2009-09-24 Thread John Resig
> 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

2009-09-24 Thread Jonas Sicking
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

2009-09-24 Thread Jonas Sicking
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

2009-09-24 Thread Sam Weinig


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

2009-09-24 Thread John Resig
> 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

2009-09-24 Thread Boris Zbarsky

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

2009-09-24 Thread Boris Zbarsky

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

2009-09-24 Thread Sam Weinig


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

2009-09-24 Thread Garrett Smith
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

2009-09-24 Thread Lachlan Hunt

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

2009-09-24 Thread John Resig
>
>  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

2009-09-24 Thread Lachlan Hunt

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

2009-09-24 Thread Lachlan Hunt

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

2009-09-24 Thread John Resig
> 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

2009-09-24 Thread Boris Zbarsky

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

2009-09-24 Thread Sean Hogan

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

2009-09-24 Thread Sean Hogan

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

2009-09-24 Thread Lachlan Hunt

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

2009-09-24 Thread Lachlan Hunt

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

2009-09-24 Thread Garrett Smith
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

2009-09-24 Thread Lachlan Hunt

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

2009-09-24 Thread Mike Wilson
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

2009-09-23 Thread Jonas Sicking
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

2009-09-23 Thread Maciej Stachowiak


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

2009-09-23 Thread Jonas Sicking
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

2009-09-23 Thread John Resig
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

2009-09-23 Thread Garrett Smith
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

2009-09-23 Thread Sean Hogan

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

2009-09-23 Thread Jonas Sicking
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

2009-09-23 Thread Lachlan Hunt

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

2009-09-23 Thread Mike Wilson
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

2009-09-23 Thread Lachlan Hunt

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/