Fixing spreadsheets printing.

Some plugins needs to have document loaded to decide if printing is supported. This patch makes scripted print preview for plugins to wait DidStopLoading().

BUG=268778
R=cevans@chromium.org, thestig@chromium.org

Review URL: https://codereview.chromium.org/23855002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221300 0039d316-1c4b-4281-b951-d872f2087c98
parent a34b0d15
......@@ -97,7 +97,8 @@ bool PrintViewManager::PrintPreviewNow(bool selection_only) {
}
void PrintViewManager::PrintPreviewForWebNode() {
DCHECK_EQ(NOT_PREVIEWING, print_preview_state_);
if (print_preview_state_ != NOT_PREVIEWING)
return;
print_preview_state_ = USER_INITIATED_PREVIEW;
}
......@@ -133,8 +134,7 @@ void PrintViewManager::OnDidShowPrintDialog() {
observer_->OnPrintDialogShown();
}
void PrintViewManager::OnScriptedPrintPreview(bool source_is_modifiable,
IPC::Message* reply_msg) {
void PrintViewManager::OnSetupScriptedPrintPreview(IPC::Message* reply_msg) {
BrowserThread::CurrentlyOn(BrowserThread::UI);
ScriptedPrintPreviewClosureMap& map =
g_scripted_print_preview_closure_map.Get();
......@@ -168,7 +168,15 @@ void PrintViewManager::OnScriptedPrintPreview(bool source_is_modifiable,
reply_msg);
map[rph] = callback;
scripted_print_preview_rph_ = rph;
}
void PrintViewManager::OnShowScriptedPrintPreview(bool source_is_modifiable) {
PrintPreviewDialogController* dialog_controller =
PrintPreviewDialogController::GetInstance();
if (!dialog_controller) {
PrintPreviewDone();
return;
}
dialog_controller->PrintPreview(web_contents());
PrintHostMsg_RequestPrintPreview_Params params;
params.is_modifiable = source_is_modifiable;
......@@ -185,8 +193,10 @@ bool PrintViewManager::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrintPreview,
OnScriptedPrintPreview)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_SetupScriptedPrintPreview,
OnSetupScriptedPrintPreview)
IPC_MESSAGE_HANDLER(PrintHostMsg_ShowScriptedPrintPreview,
OnShowScriptedPrintPreview)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......
......@@ -74,8 +74,8 @@ class PrintViewManager : public PrintViewManagerBase,
// IPC Message handlers.
void OnDidShowPrintDialog();
void OnScriptedPrintPreview(bool source_is_modifiable,
IPC::Message* reply_msg);
void OnSetupScriptedPrintPreview(IPC::Message* reply_msg);
void OnShowScriptedPrintPreview(bool source_is_modifiable);
void OnScriptedPrintPreviewReply(IPC::Message* reply_msg);
// Weak pointer to an observer that is notified when the print dialog is
......
......@@ -436,8 +436,12 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
// Run a nested message loop in the renderer until print preview for
// window.print() finishes.
IPC_SYNC_MESSAGE_ROUTED1_0(PrintHostMsg_ScriptedPrintPreview,
bool /* is_modifiable */)
IPC_SYNC_MESSAGE_ROUTED0_0(PrintHostMsg_SetupScriptedPrintPreview)
// Tell the browser to show the print preview, when the document is sufficiently
// loaded such that the renderer can determine whether it is modifiable or not.
IPC_MESSAGE_ROUTED1(PrintHostMsg_ShowScriptedPrintPreview,
bool /* is_modifiable */)
// Notify the browser that the PDF in the initiator renderer has disabled print
// scaling option.
......
......@@ -304,14 +304,16 @@ void ComputeWebKitPrintParamsInDesiredDpi(
print_params.desired_dpi);
}
WebKit::WebPlugin* GetPlugin(const WebKit::WebFrame* frame) {
return frame->document().isPluginDocument() ?
frame->document().to<WebKit::WebPluginDocument>().plugin() : NULL;
}
bool PrintingNodeOrPdfFrame(const WebKit::WebFrame* frame,
const WebKit::WebNode& node) {
if (!node.isNull())
return true;
if (!frame->document().isPluginDocument())
return false;
WebKit::WebPlugin* plugin =
frame->document().to<WebKit::WebPluginDocument>().plugin();
WebKit::WebPlugin* plugin = GetPlugin(frame);
return plugin && plugin->supportsPaginatedPrint();
}
......@@ -741,7 +743,10 @@ PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view)
is_scripted_printing_blocked_(false),
notify_browser_of_print_failure_(true),
print_for_preview_(false),
print_node_in_progress_(false) {
print_node_in_progress_(false),
is_loading_(false),
is_scripted_preview_delayed_(false),
weak_ptr_factory_(this) {
}
PrintWebViewHelper::~PrintWebViewHelper() {}
......@@ -761,6 +766,15 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed(
return true;
}
void PrintWebViewHelper::DidStartLoading() {
is_loading_ = true;
}
void PrintWebViewHelper::DidStopLoading() {
is_loading_ = false;
ShowScriptedPrintPreview();
}
// Prints |frame| which called window.print().
void PrintWebViewHelper::PrintPage(WebKit::WebFrame* frame,
bool user_initiated) {
......@@ -1658,6 +1672,15 @@ void PrintWebViewHelper::IncrementScriptedPrintCount() {
last_cancelled_script_print_ = base::Time::Now();
}
void PrintWebViewHelper::ShowScriptedPrintPreview() {
if (is_scripted_preview_delayed_) {
is_scripted_preview_delayed_ = false;
Send(new PrintHostMsg_ShowScriptedPrintPreview(routing_id(),
print_preview_context_.IsModifiable()));
}
}
void PrintWebViewHelper::RequestPrintPreview(PrintPreviewRequestType type) {
const bool is_modifiable = print_preview_context_.IsModifiable();
const bool has_selection = print_preview_context_.HasSelection();
......@@ -1667,10 +1690,27 @@ void PrintWebViewHelper::RequestPrintPreview(PrintPreviewRequestType type) {
params.has_selection = has_selection;
switch (type) {
case PRINT_PREVIEW_SCRIPTED: {
// Shows scripted print preview in two stages.
// 1. PrintHostMsg_SetupScriptedPrintPreview blocks this call and JS by
// pumping messages here.
// 2. PrintHostMsg_ShowScriptedPrintPreview shows preview once the
// document has been loaded.
is_scripted_preview_delayed_ = true;
if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) {
// Wait for DidStopLoading. Plugins may not know the correct
// |is_modifiable| value until they are fully loaded, which occurs when
// DidStopLoading() is called. Defer showing the preview until then.
} else {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview,
weak_ptr_factory_.GetWeakPtr()));
}
IPC::SyncMessage* msg =
new PrintHostMsg_ScriptedPrintPreview(routing_id(), is_modifiable);
new PrintHostMsg_SetupScriptedPrintPreview(routing_id());
msg->EnableMessagePumping();
Send(msg);
is_scripted_preview_delayed_ = false;
return;
}
case PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME: {
......
......@@ -10,6 +10,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/public/renderer/render_view_observer.h"
#include "content/public/renderer/render_view_observer_tracker.h"
......@@ -112,6 +113,8 @@ class PrintWebViewHelper
// RenderViewObserver implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void PrintPage(WebKit::WebFrame* frame, bool user_initiated) OVERRIDE;
virtual void DidStartLoading() OVERRIDE;
virtual void DidStopLoading() OVERRIDE;
// Message handlers ---------------------------------------------------------
......@@ -326,6 +329,9 @@ class PrintWebViewHelper
// Scripted printing will be blocked for a limited amount of time.
void IncrementScriptedPrintCount();
// Shows scripted print preview when options from plugin are availible.
void ShowScriptedPrintPreview();
void RequestPrintPreview(PrintPreviewRequestType type);
// Checks whether print preview should continue or not.
......@@ -478,6 +484,9 @@ class PrintWebViewHelper
bool print_node_in_progress_;
PrintPreviewContext print_preview_context_;
bool is_loading_;
bool is_scripted_preview_delayed_;
base::WeakPtrFactory<PrintWebViewHelper> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment