- From: Benjamin Poulain <benjamin@webkit.org>
- Date: Sun, 12 Oct 2014 22:00:09 -0700
- To: "Tab Atkins Jr." <jackalmage@gmail.com>, Benjamin Poulain <bpoulain@apple.com>
- CC: www-style list <www-style@w3.org>
On 10/11/14, 7:58 AM, Tab Atkins Jr. wrote:
> On Fri, Oct 10, 2014 at 11:31 PM, Benjamin Poulain <bpoulain@apple.com> wrote:
>> Hi,
>>
>> One problem I am interested in solving is the inability to format documents that do not have a strong hierarchical structure.
>>
>> For example, let's take:
>> <h1>Title 1</h1>
>> <h2>Subtitle</h2>
>> <p>Paragraph1</p>
>> <p>Paragraph2</p>
>> <h1>Title 2</h1>
>> <p>Paragraph3</p>
>> <p>Paragraph4</p>
>> A common use case is styling the first paragraph after a title (for example, using ::first-letter). We can try:
>> h1+p::first-letter
>> but that is too strong, it does not patch Paragraph1. We can try:
>> h1~p::first-letter
>> but that is too weak, every paragraph matches.
>>
>>
>> My current idea to solve those cases is to extend the ~ combinator to take a selector filtering the traversal. Something of the form:
>> a ~(b) c
>>
>> Traversal to find "c" would
>> 1) Evaluate "c" on a sibling.
>> 2) If [1] fails, evaluate b on the sibling.
>> 3) If [2] succeed, go to the next sibling.
>> 4) If [2] fails, fail to match.
>>
>> The use case above can be written has:
>> h1 ~(:not(h1, p)) p
>> Which is traverse from <h1> to a <p> but never skip over a <h1> or <p>.
>>
>>
>> The same principle could be used for descendant selector for generality.
>> For example, an image not in a link:
>> img:not(:any-link *)
>> can be rewritten as
>> * >>(:not(:any-link)) img
>> which is cleaner in my opinion.
> This one doesn't work - it'll match "<a><span><img></span></a>". You
> need to verify that there's no <a> ancestors at all, like ":root
Well, it looks like you already more familiar than me with the extended
combinators :)
>> Any interest?
> Thanks for bringing up this case explicitly. ^_^
>
> Okay, so it's a functional combinator somewhere between "next" and
> "general" (for both siblings and descendants), qualified with a
> selector to determine exactly what kinds of elements its allowed to
> skip over. It looks like ~(*) and >>(*) are both equivalent to the ~
> and >> combinators by themselves, yes?
Yep.
> Overall, I think I like it. I hadn't thought of actually making a
> functional combinator, so that's pretty cool. It shouldn't be too
> much of a complication of the processing model, either - when running
> selectors backwards, it just means you're checking the selector
> against the previous siblings/ancestors. It's basically just a
> helpful syntax, as you can achieve an identical effect by just
> repeating the selector multiple times, like `A + C, A + B + C, A + B +
> B + C, A + B + B + B + C, ...`.
Yep, that's the idea. It is a bit more general than that since the
number of previous sibling "filtered" is arbitrary.
> Just to throw it out, an alternate syntax might be to lean on the
> /foo/ syntax for named combinators, which would look something like
> `h1 /sibling :not(h1,p)/ p` or `:root /child :not(:any-link)/ img`. A
> benefit of this is that we no longer need to come up with *names* for
> the general forms of these combinators: if you don't pass any
> arguments, they just refer to the next child or sibling; if you want
> the general form, just pass a * argument, like `/sibling */`.
> (That'll close a comment if you don't have any whitespace between the
> * and /, but that's fine; as long as you're not in a comment, */ has
> no special meaning and is just two DELIM tokens.)
I would rather not create new names. There is value in extending the
existing concepts, people are already familiar with the syntax.
A "problem" is extending the descendant combinator, the results looks a
bit odd with the current syntax:
:root (:not(:any-link)) img
Benjamin
Received on Monday, 13 October 2014 05:01:07 UTC