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.
--
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/