Bug 19937

Summary: Add beforeprint and afterprint events
Product: WebKit Reporter: Calvin Anderson <anderson.calvin1>
Component: PrintingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED DUPLICATE    
Severity: Enhancement CC: abarth, ap, benwells, bfulgham, bob.net2005, cdumez, cgriego, dominicc, eric, hartman.wiki, marcoos+bwo, martin.hejral, mathias, rshimazu, sam, tj.vantoll, webkit-bug-importer, webkit, webkit.review.bot, zvika
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Attachments:
Description Flags
Premature upload
none
Patch
none
Patch
none
Patch
none
Patch
none
With tests for navigation during before and afterprint none

Description Calvin Anderson 2008-07-07 16:36:58 PDT
I. Steps:
 -----------
 
 Documentation for onbeforeprint and onafterprint events: 
 
 onbeforeprint:  http://msdn2.microsoft.com/en-us/library/ms536906(VS.85).aspx
 onafterprint:  http://msdn2.microsoft.com/en-us/library/ms536788(VS.85).aspx
 
 
 
 
 
 II. Issue:
 -----------------
 Safari doesnot support onbeforeprint and onafterprint events
 
 
 
 III. Other browsers:
 -----------------------
 IE7 : ok
 FF3 : not working
 Opera 9.27: not working
 
 IV. Safari nightly tested: version 3.1.1(525.17 )- r34388
 
 Not working properly on Safari.
 
 
 
 V. Safari screenshot : Not Avalible
Comment 1 Mark Rowe (bdash) 2008-07-07 17:46:59 PDT
>  IV. Safari nightly tested: version 3.1.1(525.17 )- r34388

Note: You tested a WebKit nightly, not a Safari nightly.
Comment 2 Alexey Proskuryakov 2011-12-07 13:49:28 PST
*** Bug 26137 has been marked as a duplicate of this bug. ***
Comment 3 Alexey Proskuryakov 2011-12-07 13:50:46 PST
*** Bug 73973 has been marked as a duplicate of this bug. ***
Comment 4 Alexey Proskuryakov 2011-12-07 13:51:21 PST
These are now supported by Firefox, and are in HTML5.
Comment 5 Ben Wells 2011-12-07 21:44:05 PST
Created attachment 118328 [details]
Premature upload
Comment 6 Ben Wells 2011-12-07 21:58:00 PST
Created attachment 118330 [details]
Patch
Comment 7 Ben Wells 2011-12-07 22:05:04 PST
(In reply to comment #6)
> Created an attachment (id=118330) [details]
> Patch

Alexey commented on bug 73973 (dup of this):

"Looking at the patch, it appears that beforeprint will be only dispatched after switching to printing mode. That seems suspicious."

Indeed, sending the message with enqueue was not correct for javascript calls to window.print (versus user initiated printing via the browser). The new patch fixes this by using dispatch, so handling the event synchronously.

Handling this deep can cause multiple calls to before/after print. It does for Chromium anyway - once before the print dialog comes up, and once after. The previous patch was an attempt to address that but it only worked with javascript printing.

There are no common single entry points to print mode within WebKit that I'm aware of, so avoiding the multiple calls - if necessary - will require browser specific code to dispatch the events. Unless someone has a better idea.

Tests still not done, so not ready for review yet.
Comment 8 Ben Wells 2011-12-13 20:34:19 PST
Created attachment 119147 [details]
Patch
Comment 9 Ben Wells 2011-12-13 20:43:07 PST
I've added a couple of tests for beforeprint, but I have some questions.

1. I'm not sure of the best way to test afterprint. I couldn't see a way in layoutTestController to enter then exit printing. Should i add a parameter to setPrinting (true by default) to allow this? Or is there a better way?

2. The results have information about the layout, which I think might cause platform differences. If I don't call layoutTestController.setPrinting, the layout information isn't there, just plain text. Is there a way to just have plain text output while printing?
Comment 10 Ben Wells 2012-01-02 20:58:27 PST
Created attachment 120911 [details]
Patch
Comment 11 Eric Seidel (no email) 2012-01-09 13:26:24 PST
Comment on attachment 120911 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=120911&action=review

> Source/WebCore/page/PrintContext.cpp:172
> +    m_frame->document()->dispatchWindowEvent(Event::create(eventNames().beforeprintEvent, false, false));

Javascript can do anything here, including navigate the frame.  Will that cause badness to happen in the rest of this function (or it's callers)?

> Source/WebCore/page/PrintContext.cpp:222
> +    m_frame->document()->dispatchWindowEvent(Event::create(eventNames().afterprintEvent, false, false));

Same problem, since I believe this is going to execute syncrhonous javascript?  Are callers prepared for that case?
Comment 12 Ben Wells 2012-01-22 22:51:02 PST
Created attachment 123522 [details]
Patch
Comment 13 Ben Wells 2012-01-26 01:34:10 PST
If someone has time to review this patch it would be great.
Comment 14 Ben Wells 2012-01-26 17:06:52 PST
Created attachment 124219 [details]
With tests for navigation during before and afterprint
Comment 15 Eric Seidel (no email) 2012-01-30 16:04:49 PST
Do you have answers to my arbitrary javascript questions above?
Comment 16 Ben Wells 2012-01-30 18:15:34 PST
(In reply to comment #15)
> Do you have answers to my arbitrary javascript questions above?

Sorry I should have been clearer. There is another patch up; I think / hope I've updated the code to account for that. I've used a guard RefPtr on the frame to prevent it being destroyed.

I've also added a couple of tests which navigate away from the page being printed in before and afterprint.
Comment 17 zvika 2012-01-30 23:34:03 PST
(In reply to comment #16)
> (In reply to comment #15)
> > Do you have answers to my arbitrary javascript questions above?
> 
> Sorry I should have been clearer. There is another patch up; I think / hope I've updated the code to account for that. I've used a guard RefPtr on the frame to prevent it being destroyed.
> 
> I've also added a couple of tests which navigate away from the page being printed in before and afterprint.

Does the guard RefPtr only prevent the frame from being closed, or are there additional limitations it introduce on the script?

I am asking because I need the event script to modify the frame DOM by adding some divs and iframes.
Comment 18 Ben Wells 2012-01-30 23:36:01 PST
> Does the guard RefPtr only prevent the frame from being closed, or are there additional limitations it introduce on the script?
> 
> I am asking because I need the event script to modify the frame DOM by adding some divs and iframes.

It simply prevents the frame object (in C++) from being destroyed.
Comment 19 Ben Wells 2012-01-30 23:47:51 PST
(In reply to comment #16)
> (In reply to comment #15)
> > Do you have answers to my arbitrary javascript questions above?
> 
> Sorry I should have been clearer. There is another patch up; I think / hope I've updated the code to account for that. I've used a guard RefPtr on the frame to prevent it being destroyed.
> 
> I've also added a couple of tests which navigate away from the page being printed in before and afterprint.

Eric: on further reading of your question I noted the 'on callers' part. I think there is still a problem here, for example the m_frame in PrintContext could get freed in begin() which would cause bad things to happen when end() is called.

I don't know why this doesn't make the tests crash but will look more.
Comment 20 Ben Wells 2012-01-31 20:48:44 PST
A record of some findings so far:

- if the events use window.location to navigate, this gets deferred. Also, this doesn't cause frames to be destroyed in the simple case.

- if the events use window.close to close a window that has been opened, this gets deferred also (DOMWIndow::close calls chrome()->closeWindowSoon()) and the frame is destroyed after the printing action has finished

I still need to investigate the non-simple case of iframes navigating.
Comment 21 Ben Wells 2012-02-12 16:53:55 PST
Update: with the matchMedia api it is fairly simple to have an afterprint and beforeprint event. This eliminates the need I had for these events, so I am not working on this bug anymore.
Comment 22 TJ VanToll 2012-06-12 08:06:03 PDT
(In reply to comment #21)
> Update: with the matchMedia api it is fairly simple to have an afterprint and beforeprint event. This eliminates the need I had for these events, so I am not working on this bug anymore.

Ben: What syntax could you use to implement these with the matchMedia API?  I'm having issues getting this working.

Thanks.
Comment 23 Ben Wells 2012-06-12 18:41:15 PDT
(In reply to comment #22)
> (In reply to comment #21)
> > Update: with the matchMedia api it is fairly simple to have an afterprint and beforeprint event. This eliminates the need I had for these events, so I am not working on this bug anymore.
> 
> Ben: What syntax could you use to implement these with the matchMedia API?  I'm having issues getting this working.
> 
> Thanks.

There is a working attachment on this chromium bug: http://code.google.com/p/chromium/issues/detail?id=105743.

Let me know if that doesn't work.
Comment 24 Ryotaro Shimazu 2013-08-25 04:21:31 PDT
(In reply to comment #23)
> There is a working attachment on this chromium bug: http://code.google.com/p/chromium/issues/detail?id=105743.
> 
> Let me know if that doesn't work.

It basically works with Google Chrome and with Mac Safari but with Android (4.1) stock browser it does not work.
It seems that this is because Android stock browser does not support addListener method?
I am wondering how Android stock browser can detect print event.
Comment 25 Derk-Jan Hartman 2017-12-12 02:55:04 PST
As a note, Chrome added support for this in version v63
Comment 26 MH 2018-01-19 05:32:37 PST
it looks like Safari-Webkit is the last big browser that does not have this

PLEASE is there any chance of shifting-upgrading?

-

Browser compatibility:

Chrome	Edge	Firefox (Gecko)	Internet Explorer

https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onafterprint
Comment 27 Radar WebKit Bug Importer 2021-08-24 16:00:48 PDT
<rdar://problem/82314326>
Comment 28 Chris Dumez 2022-02-11 11:33:57 PST

*** This bug has been marked as a duplicate of bug 196478 ***