W3C home > Mailing lists > Public > www-style@w3.org > July 2008

Re: Opera's Proposal for :context Selector

From: Lachlan Hunt <lachlan.hunt@lachy.id.au>
Date: Fri, 11 Jul 2008 09:01:24 +0200
Message-ID: <48770544.4070808@lachy.id.au>
To: Andrew Fedoniouk <news@terrainformatica.com>
Cc: www-style <www-style@w3.org>

Andrew Fedoniouk wrote:
> Lachlan Hunt wrote:
>> i.e. Consider the following fragment:
>>
>> <body>
>>   <section id="foo">
>>     <div>
>>       ...
>>     </div>
>>   </section>
>> </body>
>>
>> foo.querySelector("body div");
>>
>> As currently defined and as it is being implemented by browsers, that 
>> would match and return the above div element.  This is because the 
>> Selectors spec defines whether or not a given element matches a 
>> particular element, and the API does not redefine that.
> 
> If there are such implementations that have
> querySelector(); implemented for arbitrary DOM elements then
> without :context/:root they are barely useful.

No implementations have shipped yet, but the API is implemented in 
recent betas, nightlies or experimental builds of the browsers.

>> If :root were redefined as you suggest, then so would this would need 
>> to as well:
>>
>> foo.querySelector("body :root div");
> 
> No. That is invalid selector. :root can only be defined for the very 
> first element of the selector. Otherwise it makes no sense - will always 
> be false.

Yes, I know :root can only be the first element, which is why I'm saying 
it can't be used in this case!

>> (Note that will in fact work with the :context selector in place of 
>> :root.)
> 
> foo.querySelector("body :context div");
> 
> That is very ineffective selector.

In that particular case, yes, it's entirely redundant.  But consider 
this case:

foo.querySelectorAll(".foo :context>.xxx, .bar :context>.yyy");

It allows you to select different child elements based on the parent or 
other ancestor element.

> Say you have N children of the element. Then for all N children
> you will execute the same testing sequence "body :context".
> 
> In fact such things should be just disallowed.
> 
> If you really need such a selector then you should write it as:
> 
> var div = self.selectParent("body")? self.selectChild("div"):null;
> 
> this will be the most effective way of doing
>   foo.querySelector("body :context div");

Why are 2 function calls more efficient than a single function call that 
is already compatible with the spec and implementations (pending support 
for :context)?

> I've already implemented style-set's [1] that are such scoped style 
> sheets (but defined purely in CSS). We have more than a year of real 
> experience of using scoped style systems.

It appears that your style sets were designed to meet different use 
cases from scoped stylesheets in HTML5.
> jQuery allows you to write:
> 
> $(this).parent("ul.collapsible")
> 
> See: http://docs.jquery.com/Traversing/parent#expr

That page doesn't offer any examples or use cases for why the expression 
is useful.  But at least that is some evidence to support your request 
and could be something worth considering for version 2 of the spec.  But 
it is orthogonal to the :context selector issue being discussed here, 
and so I won't discuss it further in this thread.

> Moreover: minimal set of selector operations that is needed
> for good native support of jQuery contains these three functions:
> 
> element.selectChild(selector[, callback]);
> element.selectParent(selector[, callback]);
> element.matches(selector);

The matches() function has been considered before and could possibly be 
introduced in version 2, but the use cases need to be investigated first.

> Too bad. That is one of reasons why JS based solutions are slow. Slow by 
> design.
> 
> Write function that contains something like this
>   elem.querySelector("*").length
> and you can name it as JoyOfGarbageCollector().

The API was designed to allow scripts to obtain a collection of elements 
that they actually want to do something with.  I agree, it's not optimal 
if you only wish to count the number of matching elements and then 
discard the list, but then I'm not sure why such information would be 
useful on its own.  The typical case for getting the length of a list is 
for iteration, in which case the elements themselves are usually used 
within the loop anyway.  But again, this is orthogonal to the issue at hand.

-- 
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/
Received on Friday, 11 July 2008 07:02:09 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:10 GMT