- 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