diff options
author | sverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-26 15:49:33 +0000 |
---|---|---|
committer | sverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-26 15:49:33 +0000 |
commit | 0fda727e08d2f785ce127fba39c4ce69955fa934 (patch) | |
tree | d4001d93587a35d618b9ee871dfb382dfc9ae852 | |
parent | ed42bc2f22755d2864056cb03fc2ef17793ba9f0 (diff) | |
download | chromium_src-0fda727e08d2f785ce127fba39c4ce69955fa934.zip chromium_src-0fda727e08d2f785ce127fba39c4ce69955fa934.tar.gz chromium_src-0fda727e08d2f785ce127fba39c4ce69955fa934.tar.bz2 |
Restrict how often javascript can annoy the user with the print dialog. If a page continuously calls print() through javascript and the user cancels the printing no other printer dialog will be shown for 15 seconds.
Also removed "Print failed" notification when the user cancels printing (since this should be obvious to the user).
BUG=http://crbug.com/7880
TEST=See bug.
Review URL: http://codereview.chromium.org/146052
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19362 0039d316-1c4b-4281-b951-d872f2087c98
-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_; |