[css-lists] Bug in nested counter scopes

Someone submitted a PR <https://github.com/w3c/csswg-drafts/pull/102>
to "fix" an example in the CSS2 spec.  The PR isn't right (the example
matches the similar code in the UA style sheet, and we should keep
that correspondence), but it made me realize there's probably actually
a bug in the way we deal with nested counter scopes.

First, an example:

<!DOCTYPE html>
<list><item>foo</item></list>
<list><item>foo</item></list>
<div>
 <list><item>foo</item></list>
</div>
<style>
list { display: block; counter-reset: foo; }
item { display: block; counter-increment: foo; }
item::before { content: counters(foo, ".") ". "; }
</style>

Here we clearly *intend* for a <list> to set up a counter scope for
its children.  Sibling lists should set up independent counter scopes.
This works fine in the first two, but the third <list> ends up nesting
its counter scope inside the second <list>'s!  The same occurs if you
use actual HTML and manually reference the "list-item" counter.

The problem here is that we're not careful enough in nesting scopes.
We do carefully guard against accidentally nesting inside of direct
siblings (second bullet point in
<https://drafts.csswg.org/css-lists/#create-a-new-counter>), but we
don't guard against nesting inside of counters created by preceding
cousins.

I think we should amend that section to only nest a counter if the
innermost counter was created by an ancestor; otherwise, we should
replace the innermost counter with the new counter.  This won't have
any effect on HTML's list elements, and it shouldn't have any effect
on other common use-cases like numbering all figures or headings in a
document.

Thoughts?

~TJ

Received on Thursday, 21 April 2016 17:52:59 UTC