[selectors3 / 4] Cross element pseudo-elements

The 8th of April has passed and the biggest issue with Selectors Level
3 (outside Unicode Normalization) that I found in the group wiki is
the handling of ::first-line. So I would like to show my proposal,
that tries to generalize the solution. Some of this probably belongs
to Selectors Level 4, though.
The problem is fundamentally that ::first-line does not select a box,
it selects a sequence of text, which may cross box boundaries. This is
the same problems we had with ::selection, for example. In fact, this
applies to ::first-line, ::last-line, ::nth-line(an+b), ::selection,
::text(regexp,n), ::first-letter, etc.

My proposal regards the processing model for "formatting
pseudo-elements" (all the above). I included some examples to make it
clearer, using ::selection because this is more likely to cross
elements, but any pseudo-element in principle can be used. I used
selectors to refer to blocks (and I assume that multiple declarations
in the same block are early collapsed)
Given
<div><p><span>some very long content </span> and some </p><p
id="important">more</p> that is not</div>
and a style of
div::selection { background-color:green; }
p::selection { color:black; }
span::selection { color:inherit; }
span { color:blue; }
p#important::selection { color:red;background-color:yellow; }

1) First, the UA must build a sequence of all content (with
white-space, content, ::before / ::after / ::marker / ::alternate
processed)
The text is "some very long content and some more that is not"
2) Secondly the UA must get the sequence of all content that matches
the pseudo-element (all content on the first line, all content
selected, all content that matches the regexp...), and split that
sequence at element boundaries
I selected "long content and some more that", splitting I get "long
content", " and some", "more", " that". Collapsed space goes in the
outer element, if in the DOM it goes in both (like
"content<space><space>and" in my example)
3) The UA must then match the pseudo-elements selectors to every box
created by that splitting. A winning pseudo-element declaration is
found for every element in the ancestor chain.
"long content" gets "color" from "span::selection" and "p::selection",
"background-color" from "div::selection"
" and some" gets "color" from "p::selection", "background-color" from
"div::selection"
"more" gets "color" from "p::selection", "p#important::selection", but
"p#important" wins over "p", so only from "p#important::selection".
"background-color" is given by both "p#important::selection" and
"div::selection"
"that" gets "background-color" from "div::selection"
4) Declarations attached to pseudo-elements whose superior parent is
deeper in the DOM win over the others.
So:
"long content" gets a Specified Value for "color" of "inherit", only
from "span::selection" because "span" is deeper than "p";
"background-color" comes only from an element, so no problems
" and some" has no conflicting declarations
"more" gets "background-color" from "p#important::selection" because
"p" is deeper than "div", "color" is not a problem, it has already
been found from step 3
"that" has no conflicting declarations
5) The Computed Values are found for the Specified Values as usual;
explicit inheritance (the inherit keyword) is from the superior-parent
of the pseudo-element that carried the winning declaration, not from
the enclosing box; for non specified properties (inherited or not),
values are found from the enclosing element or pseudo-element. The
order is
"::selection" => "::text" => "::first-letter" =>
"::nth-line()"/"::first-line"/"::last-line" => "::before / ::after /
::marker / ::inside / ::outside / ::alternate / ::scrollbar-* /
::footnote-* / DOM element"
"long content" gets "color:#0000FF", "background-color:#00FF00"; all
other properties are from the <span> in which it resides (because it
belongs to natural content, not to generated content)
" and some" gets "color:#000000;" , "background-color:#00FF00"; all
other properties are from the <p> in which it resides
"more" gets "color:#FF0000;" , "background-color:#FFFF00"; all other
properties are from the <p> in which it resides
"that" gets "background-color:#00FF00"; all other properties are from
the <div> in which it resides
6) Used Values are found as usual and the resulting inline boxes are rendered

I know, the processing is quite hard to understand, but it is the best
that I've found that solves all issues with the same text for every
pseudo-element, and allows almost every, current or future, property
(except "display" and "content", probably)
I hope that this will help somebody

Giovanni

Received on Tuesday, 14 April 2009 13:54:33 UTC