diff options
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 48 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.h | 8 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 19 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 2 |
4 files changed, 62 insertions, 15 deletions
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 781c059..e575c72 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -11,6 +11,7 @@ #include "chrome/renderer/render_view.h" #include "grit/generated_resources.h" #include "printing/units.h" +#include "webkit/api/public/WebConsoleMessage.h" #include "webkit/api/public/WebScreenInfo.h" #include "webkit/api/public/WebSize.h" #include "webkit/api/public/WebURL.h" @@ -22,8 +23,15 @@ #include "skia/ext/vector_canvas.h" #endif +using WebKit::WebConsoleMessage; +using WebKit::WebString; +using WebKit::WebURLRequest; + namespace { +const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2; +const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 2 * 60; // 2 Minutes. + // Class that calls the Begin and End print functions on the frame and changes // the size of the view temporarily to support full page printing.. // Do not serve any events in the time between construction and destruction of @@ -86,16 +94,38 @@ class PrepareFrameAndViewForPrint { } // namespace -void PrintWebViewHelper::SyncPrint(WebFrame* frame) { +void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) { #if defined(OS_WIN) // If still not finished with earlier print request simply ignore. if (IsPrinting()) return; + // Check if there is script repeatedly trying to print and ignore it if too + // frequent. We use exponential wait time so for a page that calls print() in + // a loop the user will need to cancel the print dialog after 2 seconds, 4 + // seconds, 8, ... up to the maximum of 2 minutes. + // This gives the user time to navigate from the page. + if (script_initiated && (user_cancelled_scripted_print_count_ > 0)) { + base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_; + int min_wait_seconds = std::min( + kMinSecondsToIgnoreJavascriptInitiatedPrint << + (user_cancelled_scripted_print_count_ - 1), + kMaxSecondsToIgnoreJavascriptInitiatedPrint); + if (diff.InSeconds() < min_wait_seconds) { + WebString message(WebString::fromUTF8( + "Ignoring too frequent calls to print().")); + frame->AddMessageToConsole(WebConsoleMessage( + WebConsoleMessage::LevelWarning, + message)); + return; + } + } + // Retrieve the default print settings to calculate the expected number of // pages. ViewMsg_Print_Params default_settings; + bool user_cancelled_print = false; IPC::SyncMessage* msg = new ViewHostMsg_GetDefaultPrintSettings(routing_id(), &default_settings); @@ -148,22 +178,30 @@ void PrintWebViewHelper::SyncPrint(WebFrame* frame) { // TODO: Always copy before printing. PrintPages(print_settings, frame); } + + // Reset cancel counter on first successful print. + user_cancelled_scripted_print_count_ = 0; return; // All went well. } else { - // The user cancelled. + user_cancelled_print = true; } } else { // Send() failed. NOTREACHED(); } } else { - // The user cancelled. + // Failed to get default settings. + NOTREACHED(); } } else { // Send() failed. NOTREACHED(); } - DidFinishPrinting(false); + if (script_initiated && user_cancelled_print) { + ++user_cancelled_scripted_print_count_; + last_cancelled_script_print_ = base::Time::Now(); + } + DidFinishPrinting(user_cancelled_print); #else // defined(OS_WIN) // TODO(port): print not implemented NOTIMPLEMENTED(); @@ -209,7 +247,7 @@ bool PrintWebViewHelper::CopyAndPrint(const ViewMsg_PrintPages_Params& params, // When loading is done this will call DidStopLoading that will do the // actual printing. - print_web_view_->GetMainFrame()->LoadRequest(WebKit::WebURLRequest(url)); + print_web_view_->GetMainFrame()->LoadRequest(WebURLRequest(url)); return true; } diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index c2a02c2..77079fd 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -8,6 +8,7 @@ #include <vector> #include "base/scoped_ptr.h" +#include "base/time.h" #include "webkit/glue/webview_delegate.h" namespace gfx { @@ -31,11 +32,12 @@ struct ViewMsg_PrintPages_Params; class PrintWebViewHelper : public WebViewDelegate { public: explicit PrintWebViewHelper(RenderView * render_view) - : render_view_(render_view) {} + : render_view_(render_view), + user_cancelled_scripted_print_count_(0) {} virtual ~PrintWebViewHelper() {} - void SyncPrint(WebFrame* frame); + void Print(WebFrame* frame, bool script_initiated); // Is there a background print in progress? bool IsPrinting() { @@ -97,6 +99,8 @@ class PrintWebViewHelper : public WebViewDelegate { RenderView* render_view_; scoped_ptr<WebView> print_web_view_; scoped_ptr<ViewMsg_PrintPages_Params> print_pages_params_; + base::Time last_cancelled_script_print_; + int user_cancelled_scripted_print_count_; private: DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index ef81a65..7a2e29e 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -442,10 +442,8 @@ void RenderView::SendThumbnail() { void RenderView::OnPrintPages() { DCHECK(webview()); - if (webview()) { - // The renderer own the control flow as if it was a window.print() call. - ScriptedPrint(webview()->GetMainFrame()); - } + if (webview()) + Print(webview()->GetMainFrame(), false); } void RenderView::OnPrintingDone(int document_cookie, bool success) { @@ -2266,10 +2264,7 @@ void RenderView::SetInputMethodState(bool enabled) { } void RenderView::ScriptedPrint(WebFrame* frame) { - if (print_helper_.get() == NULL) { - print_helper_.reset(new PrintWebViewHelper(this)); - } - print_helper_->SyncPrint(frame); + Print(frame, true); } void RenderView::UserMetricsRecordAction(const std::wstring& action) { @@ -2903,3 +2898,11 @@ void RenderView::SendPasswordForms(WebFrame* frame) { if (!password_forms.empty()) Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, password_forms)); } + +void RenderView::Print(WebFrame* frame, bool script_initiated) { + DCHECK(frame); + if (print_helper_.get() == NULL) { + print_helper_.reset(new PrintWebViewHelper(this)); + } + print_helper_->Print(frame, script_initiated); +} diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 2075138..4b7311f 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -606,6 +606,8 @@ class RenderView : public RenderWidget, // Scan the given frame for password forms and send them up to the browser. void SendPasswordForms(WebFrame* frame); + void Print(WebFrame* frame, bool script_initiated); + // Bitwise-ORed set of extra bindings that have been enabled. See // BindingsPolicy for details. int enabled_bindings_; |