onbeforeprint is executed BEFORE "@media print" CSS is applied

RESOLVED INVALID
(NeedInfo from)

Status

()

RESOLVED INVALID
4 years ago
a year ago

People

(Reporter: g, Unassigned, NeedInfo)

Tracking

34 Branch
x86_64
Windows 7
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(3 attachments)

(Reporter)

Description

4 years ago
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0 (Beta/Release)
Build ID: 20140804030205

Steps to reproduce:

I used onbeforeprint in combination with a CSS Media Query for PRINT.

What I want, is that my static content should be generated via onbeforeprint. Before it should be generated, the PRINT CSS has to be applied, my javascript functions should work inside the Print CSS.
Please compare my results with Google Chrome and Mozilla Firefox. 
In Google Chrome its working like I want, the CSS is applied first, than the javascript functions are executed on this CSS.

http://jsfiddle.net/Uy5QB/19/


Actual results:

The javascript functions are executed on the normal website CSS.
In this case, the static content is regenerated wrong.


Expected results:

Instead, the CSS should be applied first, and than in the applied print css, my javascript functions are executed
(Reporter)

Comment 1

4 years ago
Created attachment 8467111 [details]
fiddle.png

Showing how Google Chrome generates the page, in contrast to Mozilla Firefox.

Updated

4 years ago
Component: Untriaged → Printing: Output
Product: Firefox → Core
Created attachment 8467892 [details]
reduced testcase 1 (showing that "beforeprint" doesn't see print stylesheet)

I can confirm that onbeforeprint isn't seeing the print stylesheet, using this attached testcase, in Firefox Nightly 34.0a1 (2014-08-04).  In particular, print preview adds the text "1px" to the div, which indicates that onbeforeprint is seeing the computed style before "@media print" stylesheets are applied.

However, it's not clear to me that this is incorrect.

Also, it looks like (at least on this testcase) Chrome (version 38) isn't running my onbeforeprint handler at all.  When I do Ctrl + P and look at its rendering, no width value (neither 1px nor 30px) is added to the div.
(In reply to Daniel Holbert [:dholbert] from comment #2)
> However, it's not clear to me that this is incorrect.

This is specified here:
 http://www.w3.org/TR/html5/webappapis.html#printing
...which has these steps (omitting other ones for brevity):
{
 2. The user agent must fire a simple event named beforeprint at the Window object of the Document that is being printed, as well as any nested browsing contexts in it. The beforeprint event can be used to annotate the printed copy, for instance adding the time at which the document was printed.
[...]
 4. The user agent should offer the user the opportunity to obtain a physical form (or the representation of a physical form) of the document. The user agent may wait for the user to either accept or decline before returning;
}

The text "obtain a physical form" is linked to text that says the physical form is a printed / PDF rendering, and importantly:
{
When the user actually obtains a physical form (or a representation of a physical form) of a Document, the user agent is expected to create a new rendering of the Document for the print media.
}

In other words, we create a new rendering (with print stylesheets applied) *when the user actually obtains a physical form*. Which is during step 4, *after* onbeforeprint has been fired.
Summary: javascript executed BEFORE print CSS is applied → onbeforeprint is executed BEFORE "@media print" CSS is applied
Created attachment 8467902 [details]
testcase 2 (testing whether beforeprint even runs)

This testcase (which clears the document in its onbeforeprint handler) seems to indicate, on my machine at least, that Chrome doesn't support onbeforeprint.

This MDN page agrees with me:
 https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeprint
...as does the first result of a google search for "onbeforeprint chrome":
http://stackoverflow.com/questions/13598790/onbeforeprint-and-onafterprint-is-not-working-in-chrome-and-ie

So, unless those ^ are mistaken, I don't think Chrome is a useful reference for how this should work. :)
I'm tentatively resolving this as INVALID, since it looks like (per spec-text quoted in comment 3) we're doing the right thing here, and there's no interop issue w/ Chrome (as originally reported) because Chrome doesn't even support this event.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 4 years ago
Resolution: --- → INVALID
(Reporter)

Comment 6

4 years ago
Chrome doesnt use onbeforeprint, but it uses some other handlers. Why dont you take a look at my code? I am not very interested in which way is right. If you have a solution for my problem, please TELL IT to me.
If not, my bug is legit.
(Reporter)

Comment 7

4 years ago
Unconfirmed, please read my previous post.
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
(Reporter)

Comment 8

4 years ago
If you try to follow the W3C recommendation, I think the W3C recommendation is broken, because how else can I solve my problem?? Do I have to set all CSS properties manually via javascript. Oh god.

Chrome does what I need, and Firefox  not, so easy.

Like I often said before, please tell me about a solution.

The W3C draft is wrong.
We clone document for printing, so web page can't get access to the cloned document.
(In reply to g from comment #6)
> Chrome doesnt use onbeforeprint, but it uses some other handlers. Why dont
> you take a look at my code?

I skimmed it, but I didn't immediately see a spot where Chrome was hooking in to detect printing and working on the post-print-stylesheet scripts. Is it the "window.matchMedia" part?  All that code does is adjust "triggerCheck", wheras the beforePrint function (used in Firefox) calls "chart2.validateNow()".

A simpler testcase would definitely be helpful here.

> I am not very interested in which way is right.
> If you have a solution for my problem, please TELL IT to me.
> If not, my bug is legit.

I'm sorry that I don't (currently) have a better solution to offer you.  This bug tracker's primary purpose is reporting & fixing bugs in Firefox. When it's clear what the "right"/"better" way to do something is, we obviously try to do that. That's not always possible, though. (In this case, I don't know if it's possible to do what you describe -- running JS on the post-print-stylesheet-rendered page. I don't think it is, with current web standards.)

(In reply to g from comment #8)
> I think the W3C recommendation is broken

nit: this is WHATWG, not W3C

> because how else can I solve my problem?? Do I have to set all
> CSS properties manually via javascript. Oh god.

That might be the best thing to do, yeah.

> Chrome does what I need, and Firefox  not, so easy.

I'm actually not sure Chrome does what you want here. For example, if I load http://jsfiddle.net/Uy5QB/19/show/ in a wide Chrome window and do Ctrl+P, the graph sticks off the page.  It doesn't seem to do any special graph-re-rendering-at-the-printed-page-width, like you seem to be saying it does. (Not on my machine, at least)

Can you try print-previewing http://jsfiddle.net/Uy5QB/19/show/ in a wide Chrome window and see if it actually works for you?
(In reply to Daniel Holbert [:dholbert] from comment #10)
> I'm sorry that I don't (currently) have a better solution to offer you. 
> This bug tracker's primary purpose is reporting & fixing bugs in Firefox.
> When it's clear what the "right"/"better" way to do something is, we
> obviously try to do that.

[Sorry, didn't flesh out that thought properly. Meant to say: "when a bug is invalid [because we're following the spec] and there's a clearly better way for the author to approach their problem, then we obviously try to point that out."
needinfo=reporter on whether Chrome is actually doing something useful when you make the window wide at http://jsfiddle.net/Uy5QB/19/show/ (per end of comment 10), and/or possibly providing a simplified testcase where Chrome and Firefox don't take completely different codepaths.

Also: if you think the WHATWG spec is wrong, you can bring it up on one of their mailing lists at https://www.whatwg.org/mailing-list .

My understanding, based on the spec text quoted above, is that "beforeprint" / "onbeforeprint" is intended to allow you to run some script to modify the (non-printed) document, before re-rendering it for printing -- like adding a timestamp (the example given in the spec).

If you want a way to modify the printed document *after* it's been re-rendered with the print stylesheets applied, that might require a different API.
Flags: needinfo?(g)
(In reply to g from comment #8)
> Like I often said before, please tell me about a solution.

A bit more thought on this -- so, your chart is rendered by an external library, which is partly why "the solution" is no-obvious.  I'm not really interested in debugging that external library :) but briefly: it looks like (?) the chart is completely re-built on every window-resize, which is why it scales when you resize the window, but not when you print. The "right" way to make this work would probably be to make the SVG chart adapt to the page-width dynamically, without needing javascript, with a combination of the SVG viewBox attribute (which it doesn't currently use, but probably should) and perhaps with CSS media queries based on the viewport-size.

Alternately, a simpler solution is to just remove "overflow:hidden" from the ancestors of the SVG element (in particular, the parent of the <svg> node and the "chartdiv_useractivity" node both have "overflow:hidden"), and then trust Firefox's default "shrink-to-fit" print behavior to detect things flowing off of the page & scale down the page content such that it fits.
Anyway, re-resolving as INVALID, since this doesn't seem to be bug in Firefox.  In particular:
 (1) we seem to be following the relevant spec text for the API in question (onbeforeprint)
 (2) Chrome, which is presented as a reference, has similar problems (the printed chart's width depends on your window-width before you printed, and may run off the printed page), on top of the fact that they're not supporting onbeforeprint and hence are running different JS code here anyway.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 4 years ago4 years ago
Resolution: --- → INVALID

Comment 15

a year ago
I'm going to have to second g's request here. An event should be fired *after* the css media queries are evaluated but before the print. This could be the beforeprint event or it could be some other event. However, as currently implemented the beforeprint event is basically useless.

Comment 16

a year ago
(In reply to talon4196 from comment #15)
> I'm going to have to second g's request here. An event should be fired
> *after* the css media queries are evaluated but before the print. This could
> be the beforeprint event or it could be some other event. However, as
> currently implemented the beforeprint event is basically useless.

+1, I "third" g's request.

There are, IMO, many valid reasons to execute code to modify the page in a "print" media state. The current implementation basically makes it impossible to have the page respond (using code) when transitioned to the "print" media state.
We can't change the meaning of an event which has been implemented and spec'ed for years.
And Chrome doesn't support before/afterprint events (or at least didn't until very recently. They have at least discussed about implementing support for those).

Some new mechanism would be needed here, especially since Gecko clones the original document and prints the clone, not the original page.

But, discussion about such new mechanism would need to happen in a spec bug, not here.
Proposals could be done in https://whatwg.org/newbug
You need to log in before you can comment on or make changes to this bug.