Another attempt at solving the @page problem (issue 71)

(This fulfills my action http://wiki.csswg.org/spec/css2.1#issue-71)


Recap of the problem
====================

CSS 2.1 says in section 13.2 that @page is followed by a block of 
declarations, but the Paged Media module says that it is a mix of 
declarations and at-rules. Those two conflict. E.g., a UA implementing 
Paged Media CSS 2.1 must parse a style sheet such as

    @page { @xyz {abc} margin: 1in }

(where @xyz is a future extension) by skipping the unknown at-rule, 
yielding

    @page { margin: 1in }

A UA following CSS 2.1 must instead skip an invalid declaration, giving:

    @page {}

The following theoretical solutions exist:

 1) Change Paged Media to conform to CSS 2.1. That requires that margin
    boxes (@top, @top-left, etc.) are be declared outside @page, e.g.:

        @page { margin: 1in }
        @top { content: "Foo" }

    ADVANTAGE: This is arguably what Paged Media should have been like,
    because it matches the style of CSS (which avoids nesting as much as
    possible) and it fits the generic grammar of CSS (which is designed
    to mix rulesets and at-rules, not declarations and at-rules).

    DISADVANTAGE: There are known to be implementations already of the
    Paged Media module, since it was a CR once. Those implementations
    appear difficult to change. I know of Prince, PDFReactor, and the HP
    Deskjet 990 (although I haven't verified that last one myself).

 2) Change the error recovery rules for declaration blocks in
    section 4.2 such that an invalid declaration, if it starts with an
    at-keyword, is considered to end at a right curly brace as well as
    at a semicolon. A ruleset such as

        p {color: green; @x @y {foo} color: red}

    will then be parsed as

        p {color: green; color: red}

    instead of the currently required:

        p {color: green}

    DISADVANTAGE: It's rather ugly that different invalid tokens require
    different recovery strategies. But, more importantly, all known
    implementations will have to change. Even the UAs that implement the
    Paged Media module ignore the 'color: red' in the above example. An
    unknown number of (invalid) style sheets on the Web will change
    meaning. (Which may affect proprietary extensions as well, e.g., if
    some software defines a meaning for '@if {cond} color: red'. We
    don't like proprietary extensions, but we *did* promise this
    parsing rule as far back as the CR of 2004.)

 3) Change CSS 2.1 to conform to the Paged Media module: where it says
    that @page is followed by a declaration block, say instead that
    @page is followed by a block with both declarations and at-rules.

    ADVANTAGE: The existing implementations of Paged Media do not need
    to change.

    DISADVANTAGE: UAs that currently follow CSS 2.1 will have to change,
    viz., by applying a different grammar to @page.

    However, this only affects style sheets that were already
    unreliable, because they were parsed differently in different UAs.

In June 2009 we decided[1] for option 3, which changed, it seems, a 
decision of September 2008[2] favoring option 2. Today, option 3 still 
appears to be the only practical solution, because the cost of option 1 
is high and the cost of option 2 even higher.

[1] http://www.w3.org/blog/CSS/2009/06/23/resolutions_69
[2] http://www.w3.org/blog/CSS/2008/09/10/resolutions_36


Proposed new text
=================

I propose to implement the solution by the following concrete changes to 
the current CR text of CSS 2.1:

 a) In section 13.2[3] change

    >   An @page rule consists of the keyword "@page", followed by an
    >   optional page selector, followed by a block of declarations.

    to

    |   An @page rule consists of the keyword "@page", followed by an
    |   optional page selector, followed by a block containing
    |   declarations and at-rules.

 b) Optionally, we can add a note:

    |   Note: CSS level 2 has no at-rules that may appear inside
    |   @page, but such at-rules are expected to be defined in level 3.

    [3] http://www.w3.org/TR/2009/CR-CSS2-20090908/page.html#page-box

Furthermore, I suggest the following two enhancements to the text of 
CSS 2.1:

 c) In section 4.2[4] in the fifth bullet, change "Invalid
    at-keywords" to "At-rules with unknown at-keywords".

    Strictly speaking, this is redundant, but it helps readers.

    In fact, it is not stated with so many words, but the three bullets
    for malformed declarations, malformed statements and invalid
    at-keywords are ordered: an invalid declaration is handled by
    ignoring just the declaration; any remaining unexpected
    token in the statement is then handled by ignoring the statement;
    and finally a statement that is well-formed, but starts with an
    unknown at-keyword, is also ignored.

    Applying the bullets in a different order leads to conflicts or to
    rules that are never applied. My proposed change avoids that
    readers have to consider those different orders.

[4] 
http://www.w3.org/TR/2009/CR-CSS2-20090908/syndata.html#parsing-errors

 d) Add explicit error-recovery rules in section 13.2, just above
    13.2.1:

    |   The rules for handling malformed declarations, malformed
    |   statements, and invalid at-rules inside @page are as defined in
    |   section 4.2[link], with the following addition:
    |   when the UA expects the start of a declaration or at-rule
    |   (i.e., an IDENT token or an ATKEYWORD token) but finds an
    |   unexpected token instead, that token is considered to be
    |   the first token of a malformed declaration. I.e., the rule for
    |   malformed declarations, rather than malformed statements is used
    |   to determine which tokens to ignore in that case.

    I'm not sure if this is redundant or not. My guess is that it is
    not.



Bert
-- 
  Bert Bos                                ( W 3 C ) http://www.w3.org/
  http://www.w3.org/people/bos                               W3C/ERCIM
  bert@w3.org                             2004 Rt des Lucioles / BP 93
  +33 (0)4 92 38 76 92            06902 Sophia Antipolis Cedex, France

Received on Wednesday, 21 April 2010 09:35:25 UTC