New issue
Advanced search Search tips

Issue 659297 link

Starred by 4 users

Issue metadata

Status: Fixed
Owner:
Closed: Mar 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 2
Type: Bug
M56

Blocking:
issue 661174



Sign in to add a comment

CSSOM rewrites CSS 'page-break-after' as 'break-after'

Project Member Reported by tflo@google.com, Oct 25 2016

Issue description

UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

Steps to reproduce the problem:
Repro example:

var s = document.createElement('span');
s.innerHTML = '<div style="page-break-after:always;"></div>';  // Outputs "<div style="page-break-after:always;"></div>"
s.children[0].outerHTML;  // Outputs "<div style="page-break-after:always;"></div>"
s.children[0].style.cssText;  // Outputs "break-after: page;"
s.children[0].style.pageBreakAfter;  // Outputs ""
s.children[0].style.breakAfter;   // Outputs "page"

What is the expected behavior?
cssText is unchanged.  pageBreakAfter is an available CSS style property

What went wrong?
When parsing HTML with inline CSS, the DOM rewrites the "page-break-after" sytle rule in terms of "break-after".

This is exercised via https://github.com/google/closure-library/blob/master/closure/goog/html/sanitizer/htmlsanitizer.js (see goog.html.sanitizer.HtmlSanitizer.getDomTreeWalker_).

That above example will be re-written as:
  <div style="break-after: page;"></div>

This is a problem because com.google.common.html.sanitizer.css.StyleFilter.SAFE_PROPERTIES doesn't allow "break-after" as a style property ("page-break-after" is allowed).

The best "workaround" I can come up for this is after the sanitization takes place:
  html = html.replace(/break-after:\s*page;/g, 'page-break-after:always;');

Did this work before? N/A 

Does this work in other browsers? N/A

Chrome version: 54.0.2840.71  Channel: stable
OS Version: 
Flash Version: Shockwave Flash 23.0 r0
 

Comment 1 by tkent@chromium.org, Oct 25 2016

Components: -Blink>DOM Blink>CSS
Summary: CSSOM rewrites CSS 'page-break-after' as 'break-after' (was: DOM rewrites CSS 'page-break-after' as 'break-after')

Comment 2 by tflo@google.com, Oct 25 2016

This is also true for the other page-break- variants.

Comment 3 by tflo@google.com, Oct 25 2016

Here's the full CSSOM rewrite for all possible values of the page-break- variants:

"page-break-after: auto;"      "break-after: auto;"
"page-break-after: always;"    "break-after: page;"
"page-break-after: avoid;"     "break-after: avoid;"
"page-break-after: left;"      "break-after: left;"
"page-break-after: right;"     "break-after: right;"
"page-break-after: recto;"     ""
"page-break-after: verso;"     ""
"page-break-after: inherit;"   "break-after: inherit;"
"page-break-after: initial;"   "break-after: initial;"
"page-break-after: unset;"     "break-after: unset;"

"page-break-before: auto;"     "break-before: auto;"
"page-break-before: always;"   "break-before: page;"
"page-break-before: avoid;"    "break-before: avoid;"
"page-break-before: left;"     "break-before: left;"
"page-break-before: right;"    "break-before: right;"
"page-break-before: recto;"    ""
"page-break-before: verso;"    ""
"page-break-before: inherit;"  "break-before: inherit;"
"page-break-before: initial;"  "break-before: initial;"
"page-break-before: unset;"    "break-before: unset;"

"page-break-inside: auto;"     "break-inside: auto;"
"page-break-inside: avoid;"    "break-inside: avoid;"
"page-break-inside: inherit;"  "break-inside: inherit;"
"page-break-inside: initial;"  "break-inside: initial;"
"page-break-inside: unset;"    "break-inside: unset;"


This was based on sanitizing the following HTML:

<div style="page-break-after: auto;"></div>
<div style="page-break-after: always;"></div>
<div style="page-break-after: avoid;"></div>
<div style="page-break-after: left;"></div>
<div style="page-break-after: right;"></div>
<div style="page-break-after: recto;"></div>
<div style="page-break-after: verso;"></div>
<div style="page-break-after: inherit;"></div>
<div style="page-break-after: initial;"></div>
<div style="page-break-after: unset;"></div>

<div style="page-break-before: auto;"></div>
<div style="page-break-before: always;"></div>
<div style="page-break-before: avoid;"></div>
<div style="page-break-before: left;"></div>
<div style="page-break-before: right;"></div>
<div style="page-break-before: recto;"></div>
<div style="page-break-before: verso;"></div>
<div style="page-break-before: inherit;"></div>
<div style="page-break-before: initial;"></div>
<div style="page-break-before: unset;"></div>

<div style="page-break-inside: auto;"></div>
<div style="page-break-inside: avoid;"></div>
<div style="page-break-inside: inherit;"></div>
<div style="page-break-inside: initial;"></div>
<div style="page-break-inside: unset;"></div>


Which became:

<div style="break-after: auto;"></div>
<div style="break-after: page;"></div>
<div style="break-after: avoid;"></div>
<div style="break-after: left;"></div>
<div style="break-after: right;"></div>
<div></div>
<div></div>
<div style="break-after: inherit;"></div>
<div style="break-after: initial;"></div>
<div style="break-after: unset;"></div>

<div style="break-before: auto;"></div>
<div style="break-before: page;"></div>
<div style="break-before: avoid;"></div>
<div style="break-before: left;"></div>
<div style="break-before: right;"></div>
<div></div>
<div></div>
<div style="break-before: inherit;"></div>
<div style="break-before: initial;"></div>
<div style="break-before: unset;"></div>

<div style="break-inside: auto;"></div>
<div style="break-inside: avoid;"></div>
<div style="break-inside: inherit;"></div>
<div style="break-inside: initial;"></div>
<div style="break-inside: unset;"></div>
Labels: Needs-Bisect M-54
Would you mind providing a sample html page for ease of triaging?

Comment 5 by timloh@chromium.org, Oct 25 2016

Cc: kojii@chromium.org
AFAICT this is mostly WAI since page-* are aliases, except that e.style.pageBreakAfter shouldn't be empty. Probably the StylePropertySerializer needs to be updated to support these.

https://drafts.csswg.org/css-break/#page-break-properties

Comment 6 by kojii@chromium.org, Oct 26 2016

tflo@:
> This is a problem because com.google.common.html.sanitizer.css.StyleFilter.SAFE_PROPERTIES doesn't allow "break-after" as a style property ("page-break-after" is allowed).

I think the best way forward is to fix the sanitizer. The "break-after" property is already in Candidate Recommendation, I don't see any good reasons to reject the use of it.

https://www.w3.org/TR/css-break-3/

Did you file a bug to the sanitizer?
Labels: Needs-Feedback
tflo@: Could you please provide us the sample html file for further triaging the issue.

Thanks.

Comment 8 by tflo@google.com, Oct 26 2016

I'm not on the same time as you guys :)


jmukthavaram@chromium.org, ligimole@chromium.org:
Here's a test bed.  It demonstrates the actual CSS style, the reported cssText, and which style properties are set.

https://jsfiddle.net/b1dnzohp/
https://fiddle.jshell.net/b1dnzohp/show/light/ (Result view)



kojii@chromium.org, timloh@chromium.org:
I actually submitted a patch to allow the break-* properties but I reverted it as the browser compatability for those properties are so low:

https://developer.mozilla.org/en-US/docs/Web/CSS/break-after#Browser_compatibility
https://developer.mozilla.org/en-US/docs/Web/CSS/break-before#Browser_compatibility
https://developer.mozilla.org/en-US/docs/Web/CSS/break-inside#Browser_compatibility

Perhaps those compatability tables need to be updated?

Comment 9 by tflo@google.com, Oct 26 2016

Some more links:

FireFox results for comparison (HTML result only):
https://fiddle.jshell.net/z8658f54/1/show/light/

Updated test that works on FireFox:
https://fiddle.jshell.net/b1dnzohp/1/show/light/

I would say that FireFox's results are more "as expected" than Chrome's.
Labels: -Needs-Feedback -Needs-Bisect M56 OS-Mac OS-Windows
Status: Untriaged (was: Unconfirmed)

Able to reproduce the issue on windows 7,Mac 10.11.4,Ubuntu 14.04 using chrome reported version #54.0.2840.71 & latest canary #56.0.2906.0.

This is a non regression as it is observed from M52 to latest canary & same feature not available from M45,M50 & M51 old builds.

Hence, marking it as Untriaged to get more inputs from dev team.

Thanks,
Status: Available (was: Untriaged)
Labels: Hotlist-Interop
Blocking: 661174
I have also observed this behavior, but in a different context.

To reproduce:
var s = document.createElement('span');

s.style.pageBreakAfter = 'always';

console.log('s.style.pageBreakAfter: ', s.style.pageBreakAfter);
console.log('s.style.breakAfter: ', s.style.breakAfter);

Here is a link to a codepen:
http://codepen.io/aljachimiak/pen/PbrRao?editors=0011

Open in Chrome and you'll find that s.pageBreakAfter is an empty string.
Open in FireFox and you'll find that s.pageBreakAfter is 'always'.


The problem here is then when I explicitly set a property, I expect it to be set.

I kind of like that the equivalent property is being set for future spec support.


My opinion is that the property that is explicitly set in js, should ALWAYS be set.  It's okay to set another equivalent property.


My use case here is that we are sending the rendered html to a server side printer that doesn't support `break-before` yet.


Note:
If you've got jQuery on your page this actually worke:
$(elem).css('page-break-before', 'always');


Thanks for your time and attention!

- Al
> Note:
> If you've got jQuery on your page this actually works:
> $(elem).css('page-break-before', 'always');

Nope - I was not in Chrome when I tried this.  Sorry for the false hope.
Cc: amoylan@chromium.org
Labels: Update-Quarterly

Comment 18 by meade@chromium.org, Oct 31 2017

Labels: ApproachableBug Code-Parser Code-Serialization
Labels: -Update-Quarterly
Project Member

Comment 20 by bugdroid1@chromium.org, Mar 12 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/da3d4e26aef179e83366f6efafb66e54676066ed

commit da3d4e26aef179e83366f6efafb66e54676066ed
Author: Chris Nardi <cnardi@chromium.org>
Date: Mon Mar 12 11:54:42 2018

[cssom] Allow accessing page-break-* properties through style

We internally represent all page-break-* properties as shorthands for
break-* properties, per the spec [1]. However, we do not check this on
serialization, meaning style.pageBreak* is always "". Add logic into
StylePropertySerializer to check for the page break shorthands.

[1]: https://drafts.csswg.org/css-break/#page-break-properties

Bug:  659297 
Change-Id: Id8fc71f7f279d474f39ce37fbd3ad7791e1b40c7
Reviewed-on: https://chromium-review.googlesource.com/957836
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Chris Nardi <cnardi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542463}
[modify] https://crrev.com/da3d4e26aef179e83366f6efafb66e54676066ed/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values-expected.txt
[modify] https://crrev.com/da3d4e26aef179e83366f6efafb66e54676066ed/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
[modify] https://crrev.com/da3d4e26aef179e83366f6efafb66e54676066ed/third_party/WebKit/Source/core/css/StylePropertySerializer.h

Owner: cnardi@chromium.org
Status: Fixed (was: Available)
I think this is fixed now; getting pageBreak* properties via style will give you the correct answer. cssText still rewrites page-break-* to break-*, but I think this follows the spec regarding the serialization of shorthands.

Sign in to add a comment