summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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_;