On 2012-06-20 17:46, Marat Tanalin | tanalin.com wrote:
20.06.2012, 18:14, "Lachlan Hunt" <lachlan.h...@lachy.id.au>:
4. Support for returning elements that are not descendants of the
     context object.

This feature allows a selector to be constructed such that it matches an
element anywhere in the tree relative to the context element. This
feature is not relevant to document.find(), since it can already return
anything from the whole tree.

    elm.find("+span")        // span is a sibling
    elm.find("/for/ input")  // input could be anywhere
    elm.find(":not(:scope)") // Everything except the context object

This feature cannot be supported on Element.qSA, even when using eplicit
:scope, because matching elements need to be descendants of the context
object.

It's unclear why an _updated_ qSA version should have same limitation
that "matching elements need to be descendants of the context
object". There is nothing obvious that makes h1.querySelector('+ H2')
impossible to work in newer implementations (in older ones it would
not work anyway -- to the same extent as `elm.querySelector(">span")`
that you've declared as "could work").

Supporting this without the risk of breaking compatibility would require switching selection behaviour based on the presence of the :scope pseudo class (either explicit or implied), for each individual selector in the group. When :scope is present, then matching could be applied to the entire tree, just like it is in element.find().

That is, given the group of selectors:

  elm.querySelectorAll(":scope+p, div p")

(Note: After pre-processing, there is no difference between explicit :scope and implied :scope in "+p")

Only ":scope+p" would be permitted to match non-descendant elements and the other "div p" would have to retain the backwards compatible selection behaviour where the subject of the selector must be a descendant of the context object.

That means, the implementation would need to split the group of selectors such that ":scope+p" (or any other selector with explicit or implied :scope) is potentially compared with all elements in the tree. Then the other selector "div p" should only be compared with descendants of the context object.

It will also not work for the reference combinator in some cases. If switching selection behaviour depends on the presence of :scope, then the reference combinator will not always work effectively.

  elm.querySelectorAll("label /for/ input")

In this case with no :scope, the matching input must be a descendant of the context object, but the label may or may not be. Compare that with this:

  elm.findAll("label /for/ input")

In this case, :scope is implied at the beginning, so the label must be a descendant of the context object, but the matching input elements may appear anywhere in the tree.

Overall, this adds significant complexity to the implementations, so while it may actually be technically possible in some cases, it's far from ideal and doesn't address all problems.

--
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/

Reply via email to