Re: Proposal for limited :matches pseudoclass

On Wed, Jan 14, 2009 at 10:55 AM, Giovanni Campagna
<scampa.giovanni@gmail.com> wrote:
> Well, "a > b < c d < e" means an element "e" that is parent of "d",
> descendant of "c", parent of "b", child of "a"
> because b should be child of "a" and "c" at the same time, this doesn't
> match anything, but it is not difficult to read, if you read starting from
> the last token (as you do with current selectors)

As noted in an earlier email, I intended the letters to be generic
placeholders for simple selectors, but I also could have been more
clear by using "a" twice, rather than "c".  Assuming I wrote it like
that, the selector as given is still useful.  As I responded to Boris,
it is equivalent to the selector (written with my proposed syntax)
"a:matches(> b) e:matches(> d)".

> ...
> Furthermore, I'm not personally against a :matches pseudoclass (in addition
> of # placeholder) just I expected it to be "element matches selector
> contained in pseudoclass", not just element is "parent or sibling", and this
> can be very expensive at computation time (at least linear on number of
> element matching the selector without pseudoclass), while instead <, <<, -
> and -- can be optimized

Yes, from what implementors have told me (and it makes complete sense,
given my current limited knowledge of CSS engines and browser parsing)
a general matching pseudoclass that accepts any selector would be
*very* expensive.  I explicitly limited my proposal to only matching
children and adjacent siblings due to feedback from Boris in an
earlier discussion, where he said that matching only against those
would likely be reasonable enough to be implementable.

Optimizing a "<<" combinator is equivalent to optimizing
"a:matches(b)" (that is, a descendant matcher, rather than just a
child matcher).  According to feedback from Boris, it's probably not
doable.

> Frex, I expect that in selector "myancestor #my-id", first UA gets #my-id
> (only one element, found from ID map), then finds a myancestor some where in
> the tree, without travelling all the DOM: this means that fast ways to get
> from child to parent - ancestor. For siblings, the concept is similar: UAs
> already optimized +, I don't think it is much of runtime expense to use the
> same patterns but to select a different element.

I thought the same thing, but have learned that this is not the case.
There's a *reason* we have a + combinator and not a - one.  CSS
engines are optimized to work on the html stream *as it is parsed*
element-by-element.  They can do this relatively cheaply if they can
be guaranteed that determining if an element matches a rule is
dependent *only* on information that has already been parsed.  The
four current combinators respect this restriction, but <, <<, -, and
-- (or their :matches() equivalents) do not, which is why it's such a
concern, and why I restricted my own proposal so severely.  I made
sure it sat within lines that an implementor said would likely be
acceptable.

To put it another way, CSS engines do not determine matches against a
complete document.  They do so against an incomplete document as it is
streamed, and so several situations that *appear* symmetrical and easy
really are not.  This is why javascript libraries like jQuery *can*
implement complex selectors like this relatively simply and with
decent performance - by the time their matching routines run, the
entire DOM is loaded, and so they *can* exploit those symmetries.

~TJ

Received on Wednesday, 14 January 2009 19:01:27 UTC