Re: Remaining Problems with Explicit :scope Switching in find/findAll

2011-11-27 Thread Tab Atkins Jr.
On Fri, Nov 25, 2011 at 1:08 AM, Lachlan Hunt lachlan.h...@lachy.id.au wrote:
 On 2011-11-25 03:58, Tab Atkins Jr. wrote:
 Alternately, assume that :matches() is eventually changed to allow
 complex selectors.  Using :scope there is completely fine.

 I'm not sure what you mean.  The current spec for matchesSelector does allow
 complex selectors as it's defined to accept a group of selectors
 (selectors 3 terminology), which is equivalent to a selector list (selectors
 4).  But :scope is still only useful when ref nodes are supplied.

Sorry for the confusion - note that I had a colon at the start of the
word, so I was referring to the Selector, not the function.  ^_^

~TJ



Re: Remaining Problems with Explicit :scope Switching in find/findAll

2011-11-27 Thread Tab Atkins Jr.
On Fri, Nov 25, 2011 at 1:42 PM, Sean Hogan shogu...@westnet.com.au wrote:
 On 25/11/11 5:53 AM, Yehuda Katz wrote:
 Tab Atkins wrote:
 So, the rules end up being very simple.  find always evaluates against
 the whole document.  If one of the selectors starts with a combinator
 or doesn't contain a :scope pseudoclass somewhere in it, :scope is
 prepended to it.  That's it.  With this, we make the most common cases
 (searching descendants/siblings) easy, while making the global case
 *also* easy.  There's a bit of intent-guessing when :scope is used in
 an indirect way, but I believe it's better to err on the side of
 simplicity and consistency there.

 I am ok with this, but I am also ok with find always evaluates against the
 whole document.  If one of the selectors doesn't contain a :scope
 pseudoclass somewhere in it, :scope is prepended to it.
 I also thing we agreed that filtering selectors, in the case of implicit
 scope, are applied on the :scope, not as a descendent of the :scope.
 As I said above, since the cases of starting with a combinator are nonsense
 queries (correct me if I'm missing something obvious), we can simplify the
 rules even more and eliminate the case of starting with a combinator *and*
 has a :scope

 Are you AGAINST findAll() always implying :scope at the start of each
 selector in a selector list, and leaving explicit :scope to
 querySelectorAll()?

 If so, why?

Yes, I am, for the same reason as Yehuda - I think querySelector() was
minted with subtly wrong semantics that make it overly difficult to
use, and believe that find() can replace it in all cases.  Thus, I
don't want to leave any cases to querySelector() if we can
reasonably handle them in find().

~TJ



Re: Remaining Problems with Explicit :scope Switching in find/findAll (was: Re: [Selectors API 2] Is matchesSelector stable enough to unprefix in implementations?)

2011-11-27 Thread Jonas Sicking
On Thursday, November 24, 2011, Lachlan Hunt lachlan.h...@lachy.id.au
wrote:
 On 2011-11-24 00:52, Yehuda Katz wrote:

 On Wed, Nov 23, 2011 at 2:38 PM, Sean Hoganshogu...@westnet.com.au
 wrote:

 The alternative option (find / findAll / matches can accept explicit
 :scope, but will otherwise imply :scope) seems to be where all the
 ambiguity lies.

 What exact cases are ambiguous with find/findAll/matches can accept
 explicit :scope, but will otherwise imply :scope?

 The problems to be solved with automatically switching between implied
and explicit :scope are basically in determining what exactly counts as an
explicit :scope.  The answers to each of these has is trade off between
complexity and functionality, with the simplest option being always
implying :scope.

 * Is explicit :scope allowed at the beginning of each selector?

  find(:scopediv);
  find(body.foo :scopediv);

 * Does :scope inside functional pseudo-classes count?

  find(:not(:scope));
  find(:matches(:scope));

 If yes, does the first match the whole document, only descendants, or
descendants plus siblings?

 * If using an explicit :scope, can it match itself?

  find(:scope) // Return null or the element itself?

 * Is :scope always implied if it begins with an explicit combinator other
than descendant, even if :scope is used elsewhere?
  find(div :scope);
  find(+div :scope);
  find(~div :scope);

Here is what I sent to the list on Nov 10th. Though it didn't get archived
so maybe it didn't go through properly:

1. Start with an empty list
2. Skip any whitespace at the beginning of the string.
3. If the next character is a , a + or a ~, insert a simple
selector[1] containing just the :scope pseudo selector at the
beginning of the selector.
4. Parse as a selector[1]. If there's a parse error throw an
SyntaxError exception.
5. If during parsing a :scope pseudo class was parsed, and if a
:scope pseudo selector was added in step 2, throw a SyntaxError
exception.
6. If during parsing no :scope pseudo class was parsed, and if no
:scope pseudo selector was added in step 2, add a simple selector
containing just the :scope pseudo class to the beginning of the
list, and use a descendant selector as combinator to the rest of the
selector.
7. Add selector to the end of list created in step 1.
8. If, after skipping any whitespace, the next character is a comma,
skip the comma and go to step 2.

The resulting selector list is evaluated against the document node,
but with :scope matching the node that .find/.findAll was called on.
.findAll returns all nodes which match the selector in document order.
.find returns the first node in the list of nodes that .findAll
returns, or null if the list is empty.

The reason I suggested to throw in step 5 was that such a selector would
never match anything and so must be a bug. But maybe that isn't the case
for /for/. More below.

 * There's also the general issue, not related to :scope, about how the
reference combinator affects the range of potential matches.
  label.find(/for/ input)

 Based on the above issues, what happens in this case?

  foo.find(label /for/ input+:scope~span)

Can this expression ever match anything if we prepend :scope? Would
simply removing step 5 above make the steps work for this case too?

/ Jonas


Re: Remaining Problems with Explicit :scope Switching in find/findAll

2011-11-27 Thread Lachlan Hunt

On 2011-11-27 21:29, Jonas Sicking wrote:

Here is what I sent to the list on Nov 10th. Though it didn't get archived
so maybe it didn't go through properly:
...


I'll review your algorithm and respond to that a bit later.


  foo.find(label /for/ input+:scope~span)


Can this expression ever match anything if we prepend :scope? Would
simply removing step 5 above make the steps work for this case too?


Yes.

p
  input id=x
  strong
label for=xX/label
  /strong
  span.../span
/p

var foo = document.find(strong);
foo.find(label /for/ input+:scope~span);

After prepending :scope, that will match the span element.

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



Re: Remaining Problems with Explicit :scope Switching in find/findAll

2011-11-27 Thread Jonas Sicking
On Sun, Nov 27, 2011 at 12:39 PM, Lachlan Hunt lachlan.h...@lachy.id.au wrote:
 On 2011-11-27 21:29, Jonas Sicking wrote:

 Here is what I sent to the list on Nov 10th. Though it didn't get archived
 so maybe it didn't go through properly:
 ...

 I'll review your algorithm and respond to that a bit later.

  foo.find(label /for/ input+:scope~span)

 Can this expression ever match anything if we prepend :scope? Would
 simply removing step 5 above make the steps work for this case too?

 Yes.

 p
  input id=x
  strong
    label for=xX/label
  /strong
  span.../span
 /p

 var foo = document.find(strong);
 foo.find(label /for/ input+:scope~span);

 After prepending :scope, that will match the span element.

Ok, so maybe removing step 5 from my suggested steps would work then.
Alternatively keeping them and saying that if you have a :scope in
your selector then we won't prepend one, and thus the above selector
wouldn't be valid selector syntax and thus should throw.

Either way seems like an ok solution.

The concern I have about always prepending :scope if the selector
starts with , even if :scope appears in the selector, is that it
creates different rules for the  combinator vs. the   combinator.

/ Jonas



Re: Remaining Problems with Explicit :scope Switching in find/findAll

2011-11-25 Thread Lachlan Hunt

On 2011-11-25 03:58, Tab Atkins Jr. wrote:

Alternately, assume that :matches() is eventually changed to allow
complex selectors.  Using :scope there is completely fine.


I'm not sure what you mean.  The current spec for matchesSelector does 
allow complex selectors as it's defined to accept a group of selectors 
(selectors 3 terminology), which is equivalent to a selector list 
(selectors 4).  But :scope is still only useful when ref nodes are supplied.


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



Re: Remaining Problems with Explicit :scope Switching in find/findAll

2011-11-25 Thread Sean Hogan

On 25/11/11 5:53 AM, Yehuda Katz wrote:


So, the rules end up being very simple.  find always evaluates against
the whole document.  If one of the selectors starts with a combinator
or doesn't contain a :scope pseudoclass somewhere in it, :scope is
prepended to it.  That's it.  With this, we make the most common cases
(searching descendants/siblings) easy, while making the global case
*also* easy.  There's a bit of intent-guessing when :scope is used in
an indirect way, but I believe it's better to err on the side of
simplicity and consistency there.


I am ok with this, but I am also ok with find always evaluates 
against the whole document.  If one of the selectors doesn't contain a 
:scope pseudoclass somewhere in it, :scope is prepended to it.


I also thing we agreed that filtering selectors, in the case of 
implicit scope, are applied on the :scope, not as a descendent of the 
:scope.


As I said above, since the cases of starting with a combinator are 
nonsense queries (correct me if I'm missing something obvious), we can 
simplify the rules even more and eliminate the case of starting with 
a combinator *and* has a :scope


Are you AGAINST findAll() always implying :scope at the start of each 
selector in a selector list, and leaving explicit :scope to 
querySelectorAll()?


If so, why?

Sean



Remaining Problems with Explicit :scope Switching in find/findAll (was: Re: [Selectors API 2] Is matchesSelector stable enough to unprefix in implementations?)

2011-11-24 Thread Lachlan Hunt

On 2011-11-24 00:52, Yehuda Katz wrote:

On Wed, Nov 23, 2011 at 2:38 PM, Sean Hoganshogu...@westnet.com.au  wrote:

The alternative option (find / findAll / matches can accept explicit
:scope, but will otherwise imply :scope) seems to be where all the
ambiguity lies.


What exact cases are ambiguous with find/findAll/matches can accept
explicit :scope, but will otherwise imply :scope?


The problems to be solved with automatically switching between implied 
and explicit :scope are basically in determining what exactly counts as 
an explicit :scope.  The answers to each of these has is trade off 
between complexity and functionality, with the simplest option being 
always implying :scope.


* Is explicit :scope allowed at the beginning of each selector?

  find(:scopediv);
  find(body.foo :scopediv);

* Does :scope inside functional pseudo-classes count?

  find(:not(:scope));
  find(:matches(:scope));

If yes, does the first match the whole document, only descendants, or 
descendants plus siblings?


* If using an explicit :scope, can it match itself?

  find(:scope) // Return null or the element itself?

* Is :scope always implied if it begins with an explicit combinator 
other than descendant, even if :scope is used elsewhere?

  find(div :scope);
  find(+div :scope);
  find(~div :scope);

* There's also the general issue, not related to :scope, about how the 
reference combinator affects the range of potential matches.

  label.find(/for/ input)

Based on the above issues, what happens in this case?

  foo.find(label /for/ input+:scope~span)

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



Re: Remaining Problems with Explicit :scope Switching in find/findAll (was: Re: [Selectors API 2] Is matchesSelector stable enough to unprefix in implementations?)

2011-11-24 Thread Tab Atkins Jr.
On Thu, Nov 24, 2011 at 12:50 AM, Lachlan Hunt lachlan.h...@lachy.id.au wrote:
 On 2011-11-24 00:52, Yehuda Katz wrote:

 On Wed, Nov 23, 2011 at 2:38 PM, Sean Hoganshogu...@westnet.com.au
  wrote:

 The alternative option (find / findAll / matches can accept explicit
 :scope, but will otherwise imply :scope) seems to be where all the
 ambiguity lies.

 What exact cases are ambiguous with find/findAll/matches can accept
 explicit :scope, but will otherwise imply :scope?

 The problems to be solved with automatically switching between implied and
 explicit :scope are basically in determining what exactly counts as an
 explicit :scope.  The answers to each of these has is trade off between
 complexity and functionality, with the simplest option being always implying
 :scope.

 * Is explicit :scope allowed at the beginning of each selector?

  find(:scopediv);
  find(body.foo :scopediv);

Anywhere within the selector.


 * Does :scope inside functional pseudo-classes count?

  find(:not(:scope));
  find(:matches(:scope));

 If yes, does the first match the whole document, only descendants, or
 descendants plus siblings?

Yes, I believe so.  The first matches the whole document except for
the scoping element.  The second matches only the scoping element.


 * If using an explicit :scope, can it match itself?

  find(:scope) // Return null or the element itself?

Yes, because selectors with an explicit scope are evaluated against
the whole document.  (Selectors with an implicit scope are too,
theoretically, though implementations can optimize.)  That example
returns the element itself.


 * Is :scope always implied if it begins with an explicit combinator other
 than descendant, even if :scope is used elsewhere?
  find(div :scope);
  find(+div :scope);
  find(~div :scope);

Yes.


 * There's also the general issue, not related to :scope, about how the
 reference combinator affects the range of potential matches.
  label.find(/for/ input)

 Based on the above issues, what happens in this case?

  foo.find(label /for/ input+:scope~span)

This is equivalent to prepending :scope to the selector, and
evaluating it against the whole document.  In other words, it finds a
span that is preceded by the scope which is immediately preceded by an
input which is referenced by a label which is a child of the scope.

So, the rules end up being very simple.  find always evaluates against
the whole document.  If one of the selectors starts with a combinator
or doesn't contain a :scope pseudoclass somewhere in it, :scope is
prepended to it.  That's it.  With this, we make the most common cases
(searching descendants/siblings) easy, while making the global case
*also* easy.  There's a bit of intent-guessing when :scope is used in
an indirect way, but I believe it's better to err on the side of
simplicity and consistency there.

~TJ