- 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