diff options
author | vitalybuka <vitalybuka@chromium.org> | 2014-09-09 18:23:36 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-10 01:28:58 +0000 |
commit | f470ae06577e8f07c0664c1a8997b5d219401882 (patch) | |
tree | de09522e1ce2a55e3e933d84750755376a2d199c | |
parent | dafbe9581cc48ef683931d9a79890c2b99395712 (diff) | |
download | chromium_src-f470ae06577e8f07c0664c1a8997b5d219401882.zip chromium_src-f470ae06577e8f07c0664c1a8997b5d219401882.tar.gz chromium_src-f470ae06577e8f07c0664c1a8997b5d219401882.tar.bz2 |
Fixed print_web_view_helper for CEF.
Restored disabling preview.
Restored printing throttling.
Restoring printing without print preview removed in https://codereview.chromium.org/488853002
Restored code is not used in Chrome or Chromium browsers.
BUG=374321
TBR=gene@chromium.org
Review URL: https://codereview.chromium.org/550033002
Cr-Commit-Position: refs/heads/master@{#294063}
-rw-r--r-- | chrome/chrome_tests.gypi | 6 | ||||
-rw-r--r-- | chrome/renderer/printing/print_web_view_helper.cc | 87 | ||||
-rw-r--r-- | chrome/renderer/printing/print_web_view_helper.h | 30 | ||||
-rw-r--r-- | chrome/renderer/printing/print_web_view_helper_browsertest.cc | 76 |
4 files changed, 188 insertions, 11 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 9aaeda7..f0b8b6a 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2080,12 +2080,16 @@ ['exclude', '^browser/printing/print_preview_pdf_generated_browsertest.cc'], ['exclude', '^browser/service_process/service_process_control_browsertest.cc'], ['exclude', '^browser/ui/webui/print_preview/print_preview_ui_browsertest.cc'], - ['exclude', '^renderer/printing/print_web_view_helper_browsertest.cc'], ['exclude', '^test/data/webui/print_preview.cc'], ['exclude', '^test/data/webui/print_preview.h'], ['exclude', '^test/data/webui/print_preview.js'], ], }], + ['enable_printing==0', { + 'sources/': [ + ['exclude', '^renderer/printing/print_web_view_helper_browsertest.cc'], + ], + }], ['enable_mdns==1', { 'sources' : [ 'browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc', diff --git a/chrome/renderer/printing/print_web_view_helper.cc b/chrome/renderer/printing/print_web_view_helper.cc index 6077438..4f8be2e 100644 --- a/chrome/renderer/printing/print_web_view_helper.cc +++ b/chrome/renderer/printing/print_web_view_helper.cc @@ -68,6 +68,12 @@ const char kPageLoadScriptFormat[] = const char kPageSetupScriptFormat[] = "setup(%s);"; +#if defined(ENABLE_FULL_PRINTING) +bool g_is_preview_enabled_ = true; +#else +bool g_is_preview_enabled_ = false; +#endif + void ExecuteScript(blink::WebFrame* frame, const char* script_format, const base::Value& parameters) { @@ -791,14 +797,23 @@ PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view) PrintWebViewHelper::~PrintWebViewHelper() {} +// static +void PrintWebViewHelper::DisablePreview() { + g_is_preview_enabled_ = false; +} + bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed( blink::WebFrame* frame, bool user_initiated) { #if defined(OS_ANDROID) return false; #endif // defined(OS_ANDROID) - if (is_scripted_printing_blocked_) - return false; - return true; + // If preview is enabled, then the print dialog is tab modal, and the user + // can always close the tab on a mis-behaving page (the system print dialog + // is app modal). If the print was initiated through user action, don't + // throttle. Or, if the command line flag to skip throttling has been set. + return !is_scripted_printing_blocked_ && + (user_initiated || g_is_preview_enabled_ || + scripting_throttler_.IsAllowed(frame)); } void PrintWebViewHelper::DidStartLoading() { @@ -827,8 +842,13 @@ void PrintWebViewHelper::PrintPage(blink::WebLocalFrame* frame, if (!IsScriptInitiatedPrintAllowed(frame, user_initiated)) return; - print_preview_context_.InitWithFrame(frame); - RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); + + if (!g_is_preview_enabled_) { + Print(frame, blink::WebNode()); + } else { + print_preview_context_.InitWithFrame(frame); + RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); + } } bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { @@ -1220,13 +1240,17 @@ void PrintWebViewHelper::PrintNode(const blink::WebNode& node) { // Make a copy of the node, in case RenderView::OnContextMenuClosed resets // its |context_menu_node_|. - print_preview_context_.InitWithNode(node); - RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE); + if (!g_is_preview_enabled_) { + blink::WebNode duplicate_node(node); + Print(duplicate_node.document().frame(), duplicate_node); + } else { + print_preview_context_.InitWithNode(node); + RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE); + } print_node_in_progress_ = false; } -#if !defined(DISABLE_BASIC_PRINTING) void PrintWebViewHelper::Print(blink::WebLocalFrame* frame, const blink::WebNode& node) { // If still not finished with earlier print request simply ignore. @@ -1259,8 +1283,8 @@ void PrintWebViewHelper::Print(blink::WebLocalFrame* frame, LOG(ERROR) << "RenderPagesForPrint failed"; DidFinishPrinting(FAIL_PRINT); } + scripting_throttler_.Reset(); } -#endif // !DISABLE_BASIC_PRINTING void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { switch (result) { @@ -1970,4 +1994,49 @@ void PrintWebViewHelper::SetPrintPagesParams( settings.params.document_cookie)); } +PrintWebViewHelper::ScriptingThrottler::ScriptingThrottler() : count_(0) { +} + +bool PrintWebViewHelper::ScriptingThrottler::IsAllowed(blink::WebFrame* frame) { + const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2; + const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32; + bool too_frequent = false; + + // Check if there is script repeatedly trying to print and ignore it if too + // frequent. The first 3 times, we use a constant wait time, but if this + // gets excessive, we switch to exponential wait time. So for a page that + // calls print() in a loop the user will need to cancel the print dialog + // after: [2, 2, 2, 4, 8, 16, 32, 32, ...] seconds. + // This gives the user time to navigate from the page. + if (count_ > 0) { + base::TimeDelta diff = base::Time::Now() - last_print_; + int min_wait_seconds = kMinSecondsToIgnoreJavascriptInitiatedPrint; + if (count_ > 3) { + min_wait_seconds = + std::min(kMinSecondsToIgnoreJavascriptInitiatedPrint << (count_ - 3), + kMaxSecondsToIgnoreJavascriptInitiatedPrint); + } + if (diff.InSeconds() < min_wait_seconds) { + too_frequent = true; + } + } + + if (!too_frequent) { + ++count_; + last_print_ = base::Time::Now(); + return true; + } + + blink::WebString message( + blink::WebString::fromUTF8("Ignoring too frequent calls to print().")); + frame->addMessageToConsole(blink::WebConsoleMessage( + blink::WebConsoleMessage::LevelWarning, message)); + return false; +} + +void PrintWebViewHelper::ScriptingThrottler::Reset() { + // Reset counter on successful print. + count_ = 0; +} + } // namespace printing diff --git a/chrome/renderer/printing/print_web_view_helper.h b/chrome/renderer/printing/print_web_view_helper.h index 4ce36b8..e7cd7da 100644 --- a/chrome/renderer/printing/print_web_view_helper.h +++ b/chrome/renderer/printing/print_web_view_helper.h @@ -69,6 +69,10 @@ class PrintWebViewHelper explicit PrintWebViewHelper(content::RenderView* render_view); virtual ~PrintWebViewHelper(); + // Disable print preview and switch to system dialog printing even if full + // printing is build-in. This method is used by CEF. + static void DisablePreview(); + bool IsPrintingEnabled(); void PrintNode(const blink::WebNode& node); @@ -78,7 +82,11 @@ class PrintWebViewHelper FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperPreviewTest, BlockScriptInitiatedPrinting); FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, OnPrintPages); - + FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, OnPrintPages); + FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, + BlockScriptInitiatedPrinting); + FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, + BlockScriptInitiatedPrintingFromPopup); #if defined(OS_WIN) || defined(OS_MACOSX) FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintLayoutTest); FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintWithIframe); @@ -309,6 +317,7 @@ class PrintWebViewHelper scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_; bool is_print_ready_metafile_sent_; bool ignore_css_margins_; + // Used for scripted initiated printing blocking. bool is_scripted_printing_blocked_; @@ -428,6 +437,25 @@ class PrintWebViewHelper State state_; }; + class ScriptingThrottler { + public: + ScriptingThrottler(); + + // Returns false if script initiated printing occurs too often. + bool IsAllowed(blink::WebFrame* frame); + + // Reset the counter for script initiated printing. + // Scripted printing will be allowed to continue. + void Reset(); + + private: + base::Time last_print_; + int count_ = 0; + DISALLOW_COPY_AND_ASSIGN(ScriptingThrottler); + }; + + ScriptingThrottler scripting_throttler_; + bool print_node_in_progress_; PrintPreviewContext print_preview_context_; bool is_loading_; diff --git a/chrome/renderer/printing/print_web_view_helper_browsertest.cc b/chrome/renderer/printing/print_web_view_helper_browsertest.cc index 55a8ae5..3c777bd 100644 --- a/chrome/renderer/printing/print_web_view_helper_browsertest.cc +++ b/chrome/renderer/printing/print_web_view_helper_browsertest.cc @@ -236,6 +236,80 @@ class PrintWebViewHelperTest : public PrintWebViewHelperTestBase { DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTest); }; +// This tests only for platforms without print preview. +#if !defined(ENABLE_FULL_PRINTING) +// Tests that the renderer blocks window.print() calls if they occur too +// frequently. +TEST_F(PrintWebViewHelperTest, BlockScriptInitiatedPrinting) { + // Pretend user will cancel printing. + chrome_render_thread_->set_print_dialog_user_response(false); + // Try to print with window.print() a few times. + PrintWithJavaScript(); + PrintWithJavaScript(); + PrintWithJavaScript(); + VerifyPagesPrinted(false); + + // Pretend user will print. (but printing is blocked.) + chrome_render_thread_->set_print_dialog_user_response(true); + PrintWithJavaScript(); + VerifyPagesPrinted(false); + + // Unblock script initiated printing and verify printing works. + PrintWebViewHelper::Get(view_)->scripting_throttler_.Reset(); + chrome_render_thread_->printer()->ResetPrinter(); + PrintWithJavaScript(); + VerifyPageCount(1); + VerifyPagesPrinted(true); +} + +// Tests that the renderer always allows window.print() calls if they are user +// initiated. +TEST_F(PrintWebViewHelperTest, AllowUserOriginatedPrinting) { + // Pretend user will cancel printing. + chrome_render_thread_->set_print_dialog_user_response(false); + // Try to print with window.print() a few times. + PrintWithJavaScript(); + PrintWithJavaScript(); + PrintWithJavaScript(); + VerifyPagesPrinted(false); + + // Pretend user will print. (but printing is blocked.) + chrome_render_thread_->set_print_dialog_user_response(true); + PrintWithJavaScript(); + VerifyPagesPrinted(false); + + // Try again as if user initiated, without resetting the print count. + chrome_render_thread_->printer()->ResetPrinter(); + LoadHTML(kPrintOnUserAction); + gfx::Size new_size(200, 100); + Resize(new_size, gfx::Rect(), false); + + gfx::Rect bounds = GetElementBounds("print"); + EXPECT_FALSE(bounds.IsEmpty()); + blink::WebMouseEvent mouse_event; + mouse_event.type = blink::WebInputEvent::MouseDown; + mouse_event.button = blink::WebMouseEvent::ButtonLeft; + mouse_event.x = bounds.CenterPoint().x(); + mouse_event.y = bounds.CenterPoint().y(); + mouse_event.clickCount = 1; + SendWebMouseEvent(mouse_event); + mouse_event.type = blink::WebInputEvent::MouseUp; + SendWebMouseEvent(mouse_event); + ProcessPendingMessages(); + + VerifyPageCount(1); + VerifyPagesPrinted(true); +} + +// Duplicate of OnPrintPagesTest only using javascript to print. +TEST_F(PrintWebViewHelperTest, PrintWithJavascript) { + PrintWithJavaScript(); + + VerifyPageCount(1); + VerifyPagesPrinted(true); +} +#endif // !ENABLE_FULL_PRINTING + #if !defined(DISABLE_BASIC_PRINTING) // Tests that printing pages work and sending and receiving messages through // that channel all works. @@ -487,6 +561,7 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase { DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest); }; +#if defined(ENABLE_FULL_PRINTING) TEST_F(PrintWebViewHelperPreviewTest, BlockScriptInitiatedPrinting) { PrintWebViewHelper* print_web_view_helper = PrintWebViewHelper::Get(view_); print_web_view_helper->SetScriptedPrintBlocked(true); @@ -517,6 +592,7 @@ TEST_F(PrintWebViewHelperPreviewTest, PrintWithJavaScript) { VerifyPreviewRequest(true); } +#endif // ENABLE_FULL_PRINTING // Tests that print preview work and sending and receiving messages through // that channel all works. |