- 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