- From: fantasai <fantasai@escape.com>
- Date: Sat, 04 May 2002 17:32:39 -0400
- To: www-style@w3.org
Ian Hickson wrote:
>
> fantasai wrote:
> >
> > $ and :matches()
>
> $ is this idea exactly equivalent to :subject and (...).
>
> :matches() in this idea is exactly equivalent to :matches() in my proposal,
> after moving any selectors associated with the subject of the argument out
> to the level of the :matches() pseudo, and replacing the subject with a #.
You also wrote:
> /* select all fleas if the document contains an antiflea element */
> flea:matches(antiflea)
which indicates otherwise, since in the syntax I describe that would match
exactly nothing. They are not equivalent, they are merely similar.
> > - A $ in front of a simple selector sequence indicates the subject
> > of the selector. By default the last sequence is the subject.
>
> This is unnecessary if you have my :matches().
This is unnecessary if you have either :matches(), but why should you
restrict the ability to change the subject of a selector to the argument
of the :matches() pseudo-class? If you have the ability to process it,
then let it be used outside--it simplifies the majority of the cases
where one would want to use such capabilities as we are discussing.
> > Advantages:
> >
> > 3. Can be used to to make almost any selector imaginable, so it won't
> > need to be extended with each subsequent vesion of the spec.
>
> This isn't true. If you try to convert the selectors I gave in my last post,
> you'll see that there is at least one which your syntax cannot do.
See below.
> > 4. Parsing and processing code for the main selector can be
> > reused to handle the :matches() argument.
>
> I forgot to mention this as a plus point for mine.
It's not a plus point for yours.
Taking Mozilla's code as an example--
AFAICT--and I may be wrong--Mozilla's style system matches rules to
elements by going through the tree and sending each element, one by
one, as an argument to nsStyleSet::ResolveStyleFor, a rule matching
function. A set of functions take the element data and go through
the style rules, checking the element against each rule's selector.
Suppose we have a selector like this: .section > div > code
If Mozilla is checking <p class="intro">, it will return false after
checking the 'code' part of the selector. If it's checking
<code class="css">, it will match correctly against 'code' and then
walk up the tree to <code class="css">'s parent and check that. If
the parent is a <div>, it will check the <div>'s parent to see if it
has the 'section' class.
Now, suppose we were to implement :matches() as you describe it, and
came upon flea:matches(antiflea). If the element in question matches
'flea', then we have to jump to the root of the document and scan
for antiflea. But if we had flea:matches(# antiflea), we would stay
where we are and continue exploring flea's relations--and because
we are inside a :matches pseudo, we are able to check elements _later_
in the tree.
None of this behavior applies to selectors outside the :matches()
pseudo--not even the parsing and storing of the argument, which needs
to handle # somehow. How can you say that the code for handling the
main selector could be reused for handling :matches()'s argument? The
processing has similarities, but the code for handling :matches() is
a _superset_ of the normal selector matching code.
Now, if I had a selector written like this:
.section > :matches(h1,h2,h3,h4,h5,h6) + $div > code
The <div> would be handed to the selector matching code, which would
then walk to the <div>'s previous sibling and send that to be matched
against :matches()'s argument, which, being a normal selector with no
additional rules, would be processed with the same parsing and
matching code as the main selector. It's pure recursion.
(If <div> matched against it's prior relations, the function would then
inspect its children for <code>.)
> > 6. A partial implementation of just $ will suffice for most needs.
>
> I don't really understand this.
It means, if you implement $ and leave :matches() for later, you will
take care of the majority of the needed capabilities. The variety of
selectors that can be created with just $ and without :matches() may
be limited, but they are the most-used cases.
> > 7. Reads better: .section > $div > code
>
> .section > div:has( > code)
>
> I don't see that the dollar sign is any more understandable.
It's not the dollar sign. It's the fact that the whole path through
the tree is on one level.
.section > div
|--:has( > code)
vs.
.section > div > code
Have you ever done grammar exercises where you break down and diagram a
sentence? The idea is similar to that. To express "'div' who's parent is
a '.section' and who has a child 'code'" using the $ syntax, you create
a compound "sentence" (selector). Both "clauses" are at the same level.
With your :matches() syntax, the second clause is subordinate to the
first, as you can see by the parentheses that surround it.
> > One can see the selector as mapping unbroken path through the
> > tree, branching only when selectors _need_ to branch off.
> > .section > :matches(h1,h2,h3,h4,h5,h6) + $div > code
>
> I really don't understand what you mean by that. It sounds like an
> advantage which also applies to my suggestion, though.
If you don't understand what it means, you should avoid making assuptions
about it. I actually put that point in specifically to contrast with your
suggestion.
Look at this selector:
.section > :matches(h1,h2,h3,h4,h5,h6) + $div > code
If you visually group each sequence of simple selectors into a generic box,
you can easily see the entire pattern we are trying to match:
[1] > [2] + {3} > [4]
^
The pattern only branches off through the :matches() pseudo if it's necessary
(i.e. you have two or more right-side patterns to match against) or if one,
as the author, prefers to read it that way. In your model, it always branches
off.
> You forgot the following disadvantages:
>
> 1. Changes one of the basic concepts of CSS, that the subject of the
> selector is the last simple selector in the chain.
>
> 2. Can only have one description on the right hand side, unless you
> use the :matches() form, at which point the dollar syntax is
> redundant.
>
> 3. removes the potential use of a dollar sign from the language for
> future extensions.
>
> 4. Ambiguous: what does it mean if there are two $s in a selector?
It means the selector is invalid.
I think the reason you put that in for :subject was because there was no way
to handle multiple reverse relationships, and if you tried by using :subject
twice, you'd wind up with an ambiguous, undefined selector.
> 5. Can't describe everything.
> /* select all fleas if the document contains an antiflea element */
> /* can't be done */
flea antiflea,
:root:matches(antiflea, $ antiflea) flea,
No, it's not quite as simple as specifying an equivalent selector in
your syntax, but it's not that bad, and it's also a very rare case.
Also, reading flea:matches(antiflea)--just _reading_ it--in no way
seems to indicate the meaning you assign to it, whereas using the
syntax I describe, you can always read the selector literally.
> [1] this proposal allows for impossible selectors which are not possible
> using my :matches() form. For example:
>
> $foo:matches($bar)
>
> ...can never match. These cannot be converted to the :matches() form.
And because of this, it allows you to write
.section > :matches(h1,h2,h3,h4,h5,h6) + div
which, as you have said, cannot be converted into your :matches() form.
Note that it is not only easier to write than specifying all six
variations in full, but it is more efficient--you only match against
the div once, instead of six times.
~fantasai
Received on Saturday, 4 May 2002 17:29:06 UTC