Chromium Code Reviews| Index: chrome/renderer/printing/print_web_view_helper.cc |
| diff --git a/chrome/renderer/printing/print_web_view_helper.cc b/chrome/renderer/printing/print_web_view_helper.cc |
| index d3807778aa7861e1d28c7a9cf1917d12eb782fa4..55ef34a51488190379d15ebdaef07a55f3cced85 100644 |
| --- a/chrome/renderer/printing/print_web_view_helper.cc |
| +++ b/chrome/renderer/printing/print_web_view_helper.cc |
| @@ -774,12 +774,17 @@ void PrepareFrameAndViewForPrint::FinishPrinting() { |
| on_ready_.Reset(); |
| } |
| -PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view) |
| +PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view, |
| + bool preview_enabled, |
|
Vitaly Buka (NO REVIEWS)
2014/09/08 09:43:59
preview_enabled is always false because you build
Marshall
2014/09/09 16:24:51
Building without ENABLE_FULL_PRINTING is problemat
|
| + bool scripted_print_throttling_disabled) |
| : content::RenderViewObserver(render_view), |
| content::RenderViewObserverTracker<PrintWebViewHelper>(render_view), |
| reset_prep_frame_view_(false), |
| + is_preview_enabled_(preview_enabled), |
| + is_scripted_print_throttling_disabled_(scripted_print_throttling_disabled), |
| is_print_ready_metafile_sent_(false), |
| ignore_css_margins_(false), |
| + user_cancelled_scripted_print_count_(0), |
| is_scripted_printing_blocked_(false), |
| notify_browser_of_print_failure_(true), |
| print_for_preview_(false), |
| @@ -798,6 +803,14 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed( |
| #endif // defined(OS_ANDROID) |
| if (is_scripted_printing_blocked_) |
| return false; |
| + // 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. |
| + if (!is_scripted_print_throttling_disabled_ && |
| + !is_preview_enabled_ && |
| + !user_initiated) |
| + return !IsScriptInitiatedPrintTooFrequent(frame); |
| return true; |
| } |
| @@ -827,8 +840,14 @@ void PrintWebViewHelper::PrintPage(blink::WebLocalFrame* frame, |
| if (!IsScriptInitiatedPrintAllowed(frame, user_initiated)) |
| return; |
| - print_preview_context_.InitWithFrame(frame); |
| - RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); |
| + IncrementScriptedPrintCount(); |
| + |
| + if (is_preview_enabled_) { |
| + print_preview_context_.InitWithFrame(frame); |
| + RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); |
| + } else { |
| + Print(frame, blink::WebNode()); |
| + } |
| } |
| bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { |
| @@ -851,6 +870,7 @@ bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { |
| void PrintWebViewHelper::OnPrintForPrintPreview( |
| const base::DictionaryValue& job_settings) { |
| + DCHECK(is_preview_enabled_); |
| // If still not finished with earlier print request simply ignore. |
| if (prep_frame_view_) |
| return; |
| @@ -985,6 +1005,7 @@ bool PrintWebViewHelper::IsPrintToPdfRequested( |
| } |
| void PrintWebViewHelper::OnPrintPreview(const base::DictionaryValue& settings) { |
| + DCHECK(is_preview_enabled_); |
| print_preview_context_.OnPrintPreview(); |
| UMA_HISTOGRAM_ENUMERATION("PrintPreview.PreviewEvent", |
| @@ -1187,6 +1208,7 @@ void PrintWebViewHelper::SetScriptedPrintBlocked(bool blocked) { |
| } |
| void PrintWebViewHelper::OnInitiatePrintPreview(bool selection_only) { |
| + DCHECK(is_preview_enabled_); |
| blink::WebLocalFrame* frame = NULL; |
| GetPrintFrame(&frame); |
| DCHECK(frame); |
| @@ -1220,8 +1242,13 @@ 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 (is_preview_enabled_) { |
| + print_preview_context_.InitWithNode(node); |
| + RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE); |
| + } else { |
| + blink::WebNode duplicate_node(node); |
| + Print(duplicate_node.document().frame(), duplicate_node); |
| + } |
| print_node_in_progress_ = false; |
| } |
| @@ -1259,6 +1286,7 @@ void PrintWebViewHelper::Print(blink::WebLocalFrame* frame, |
| LOG(ERROR) << "RenderPagesForPrint failed"; |
| DidFinishPrinting(FAIL_PRINT); |
| } |
| + ResetScriptedPrintCount(); |
| } |
| #endif // !DISABLE_BASIC_PRINTING |
| @@ -1279,6 +1307,7 @@ void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { |
| break; |
| case FAIL_PREVIEW: |
| + DCHECK(is_preview_enabled_); |
| int cookie = print_pages_params_ ? |
| print_pages_params_->params.document_cookie : 0; |
| if (notify_browser_of_print_failure_) { |
| @@ -1446,6 +1475,7 @@ bool PrintWebViewHelper::UpdatePrintSettings( |
| blink::WebLocalFrame* frame, |
| const blink::WebNode& node, |
| const base::DictionaryValue& passed_job_settings) { |
| + DCHECK(is_preview_enabled_); |
| const base::DictionaryValue* job_settings = &passed_job_settings; |
| base::DictionaryValue modified_job_settings; |
| if (job_settings->empty()) { |
| @@ -1588,6 +1618,54 @@ bool PrintWebViewHelper::CopyMetafileDataToSharedMem( |
| } |
| #endif // defined(OS_POSIX) |
| +bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( |
| + 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 (user_cancelled_scripted_print_count_ > 0) { |
| + base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_; |
| + int min_wait_seconds = kMinSecondsToIgnoreJavascriptInitiatedPrint; |
| + if (user_cancelled_scripted_print_count_ > 3) { |
| + min_wait_seconds = std::min( |
| + kMinSecondsToIgnoreJavascriptInitiatedPrint << |
| + (user_cancelled_scripted_print_count_ - 3), |
| + kMaxSecondsToIgnoreJavascriptInitiatedPrint); |
| + } |
| + if (diff.InSeconds() < min_wait_seconds) { |
| + too_frequent = true; |
| + } |
| + } |
| + |
| + if (!too_frequent) |
| + return false; |
| + |
| + blink::WebString message( |
| + blink::WebString::fromUTF8("Ignoring too frequent calls to print().")); |
| + frame->addMessageToConsole( |
| + blink::WebConsoleMessage( |
| + blink::WebConsoleMessage::LevelWarning, message)); |
| + return true; |
| +} |
| + |
| +void PrintWebViewHelper::ResetScriptedPrintCount() { |
| + // Reset cancel counter on successful print. |
| + user_cancelled_scripted_print_count_ = 0; |
| +} |
| + |
| +void PrintWebViewHelper::IncrementScriptedPrintCount() { |
| + ++user_cancelled_scripted_print_count_; |
| + last_cancelled_script_print_ = base::Time::Now(); |
| +} |
| + |
| + |
| void PrintWebViewHelper::ShowScriptedPrintPreview() { |
| if (is_scripted_preview_delayed_) { |
| is_scripted_preview_delayed_ = false; |