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/

Reply via email to