summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-26 15:49:33 +0000
committersverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-26 15:49:33 +0000
commit0fda727e08d2f785ce127fba39c4ce69955fa934 (patch)
treed4001d93587a35d618b9ee871dfb382dfc9ae852
parented42bc2f22755d2864056cb03fc2ef17793ba9f0 (diff)
downloadchromium_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.cc48
-rw-r--r--chrome/renderer/print_web_view_helper.h8
-rw-r--r--chrome/renderer/render_view.cc19
-rw-r--r--chrome/renderer/render_view.h2
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_;