- From: Sean Hogan <shogun70@westnet.com.au>
- Date: Fri, 25 Sep 2009 20:07:24 +1000
- To: Lachlan Hunt <lachlan.hunt@lachy.id.au>
- CC: public-webapps <public-webapps@w3.org>
Hi Lachy,
Here's a proposal.
querySelector*(selector, context) // allows selectors with :scope
pseudo-class
queryScopedSelector*(selector, context) // allows selectors with implied
:scope
matchesSelector(selector, context) // allows selectors with :scope
pseudo-class
To check if the :scope pseudo-class is available, use:
try { document.body.matchesSelector(":scope", document.body); }
catch (error) { /* not supported */ }
OR
try { document.querySelector(":scope", document.body); }
catch (error) { /* not supported */ }
Now, querySelector*() can't accept selectors with implied :scope because
while "> em" is unambiguously ":scope > em", "p em" would become
ambiguous. (is it "p em" or ":scope p em")
So we need a new method, such as queryScopedSelector*().
element.querySelector*() limits selection to descendants of elements,
and element.queryScopedSelector*() should be consistent.
If element is the scope then element.queryScopedSelector*("~p") will
return no elements.
If we want to support sibling queries then we need to provide a scope
explicitly, so:
element.parentNode.queryScopedSelector*("~p", element);
Notes:
1. I don't think browsers should provide queryScopedSelector*()
2. I think :context is a better name than :scope
3. If the context argument of these methods could be an element or a
NodeList it might satisfy some of the other feature requests.
Lachlan Hunt wrote:
> Hi,
> I'm trying to find a suitable solution for the scoped selector
> issues, but figuring out what the most suitable API is proving
> challenging.
>
>
> *Use Cases*
>
> 1. JS libraries like JQuery and others, accept special selector
> strings beginning with combinators. e.g. ">em,+strong". These
> libraries behave as if there was a selector that matched the context
> node.
>
> e.g. In JQuery:
>
> $("+p", elm);
>
> This would select the p element that is a sibling of elm.
>
> 2. It would be useful to be able to check if an a given element
> matches a selector in relation to a specified reference element
> (:scope). For example, check if an event target is a sibling of a
> specific element, and if the parent element has a specifc class name set.
>
> e.g. Matches the selector: ".foo>:scope~input[type=text]"
>
> This may be particularly useful for event delgation.
>
> 3. Obtain a collection of elements based on their relation to more
> than one specified reference elements.
>
> e.g.
> Query to the document to obtain elements matching ":scope+span", where
> :scope is intended to match any of the elements in a specific
> collection. This would be simpler than iterating all of the nodes in
> the collection, running the query on each of them and then merging the
> results.
>
>
> *Problems*
>
> 1. Need a way to allow the browser to parse implicitly scoped
> selectors beginning with combinators and imply the presence of :scope
> before each in the group.
>
> 2. Need to allow :scope to be used within the selector strings, and
> specify one or more scope elements that will be matched by :scope.
> This needs to be useable with all of the querySelector(),
> querySelectorAll() and matchesSelector() methods, or others with
> equivalent functionality.
>
> 3. Ideally, there would be an easy, reliable way for scripts to test
> if the implementation supports scoped selectors (at least, implicitly
> scoped selectors. Those using :scope could only be discovered by
> capturing the SYNTAX_ERR exception) For legacy browsers that don't,
> they can fall back to their own selector engines.
>
>
> *Possible Solutions*
>
> 1. Define a Selector object that can be used to parse and store a
> selector, and which can handle pre-parsing the selector and
> specifying the scope elements upon creation. This selector object
> can then be passed anywhere that accepts a selector string. (This is
> basically part of the createSelector() and Selector interface
> proposal from earlier).
>
> 2. Add parameters to the querySelector(), querySelectorAll() and
> matchesSelector() methods for:
> a. Indicating whether the selectors parameter should be processed
> with an implied scope.
> b. Specifying one or more reference elements that would match :scope.
>
> 3. Create new scoped versions of the existing methods that accept one
> or more reference elements that would match the implied scope.
> Add an optional parameter to the existing querySelector*() methods
> that would Allow one or more reference elements to be specified to
> match the explicit use of :scope in the selector.
>
>
> Option 2 doesn't provide an easy way to detect browser support.
> Option 3 creates an additional queryScopedSelector*() and
> matchesScopedSelector() methods, but this could get quite verbose if
> we also add equivalent NS methods to handle the namespace issue, to
> both the scoped and non-scoped versions. This would create an
> unreasonable number of different methods that would make understanding
> the API quite complex. Option 1 is syntactically messy, and requires
> the creation of a new object just to handle a scoped selector, even if
> that selector is only used once.
>
> I'm not sure which alternative would be best, and I'm kind of hoping
> there's a 4th alternative I haven't thought of yet that can address
> the use cases easliy enough.
>
Received on Friday, 25 September 2009 10:09:28 UTC