diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 09:12:03 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 09:12:03 +0000 |
commit | c2e71d2e86657cad334fb2d778c3756878d1359b (patch) | |
tree | eb1e22e064c20618780a6afedbe333d52862a724 | |
parent | 29cd97871e733952ab4e05b5d9d7ea79d3a339d9 (diff) | |
download | chromium_src-c2e71d2e86657cad334fb2d778c3756878d1359b.zip chromium_src-c2e71d2e86657cad334fb2d778c3756878d1359b.tar.gz chromium_src-c2e71d2e86657cad334fb2d778c3756878d1359b.tar.bz2 |
Revert 110056 - Print Preview: Make print preview tab modal.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/8136027
TBR=thestig@chromium.org
Review URL: http://codereview.chromium.org/8564044
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110059 0039d316-1c4b-4281-b951-d872f2087c98
28 files changed, 698 insertions, 503 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 6b7bf1c..5d1935c 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -6318,6 +6318,15 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_PRINT_PREVIEW_INVALID_PRINTER_SETTINGS" desc="Message to display when selected printer is not reachable or its settings are invalid."> The selected printer is not available or not installed correctly. Check your printer or try selecting another printer. </message> + <message name="IDS_PRINT_PREVIEW_INITIATOR_TAB_CRASHED" desc="Error message displayed when print preview fails because the tab that initiated the print preview crashed."> + Print is unavailable because the page you were trying to print has crashed. + </message> + <message name="IDS_PRINT_PREVIEW_INITIATOR_TAB_CLOSED" desc="Error message displayed when print preview fails because the user closed the tab that initiated the print preview."> + Print is unavailable because the page you were trying to print has been closed. + </message> + <message name="IDS_PRINT_PREVIEW_REOPEN_PAGE" desc="Text for button displayed when print preview fails because the user closed the tab that initiated the print preview. Clicking the button reopens the page that was closed."> + Reopen the page + </message> <message name="IDS_PRINT_PREVIEW_PRINT_BUTTON" desc="Print button."> Print </message> diff --git a/chrome/browser/printing/background_printing_manager.cc b/chrome/browser/printing/background_printing_manager.cc index 3310e12..fc69730 100644 --- a/chrome/browser/printing/background_printing_manager.cc +++ b/chrome/browser/printing/background_printing_manager.cc @@ -66,6 +66,8 @@ void BackgroundPrintingManager::OwnPrintPreviewTab( content::Source<RenderProcessHost>(rph)); } + RemoveFromTabStrip(preview_tab); + // Activate the initiator tab. PrintPreviewTabController* tab_controller = PrintPreviewTabController::GetInstance(); @@ -79,6 +81,45 @@ void BackgroundPrintingManager::OwnPrintPreviewTab( initiator_tab->tab_contents())->Activate(); } +bool BackgroundPrintingManager::OwnInitiatorTab( + TabContentsWrapper* initiator_tab) { + DCHECK(CalledOnValidThread()); + DCHECK(!PrintPreviewTabController::IsPrintPreviewTab(initiator_tab)); + bool has_initiator_tab = false; + for (TabContentsWrapperMap::iterator it = map_.begin(); it != map_.end(); + ++it) { + if (it->second == initiator_tab) { + has_initiator_tab = true; + break; + } + } + CHECK(!has_initiator_tab); + + PrintPreviewTabController* tab_controller = + PrintPreviewTabController::GetInstance(); + if (!tab_controller) + return false; + TabContentsWrapper* preview_tab = + tab_controller->GetPrintPreviewForTab(initiator_tab); + if (!preview_tab) + return false; + + map_[preview_tab] = initiator_tab; + + // OwnPrintPreviewTab() may have already added this notification. + TabContents* preview_contents = preview_tab->tab_contents(); + if (!registrar_.IsRegistered( + this, + content::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContents>(preview_contents))) { + registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContents>(preview_contents)); + } + + RemoveFromTabStrip(initiator_tab); + return true; +} + void BackgroundPrintingManager::Observe( int type, const content::NotificationSource& source, @@ -129,15 +170,26 @@ void BackgroundPrintingManager::OnPrintJobReleased( void BackgroundPrintingManager::OnTabContentsDestroyed( TabContentsWrapper* preview_tab) { + bool is_owned_printing_tab = HasPrintPreviewTab(preview_tab); + bool is_preview_tab_for_owned_initator_tab = + (map_.find(preview_tab) != map_.end()); + DCHECK(is_owned_printing_tab || is_preview_tab_for_owned_initator_tab); + // Always need to remove this notification since the tab is gone. registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED, content::Source<TabContents>(preview_tab->tab_contents())); - if (!HasPrintPreviewTab(preview_tab)) { - NOTREACHED(); - return; + // Delete the associated initiator tab if one exists. + if (is_preview_tab_for_owned_initator_tab) { + TabContentsWrapper* initiator_tab = map_[preview_tab]; + map_.erase(preview_tab); + MessageLoop::current()->DeleteSoon(FROM_HERE, initiator_tab); } + // If |preview_tab| is not owned, then we are done. + if (!is_owned_printing_tab) + return; + // Remove NOTIFICATION_RENDERER_PROCESS_CLOSED if |preview_tab| is the last // TabContents associated with |rph|. bool shared_rph = HasSharedRenderProcessHost(printing_tabs_, preview_tab) || @@ -160,6 +212,18 @@ void BackgroundPrintingManager::OnTabContentsDestroyed( } } +void BackgroundPrintingManager::RemoveFromTabStrip(TabContentsWrapper* tab) { + Browser* browser = BrowserList::FindBrowserWithID( + tab->restore_tab_helper()->window_id().id()); + DCHECK(browser); + + TabStripModel* tabstrip = browser->tabstrip_model(); + int index = tabstrip->GetIndexOfTabContents(tab); + if (index == TabStripModel::kNoTab) + return; + tabstrip->DetachTabContentsAt(index); +} + void BackgroundPrintingManager::DeletePreviewTab(TabContentsWrapper* tab) { registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, content::Source<TabContentsWrapper>(tab)); diff --git a/chrome/browser/printing/background_printing_manager.h b/chrome/browser/printing/background_printing_manager.h index 81c2843..61fa684 100644 --- a/chrome/browser/printing/background_printing_manager.h +++ b/chrome/browser/printing/background_printing_manager.h @@ -35,6 +35,13 @@ class BackgroundPrintingManager : public base::NonThreadSafe, // hides it from the user. void OwnPrintPreviewTab(TabContentsWrapper* preview_tab); + // Takes ownership of |initiator_tab| and deletes it when its preview tab is + // destroyed by either being canceled, closed or finishing printing. This + // removes the TabContentsWrapper from its TabStrip and hides it from the + // user. Returns true if content has an associated print preview tab, + // otherwise, returns false and does not take ownership of |initiator_tab|. + bool OwnInitiatorTab(TabContentsWrapper* initiator_tab); + // Let others iterate over the list of background printing tabs. TabContentsWrapperSet::const_iterator begin(); TabContentsWrapperSet::const_iterator end(); @@ -48,11 +55,17 @@ class BackgroundPrintingManager : public base::NonThreadSafe, const content::NotificationDetails& details) OVERRIDE; private: + typedef std::map<TabContentsWrapper*, TabContentsWrapper*> + TabContentsWrapperMap; + // Notifications handlers. void OnRendererProcessClosed(RenderProcessHost* rph); void OnPrintJobReleased(TabContentsWrapper* preview_tab); void OnTabContentsDestroyed(TabContentsWrapper* preview_tab); + // Removes |tab| from its tab strip. + void RemoveFromTabStrip(TabContentsWrapper* tab); + // Add |tab| to the pending deletion set and schedule deletion. void DeletePreviewTab(TabContentsWrapper* tab); @@ -68,6 +81,13 @@ class BackgroundPrintingManager : public base::NonThreadSafe, // are pending deletion. TabContentsWrapperSet printing_tabs_pending_deletion_; + // 1:1 mapping between an initiator tab managed by BackgroundPrintingManager + // and its associated print preview tab. The print preview tab need not be in + // |printing_tabs_|. + // Key: print preview tab. + // Value: initiator tab. + TabContentsWrapperMap map_; + content::NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(BackgroundPrintingManager); diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc index d3e1cdf..b4037fc 100644 --- a/chrome/browser/printing/print_preview_message_handler.cc +++ b/chrome/browser/printing/print_preview_message_handler.cc @@ -13,13 +13,16 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/print_preview_tab_controller.h" +#include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/printing/printer_query.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/webui/print_preview_handler.h" #include "chrome/browser/ui/webui/print_preview_ui.h" #include "chrome/common/print_messages.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/content_restriction.h" #include "printing/page_size_margins.h" #include "printing/print_job_constants.h" @@ -178,6 +181,8 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting( return; } + print_preview_tab->print_view_manager()->OverrideTitle(tab_contents()); + // TODO(joth): This seems like a good match for using RefCountedStaticMemory // to avoid the memory copy, but the SetPrintPreviewData call chain below // needs updating to accept the RefCountedMemory* base class. @@ -247,16 +252,10 @@ bool PrintPreviewMessageHandler::OnMessageReceived( return handled; } -void PrintPreviewMessageHandler::NavigateToPendingEntry( - const GURL& url, - NavigationController::ReloadType reload_type) { - TabContentsWrapper* tab = tab_contents_wrapper(); - TabContentsWrapper* preview_tab = GetPrintPreviewTab(); - if (tab == preview_tab) { - // Cloud print sign-in reloads the page. - DCHECK(PrintPreviewTabController::IsPrintPreviewURL(url)); - DCHECK_EQ(NavigationController::RELOAD, reload_type); - return; +void PrintPreviewMessageHandler::DidStartLoading() { + if (tab_contents()->delegate() && + PrintPreviewTabController::IsPrintPreviewTab(tab_contents_wrapper())) { + tab_contents()->SetContentRestrictions(content::CONTENT_RESTRICTION_PRINT); } } diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h index f5de599..0f3d405 100644 --- a/chrome/browser/printing/print_preview_message_handler.h +++ b/chrome/browser/printing/print_preview_message_handler.h @@ -29,8 +29,7 @@ class PrintPreviewMessageHandler : public TabContentsObserver { // TabContentsObserver implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void NavigateToPendingEntry(const GURL& url, - NavigationController::ReloadType reload_type) OVERRIDE; + virtual void DidStartLoading() OVERRIDE; private: // Gets the print preview tab associated with the TabContents being observed. diff --git a/chrome/browser/printing/print_preview_tab_controller.cc b/chrome/browser/printing/print_preview_tab_controller.cc index 79e7763..8229b9f 100644 --- a/chrome/browser/printing/print_preview_tab_controller.cc +++ b/chrome/browser/printing/print_preview_tab_controller.cc @@ -4,9 +4,6 @@ #include "chrome/browser/printing/print_preview_tab_controller.h" -#include <algorithm> -#include <memory> -#include <string> #include <vector> #include "base/command_line.h" @@ -21,8 +18,6 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/browser/ui/webui/constrained_html_ui.h" -#include "chrome/browser/ui/webui/html_dialog_ui.h" #include "chrome/browser/ui/webui/print_preview_ui.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_switches.h" @@ -46,85 +41,8 @@ void EnableInternalPDFPluginForTab(TabContentsWrapper* preview_tab) { ASCIIToUTF16(chrome::ChromeContentClient::kPDFPluginName)); } -class PrintPreviewTabDelegate : public HtmlDialogUIDelegate { - public: - explicit PrintPreviewTabDelegate(TabContentsWrapper* initiator_tab); - virtual ~PrintPreviewTabDelegate(); - - virtual bool IsDialogModal() const OVERRIDE; - virtual string16 GetDialogTitle() const OVERRIDE; - virtual GURL GetDialogContentURL() const OVERRIDE; - virtual void GetWebUIMessageHandlers( - std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE; - virtual void GetDialogSize(gfx::Size* size) const OVERRIDE; - virtual std::string GetDialogArgs() const OVERRIDE; - virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE; - virtual void OnCloseContents(TabContents* source, - bool* out_close_dialog) OVERRIDE; - virtual bool ShouldShowDialogTitle() const OVERRIDE; - - private: - gfx::Size size_; - - DISALLOW_COPY_AND_ASSIGN(PrintPreviewTabDelegate); -}; - -PrintPreviewTabDelegate::PrintPreviewTabDelegate( - TabContentsWrapper* initiator_tab) { - const gfx::Size kMinDialogSize(800, 480); - const int kBorder = 50; - gfx::Rect rect; - initiator_tab->tab_contents()->GetContainerBounds(&rect); - size_.set_width(std::max(rect.width(), kMinDialogSize.width()) - kBorder); - size_.set_height(std::max(rect.height(), kMinDialogSize.height()) - kBorder); -} - -PrintPreviewTabDelegate::~PrintPreviewTabDelegate() { -} - -bool PrintPreviewTabDelegate::IsDialogModal() const { - // Not used, returning dummy value. - NOTREACHED(); - return true; -} - -string16 PrintPreviewTabDelegate::GetDialogTitle() const { - // Only used on Windows? UI folks prefer no title. - return string16(); -} - -GURL PrintPreviewTabDelegate::GetDialogContentURL() const { - return GURL(chrome::kChromeUIPrintURL); -} - -void PrintPreviewTabDelegate::GetWebUIMessageHandlers( - std::vector<WebUIMessageHandler*>* /* handlers */) const { - // PrintPreviewUI adds its own message handlers. -} - -void PrintPreviewTabDelegate::GetDialogSize(gfx::Size* size) const { - *size = size_; -} - -std::string PrintPreviewTabDelegate::GetDialogArgs() const { - return std::string(); -} - -void PrintPreviewTabDelegate::OnDialogClosed( - const std::string& /* json_retval */) { - delete this; -} - -void PrintPreviewTabDelegate::OnCloseContents(TabContents* /* source */, - bool* /* out_close_dialog */) { - // Not used, returning dummy value. - NOTREACHED(); -} - -bool PrintPreviewTabDelegate::ShouldShowDialogTitle() const { - // Not used, returning dummy value. - NOTREACHED(); - return false; +void ResetPreviewTabOverrideTitle(TabContentsWrapper* preview_tab) { + preview_tab->print_view_manager()->ResetTitleOverride(); } } // namespace @@ -164,9 +82,8 @@ TabContentsWrapper* PrintPreviewTabController::GetOrCreatePreviewTab( if (!preview_tab) return CreatePrintPreviewTab(initiator_tab); - // Show the initiator tab holding the existing preview tab. - static_cast<RenderViewHostDelegate*>( - initiator_tab->tab_contents())->Activate(); + // Show current preview tab. + static_cast<RenderViewHostDelegate*>(preview_tab->tab_contents())->Activate(); return preview_tab; } @@ -224,90 +141,109 @@ void PrintPreviewTabController::Observe( void PrintPreviewTabController::OnRendererProcessClosed( RenderProcessHost* rph) { - // Store tabs in a vector and deal with them after iterating through - // |preview_tab_map_| because RemoveFooTab() can change |preview_tab_map_|. - std::vector<TabContentsWrapper*> closed_initiator_tabs; - std::vector<TabContentsWrapper*> closed_preview_tabs; for (PrintPreviewTabMap::iterator iter = preview_tab_map_.begin(); iter != preview_tab_map_.end(); ++iter) { - TabContentsWrapper* preview_tab = iter->first; TabContentsWrapper* initiator_tab = iter->second; - if (preview_tab->render_view_host()->process() == rph) { - closed_preview_tabs.push_back(preview_tab); - } else if (initiator_tab && - initiator_tab->render_view_host()->process() == rph) { - closed_initiator_tabs.push_back(initiator_tab); + if (initiator_tab && + initiator_tab->render_view_host()->process() == rph) { + TabContentsWrapper* preview_tab = iter->first; + PrintPreviewUI* print_preview_ui = + static_cast<PrintPreviewUI*>(preview_tab->web_ui()); + print_preview_ui->OnInitiatorTabCrashed(); } } - - for (size_t i = 0; i < closed_preview_tabs.size(); ++i) { - RemovePreviewTab(closed_preview_tabs[i]); - PrintPreviewUI* print_preview_ui = - static_cast<PrintPreviewUI*>(closed_preview_tabs[i]->web_ui()); - if (print_preview_ui) - print_preview_ui->OnPrintPreviewTabClosed(); - } - - for (size_t i = 0; i < closed_initiator_tabs.size(); ++i) - RemoveInitiatorTab(closed_initiator_tabs[i]); } void PrintPreviewTabController::OnTabContentsDestroyed( TabContentsWrapper* tab) { TabContentsWrapper* preview_tab = GetPrintPreviewForTab(tab); - if (!preview_tab) { - NOTREACHED(); + if (!preview_tab) return; + + if (tab == preview_tab) { + // Remove the initiator tab's observers before erasing the mapping. + TabContentsWrapper* initiator_tab = GetInitiatorTab(tab); + if (initiator_tab) + RemoveObservers(initiator_tab); + + // Print preview tab contents are destroyed. Notify |PrintPreviewUI| to + // abort the initiator tab preview request. + if (IsPrintPreviewTab(tab) && tab->web_ui()) { + PrintPreviewUI* print_preview_ui = + static_cast<PrintPreviewUI*>(tab->web_ui()); + print_preview_ui->OnTabDestroyed(); + } + + // Erase the map entry. + preview_tab_map_.erase(tab); + } else { + // Initiator tab is closed. Disable the controls in preview tab. + if (preview_tab->web_ui()) { + PrintPreviewUI* print_preview_ui = + static_cast<PrintPreviewUI*>(preview_tab->web_ui()); + print_preview_ui->OnInitiatorTabClosed(); + } + + // |tab| is an initiator tab, update the map entry and remove observers. + preview_tab_map_[preview_tab] = NULL; } - if (tab == preview_tab) - RemovePreviewTab(tab); - else - RemoveInitiatorTab(tab); + ResetPreviewTabOverrideTitle(preview_tab); + RemoveObservers(tab); } void PrintPreviewTabController::OnNavEntryCommitted( TabContentsWrapper* tab, content::LoadCommittedDetails* details) { TabContentsWrapper* preview_tab = GetPrintPreviewForTab(tab); - if (!preview_tab) { - NOTREACHED(); - return; - } bool source_tab_is_preview_tab = (tab == preview_tab); - - if (source_tab_is_preview_tab) { - // Preview tab navigated. - if (details) { - content::PageTransition transition_type = - details->entry->transition_type(); - content::NavigationType nav_type = details->type; - - // New |preview_tab| is created. Don't update/erase map entry. - if (waiting_for_new_preview_page_ && - transition_type == content::PAGE_TRANSITION_START_PAGE && - nav_type == content::NAVIGATION_TYPE_NEW_PAGE) { - waiting_for_new_preview_page_ = false; + if (details) { + content::PageTransition transition_type = details->entry->transition_type(); + content::NavigationType nav_type = details->type; + + // Don't update/erase the map entry if the page has not changed. + if (transition_type == content::PAGE_TRANSITION_RELOAD || + nav_type == content::NAVIGATION_TYPE_SAME_PAGE) { + if (source_tab_is_preview_tab) SetInitiatorTabURLAndTitle(preview_tab); + return; + } - // Disabling the delegate will prevent all future navigation. - tab->tab_contents()->set_delegate(NULL); - return; - } + // New |preview_tab| is created. Don't update/erase map entry. + if (waiting_for_new_preview_page_ && + transition_type == content::PAGE_TRANSITION_LINK && + nav_type == content::NAVIGATION_TYPE_NEW_PAGE && + source_tab_is_preview_tab) { + waiting_for_new_preview_page_ = false; + SetInitiatorTabURLAndTitle(preview_tab); + return; + } - // Cloud print sign-in causes a reload. - if (!waiting_for_new_preview_page_ && - transition_type == content::PAGE_TRANSITION_RELOAD && - nav_type == content::NAVIGATION_TYPE_EXISTING_PAGE && - IsPrintPreviewURL(details->previous_url)) { - return; - } + // User navigated to a preview tab using forward/back button. + if (source_tab_is_preview_tab && + transition_type == content::PAGE_TRANSITION_FORWARD_BACK && + nav_type == content::NAVIGATION_TYPE_EXISTING_PAGE) { + return; } - NOTREACHED(); - return; } - // Initiator tab navigated. - RemoveInitiatorTab(tab); + RemoveObservers(tab); + ResetPreviewTabOverrideTitle(preview_tab); + if (source_tab_is_preview_tab) { + // Remove the initiator tab's observers before erasing the mapping. + TabContentsWrapper* initiator_tab = GetInitiatorTab(tab); + if (initiator_tab) + RemoveObservers(initiator_tab); + preview_tab_map_.erase(tab); + } else { + preview_tab_map_[preview_tab] = NULL; + + // Initiator tab is closed. Disable the controls in preview tab. + if (preview_tab->web_ui()) { + PrintPreviewUI* print_preview_ui = + static_cast<PrintPreviewUI*>(preview_tab->web_ui()); + print_preview_ui->OnInitiatorTabClosed(); + } + } } // static @@ -329,6 +265,7 @@ void PrintPreviewTabController::EraseInitiatorTabInfo( RemoveObservers(it->second); preview_tab_map_[preview_tab] = NULL; + ResetPreviewTabOverrideTitle(preview_tab); } TabContentsWrapper* PrintPreviewTabController::GetInitiatorTab( @@ -357,13 +294,25 @@ TabContentsWrapper* PrintPreviewTabController::CreatePrintPreviewTab( } } - HtmlDialogUIDelegate* delegate = new PrintPreviewTabDelegate(initiator_tab); - ConstrainedHtmlUIDelegate* html_delegate = - ConstrainedHtmlUI::CreateConstrainedHtmlDialog(current_browser->profile(), - delegate, - initiator_tab); - TabContentsWrapper* preview_tab = html_delegate->tab(); + // Add a new tab next to initiator tab. + browser::NavigateParams params(current_browser, + GURL(chrome::kChromeUIPrintURL), + content::PAGE_TRANSITION_LINK); + params.disposition = NEW_FOREGROUND_TAB; + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) + params.disposition = NEW_POPUP; + + // For normal tabs, set the position as immediately to the right, + // otherwise let the tab strip decide. + if (current_browser->is_type_tabbed()) { + params.tabstrip_index = current_browser->tabstrip_model()-> + GetIndexOfTabContents(initiator_tab) + 1; + } + + browser::Navigate(¶ms); + TabContentsWrapper* preview_tab = params.target_contents; EnableInternalPDFPluginForTab(preview_tab); + static_cast<RenderViewHostDelegate*>(preview_tab->tab_contents())->Activate(); // Add an entry to the map. preview_tab_map_[preview_tab] = initiator_tab; @@ -425,39 +374,4 @@ void PrintPreviewTabController::RemoveObservers(TabContentsWrapper* tab) { } } -void PrintPreviewTabController::RemoveInitiatorTab( - TabContentsWrapper* initiator_tab) { - TabContentsWrapper* preview_tab = GetPrintPreviewForTab(initiator_tab); - DCHECK(preview_tab); - // Update the map entry first, so when the print preview tab gets destroyed - // and reaches RemovePreviewTab(), it does not attempt to also remove the - // initiator tab's observers. - preview_tab_map_[preview_tab] = NULL; - RemoveObservers(initiator_tab); - - // Initiator tab is closed. Close the print preview tab too. - PrintPreviewUI* print_preview_ui = - static_cast<PrintPreviewUI*>(preview_tab->web_ui()); - if (print_preview_ui) - print_preview_ui->OnInitiatorTabClosed(); -} - -void PrintPreviewTabController::RemovePreviewTab( - TabContentsWrapper* preview_tab) { - // Remove the initiator tab's observers before erasing the mapping. - TabContentsWrapper* initiator_tab = GetInitiatorTab(preview_tab); - if (initiator_tab) - RemoveObservers(initiator_tab); - - // Print preview TabContents is destroyed. Notify |PrintPreviewUI| to abort - // the initiator tab preview request. - PrintPreviewUI* print_preview_ui = - static_cast<PrintPreviewUI*>(preview_tab->web_ui()); - if (print_preview_ui) - print_preview_ui->OnTabDestroyed(); - - preview_tab_map_.erase(preview_tab); - RemoveObservers(preview_tab); -} - } // namespace printing diff --git a/chrome/browser/printing/print_preview_tab_controller.h b/chrome/browser/printing/print_preview_tab_controller.h index 5df2144..ad21fbd 100644 --- a/chrome/browser/printing/print_preview_tab_controller.h +++ b/chrome/browser/printing/print_preview_tab_controller.h @@ -104,10 +104,6 @@ class PrintPreviewTabController void AddObservers(TabContentsWrapper* tab); void RemoveObservers(TabContentsWrapper* tab); - // Removes tabs when they close/crash/navigate. - void RemoveInitiatorTab(TabContentsWrapper* initiator_tab); - void RemovePreviewTab(TabContentsWrapper* preview_tab); - // Mapping between print preview tab and the corresponding initiator tab. PrintPreviewTabMap preview_tab_map_; diff --git a/chrome/browser/printing/print_preview_tab_controller_browsertest.cc b/chrome/browser/printing/print_preview_tab_controller_browsertest.cc index c870827..a17a892 100644 --- a/chrome/browser/printing/print_preview_tab_controller_browsertest.cc +++ b/chrome/browser/printing/print_preview_tab_controller_browsertest.cc @@ -2,53 +2,74 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/command_line.h" #include "chrome/browser/printing/print_preview_tab_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/browser/tab_contents/tab_contents.h" -#include "content/browser/tab_contents/tab_contents_observer.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "googleurl/src/gurl.h" namespace { -class PrintPreviewTabControllerBrowserTest : public InProcessBrowserTest { - public: - PrintPreviewTabControllerBrowserTest() {} - virtual ~PrintPreviewTabControllerBrowserTest() {} +typedef InProcessBrowserTest PrintPreviewTabControllerBrowserTest; - virtual void SetUpCommandLine(CommandLine* command_line) { - command_line->AppendSwitch(switches::kEnablePrintPreview); - } -}; +// Test to verify that when a preview tab navigates, we can create a new print +// preview tab for both initiator tab and new preview tab contents. +IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, + NavigateFromPrintPreviewTab) { + ASSERT_TRUE(browser()); + BrowserList::SetLastActive(browser()); + ASSERT_TRUE(BrowserList::GetLastActive()); -class TabDestroyedObserver : public TabContentsObserver { - public: - explicit TabDestroyedObserver(TabContents* contents) - : TabContentsObserver(contents), - tab_destroyed_(false) { - } - virtual ~TabDestroyedObserver() {} + // Lets start with one window with one tab. + EXPECT_EQ(1u, BrowserList::size()); + EXPECT_EQ(1, browser()->tab_count()); - bool tab_destroyed() { return tab_destroyed_; } + // Create a reference to initiator tab contents. + TabContentsWrapper* initiator_tab = + browser()->GetSelectedTabContentsWrapper(); + ASSERT_TRUE(initiator_tab); - private: - virtual void TabContentsDestroyed(TabContents* tab) { - tab_destroyed_ = true; - } + scoped_refptr<printing::PrintPreviewTabController> + tab_controller(new printing::PrintPreviewTabController()); + ASSERT_TRUE(tab_controller); - bool tab_destroyed_; -}; + // Get the preview tab for initiator tab. + TabContentsWrapper* preview_tab = + tab_controller->GetOrCreatePreviewTab(initiator_tab); + + // New print preview tab is created. Current focus is on preview tab. + EXPECT_EQ(2, browser()->tab_count()); + EXPECT_NE(initiator_tab, preview_tab); + + GURL url(chrome::kAboutBlankURL); + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_EQ(url, preview_tab->tab_contents()->GetURL()); + + // Get the print preview tab for initiator tab. + TabContentsWrapper* new_preview_tab = + tab_controller->GetOrCreatePreviewTab(initiator_tab); + + // New preview tab is created. + EXPECT_EQ(3, browser()->tab_count()); + EXPECT_NE(new_preview_tab, preview_tab); + + // Get the print preview tab for old preview tab. + TabContentsWrapper* newest_preview_tab = + tab_controller->GetOrCreatePreviewTab(preview_tab); + + // Newest preview tab is created and the previously created preview tab is not + // merely activated. + EXPECT_EQ(4, browser()->tab_count()); + EXPECT_NE(newest_preview_tab, new_preview_tab); +} // Test to verify that when a initiator tab navigates, we can create a new -// preview tab for the new tab contents. +// preview tab for the new tab contents. But we cannot create a preview tab for +// the old preview tab. IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, NavigateFromInitiatorTab) { ASSERT_TRUE(browser()); @@ -64,39 +85,44 @@ IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, browser()->GetSelectedTabContentsWrapper(); ASSERT_TRUE(initiator_tab); - printing::PrintPreviewTabController* tab_controller = - printing::PrintPreviewTabController::GetInstance(); + scoped_refptr<printing::PrintPreviewTabController> + tab_controller(new printing::PrintPreviewTabController()); ASSERT_TRUE(tab_controller); // Get the preview tab for initiator tab. TabContentsWrapper* preview_tab = tab_controller->GetOrCreatePreviewTab(initiator_tab); - // New print preview tab is created. - EXPECT_EQ(1, browser()->tab_count()); - ASSERT_TRUE(preview_tab); - ASSERT_NE(initiator_tab, preview_tab); - TabDestroyedObserver observer(preview_tab->tab_contents()); + // New print preview tab is created. Current focus is on preview tab. + EXPECT_EQ(2, browser()->tab_count()); + EXPECT_NE(initiator_tab, preview_tab); - // Navigate in the initiator tab. + // Activate initiator tab. + browser()->ActivateTabAt(0, true); GURL url(chrome::kChromeUINewTabURL); ui_test_utils::NavigateToURL(browser(), url); - ASSERT_TRUE(observer.tab_destroyed()); - // Get the print preview tab for initiator tab. TabContentsWrapper* new_preview_tab = tab_controller->GetOrCreatePreviewTab(initiator_tab); // New preview tab is created. - EXPECT_EQ(1, browser()->tab_count()); - EXPECT_TRUE(new_preview_tab); + EXPECT_EQ(3, browser()->tab_count()); + EXPECT_NE(new_preview_tab, preview_tab); + + // Get the print preview tab for old preview tab. + TabContentsWrapper* newest_preview_tab = + tab_controller->GetOrCreatePreviewTab(preview_tab); + + // Make sure preview tab is not created for |preview_tab|. + EXPECT_EQ(3, browser()->tab_count()); + EXPECT_EQ(newest_preview_tab, preview_tab); } -// Test to verify that after reloading the initiator tab, it creates a new -// print preview tab. +// Test to verify that even after reloading initiator tab and preview tab, +// their association exists. IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, - ReloadInitiatorTab) { + ReloadInitiatorTabAndPreviewTab) { ASSERT_TRUE(browser()); BrowserList::SetLastActive(browser()); ASSERT_TRUE(BrowserList::GetLastActive()); @@ -110,35 +136,119 @@ IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, browser()->GetSelectedTabContentsWrapper(); ASSERT_TRUE(initiator_tab); - printing::PrintPreviewTabController* tab_controller = - printing::PrintPreviewTabController::GetInstance(); + scoped_refptr<printing::PrintPreviewTabController> + tab_controller(new printing::PrintPreviewTabController()); ASSERT_TRUE(tab_controller); // Get the preview tab for initiator tab. TabContentsWrapper* preview_tab = tab_controller->GetOrCreatePreviewTab(initiator_tab); - // New print preview tab is created. - EXPECT_EQ(1, browser()->tab_count()); - ASSERT_TRUE(preview_tab); - ASSERT_NE(initiator_tab, preview_tab); - TabDestroyedObserver tab_destroyed_observer(preview_tab->tab_contents()); - - // Reload the initiator tab. - ui_test_utils::WindowedNotificationObserver notification_observer( - content::NOTIFICATION_LOAD_STOP, - content::NotificationService::AllSources()); - browser()->Reload(CURRENT_TAB); - notification_observer.Wait(); + // New print preview tab is created. Current focus is on preview tab. + EXPECT_EQ(2, browser()->tab_count()); + EXPECT_NE(initiator_tab, preview_tab); - ASSERT_TRUE(tab_destroyed_observer.tab_destroyed()); + // Activate initiator tab and reload. + browser()->ActivateTabAt(0, true); + browser()->Reload(CURRENT_TAB); // Get the print preview tab for initiator tab. TabContentsWrapper* new_preview_tab = tab_controller->GetOrCreatePreviewTab(initiator_tab); - EXPECT_EQ(1, browser()->tab_count()); - EXPECT_TRUE(new_preview_tab); + // Old preview tab is activated. + EXPECT_EQ(2, browser()->tab_count()); + EXPECT_EQ(new_preview_tab, preview_tab); + + // Reload preview tab. + browser()->Reload(CURRENT_TAB); + // Get the print preview tab for old preview tab. + TabContentsWrapper* newest_preview_tab = + tab_controller->GetOrCreatePreviewTab(preview_tab); + + // Make sure new preview tab is not created for |preview_tab|. + EXPECT_EQ(2, browser()->tab_count()); + EXPECT_EQ(newest_preview_tab, preview_tab); +} + +// Test that print preview tabs are placed correctly. +IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, + OpenPreviewTabInCorrectPosition) { + const int kTabCount = 4; + // Create kTabCount - 1 tabs since we start with 1 tab already. + for (int i = 0; i < kTabCount - 1; ++i) { + browser::NavigateParams p(browser(), GURL(), content::PAGE_TRANSITION_LINK); + p.disposition = NEW_FOREGROUND_TAB; + browser::Navigate(&p); + } + EXPECT_EQ(kTabCount, browser()->tab_count()); + + // Create a print preview tab. + scoped_refptr<printing::PrintPreviewTabController> + tab_controller(new printing::PrintPreviewTabController()); + ASSERT_TRUE(tab_controller); + + const int kInitiatorTabIndex = 1; + TabContentsWrapper* initiator_tab = + browser()->GetTabContentsWrapperAt(kInitiatorTabIndex); + ASSERT_TRUE(initiator_tab); + TabContentsWrapper* preview_tab = + tab_controller->GetOrCreatePreviewTab(initiator_tab); + EXPECT_TRUE(preview_tab); + + // Check the preview tab's location. + EXPECT_EQ(preview_tab, + browser()->GetTabContentsWrapperAt(kInitiatorTabIndex + 1)); + EXPECT_EQ(preview_tab, browser()->GetSelectedTabContentsWrapper()); +} + +// Test that print preview tabs created by pop-up windows are placed correctly. +IN_PROC_BROWSER_TEST_F(PrintPreviewTabControllerBrowserTest, + OpenPreviewTabFromPopupInCorrectPosition) { + const int kTabCount = 4; + // Create kTabCount - 1 tabs since we start with 1 tab already. + for (int i = 0; i < kTabCount - 1; ++i) { + browser::NavigateParams p(browser(), GURL(), content::PAGE_TRANSITION_LINK); + p.disposition = NEW_FOREGROUND_TAB; + browser::Navigate(&p); + } + EXPECT_EQ(kTabCount, browser()->tab_count()); + + // Create a popup + browser::NavigateParams p(browser(), GURL(), content::PAGE_TRANSITION_LINK); + p.disposition = NEW_POPUP; + ui_test_utils::NavigateToURL(&p); + + +#if defined(OS_CHROMEOS) + // Navigate() should have opened a new tab on CrOS. + EXPECT_EQ(browser(), p.browser); + EXPECT_EQ(Browser::TYPE_TABBED, p.browser->type()); +#else + // Navigate() should have opened a new popup window. + EXPECT_NE(browser(), p.browser); + EXPECT_EQ(Browser::TYPE_POPUP, p.browser->type()); +#endif + ASSERT_TRUE(p.target_contents); + + // Create a print preview tab. + scoped_refptr<printing::PrintPreviewTabController> + tab_controller(new printing::PrintPreviewTabController()); + ASSERT_TRUE(tab_controller); + + TabContentsWrapper* preview_tab = + tab_controller->GetOrCreatePreviewTab(p.target_contents); + EXPECT_TRUE(preview_tab); + + int tab_position = kTabCount; +#if defined(OS_CHROMEOS) + // Increment position since CrOS opened a new tab instead of a popup. + tab_position++; +#endif + + // Check the preview tab's location. + EXPECT_EQ(preview_tab, browser()->GetTabContentsWrapperAt(tab_position)); + EXPECT_EQ(preview_tab, browser()->GetSelectedTabContentsWrapper()); } } // namespace diff --git a/chrome/browser/printing/print_preview_tab_controller_unittest.cc b/chrome/browser/printing/print_preview_tab_controller_unittest.cc index 906dbc7..89bcedc9 100644 --- a/chrome/browser/printing/print_preview_tab_controller_unittest.cc +++ b/chrome/browser/printing/print_preview_tab_controller_unittest.cc @@ -42,8 +42,8 @@ TEST_F(PrintPreviewTabControllerUnitTest, GetOrCreatePreviewTab) { TabContentsWrapper* preview_tab = tab_controller->GetOrCreatePreviewTab(initiator_tab); - // New print preview tab is created. - EXPECT_EQ(1, browser()->tab_count()); + // New print preview tab is created. Current focus is on preview tab. + EXPECT_EQ(2, browser()->tab_count()); EXPECT_NE(initiator_tab, preview_tab); // Get the print preview tab for initiator tab. @@ -51,12 +51,62 @@ TEST_F(PrintPreviewTabControllerUnitTest, GetOrCreatePreviewTab) { tab_controller->GetOrCreatePreviewTab(initiator_tab); // Preview tab already exists. Tab count remains the same. - EXPECT_EQ(1, browser()->tab_count()); + EXPECT_EQ(2, browser()->tab_count()); // 1:1 relationship between initiator and preview tab. EXPECT_EQ(new_preview_tab, preview_tab); } +// Test to verify the initiator tab title is stored in |PrintPreviewUI| after +// preview tab reload. +TEST_F(PrintPreviewTabControllerUnitTest, TitleAfterReload) { + ASSERT_TRUE(browser()); + BrowserList::SetLastActive(browser()); + ASSERT_TRUE(BrowserList::GetLastActive()); + + // Lets start with one window with one tab. + EXPECT_EQ(1u, BrowserList::size()); + EXPECT_EQ(0, browser()->tab_count()); + browser()->NewTab(); + EXPECT_EQ(1, browser()->tab_count()); + + // Create a reference to initiator tab contents. + TabContentsWrapper* initiator_tab = + browser()->GetSelectedTabContentsWrapper(); + + scoped_refptr<printing::PrintPreviewTabController> + tab_controller(new printing::PrintPreviewTabController()); + ASSERT_TRUE(tab_controller); + + // Get the preview tab for initiator tab. + TabContentsWrapper* preview_tab = + tab_controller->GetOrCreatePreviewTab(initiator_tab); + + // New print preview tab is created. Current focus is on preview tab. + EXPECT_EQ(2, browser()->tab_count()); + EXPECT_NE(initiator_tab, preview_tab); + + // Set up a PrintPreviewUI for |preview_tab|. + PrintPreviewUI* preview_ui = new PrintPreviewUI(preview_tab->tab_contents()); + // RenderViewHostManager takes ownership of |preview_ui|. + preview_tab->tab_contents()->render_manager_for_testing()-> + SetWebUIPostCommit(preview_ui); + + // Simulate a reload event on |preview_tab|. + scoped_ptr<NavigationEntry> entry; + entry.reset(new NavigationEntry()); + entry->set_transition_type(content::PAGE_TRANSITION_RELOAD); + content::LoadCommittedDetails details; + details.type = content::NAVIGATION_TYPE_SAME_PAGE; + details.entry = entry.get(); + content::NotificationService::current()->Notify( + content::NOTIFICATION_NAV_ENTRY_COMMITTED, + content::Source<NavigationController>(&preview_tab->controller()), + content::Details<content::LoadCommittedDetails>(&details)); + EXPECT_EQ(initiator_tab->tab_contents()->GetTitle(), + preview_ui->initiator_tab_title_); +} + // To show multiple print preview tabs exist in the same browser for // different initiator tabs. If preview tab already exists for an initiator, it // gets focused. @@ -89,7 +139,7 @@ TEST_F(PrintPreviewTabControllerUnitTest, MultiplePreviewTabs) { tab_controller->GetOrCreatePreviewTab(tab_contents_1); EXPECT_NE(tab_contents_1, preview_tab_1); - EXPECT_EQ(2, browser()->tab_count()); + EXPECT_EQ(3, browser()->tab_count()); // Create preview tab for |tab_contents_2| TabContentsWrapper* preview_tab_2 = @@ -97,25 +147,23 @@ TEST_F(PrintPreviewTabControllerUnitTest, MultiplePreviewTabs) { EXPECT_NE(tab_contents_2, preview_tab_2); // 2 initiator tab and 2 preview tabs exist in the same browser. - // The preview tabs are constrained in their respective initiator tabs. - EXPECT_EQ(2, browser()->tab_count()); + EXPECT_EQ(4, browser()->tab_count()); TabStripModel* model = browser()->tabstrip_model(); ASSERT_TRUE(model); - int tab_1_index = model->GetIndexOfTabContents(tab_contents_1); - int tab_2_index = model->GetIndexOfTabContents(tab_contents_2); int preview_tab_1_index = model->GetIndexOfTabContents(preview_tab_1); int preview_tab_2_index = model->GetIndexOfTabContents(preview_tab_2); - EXPECT_EQ(-1, preview_tab_1_index); - EXPECT_EQ(-1, preview_tab_2_index); - EXPECT_EQ(tab_2_index, browser()->active_index()); + EXPECT_NE(-1, preview_tab_1_index); + EXPECT_NE(-1, preview_tab_2_index); + // Current tab is |preview_tab_2|. + EXPECT_EQ(preview_tab_2_index, browser()->active_index()); // When we get the preview tab for |tab_contents_1|, // |preview_tab_1| is activated and focused. tab_controller->GetOrCreatePreviewTab(tab_contents_1); - EXPECT_EQ(tab_1_index, browser()->active_index()); + EXPECT_EQ(preview_tab_1_index, browser()->active_index()); } // Clear the initiator tab details associated with preview tab. @@ -143,7 +191,7 @@ TEST_F(PrintPreviewTabControllerUnitTest, ClearInitiatorTabDetails) { tab_controller->GetOrCreatePreviewTab(initiator_tab); // New print preview tab is created. Current focus is on preview tab. - EXPECT_EQ(1, browser()->tab_count()); + EXPECT_EQ(2, browser()->tab_count()); EXPECT_NE(initiator_tab, preview_tab); // Clear the initiator tab details associated with the preview tab. @@ -154,6 +202,6 @@ TEST_F(PrintPreviewTabControllerUnitTest, ClearInitiatorTabDetails) { tab_controller->GetOrCreatePreviewTab(initiator_tab); // New preview tab is created. - EXPECT_EQ(1, browser()->tab_count()); + EXPECT_EQ(3, browser()->tab_count()); EXPECT_NE(new_preview_tab, preview_tab); } diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 77dda24..6d4ddcd 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -33,6 +33,13 @@ using content::BrowserThread; namespace { +string16 GenerateRenderSourceName(TabContents* tab_contents) { + string16 name(tab_contents->GetTitle()); + if (name.empty()) + name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); + return name; +} + // Release the PrinterQuery identified by |cookie|. void ReleasePrinterQuery(int cookie) { printing::PrintJobManager* print_job_manager = @@ -60,6 +67,7 @@ PrintViewManager::PrintViewManager(TabContentsWrapper* tab) number_pages_(0), printing_succeeded_(false), inside_inner_message_loop_(false), + is_title_overridden_(false), observer_(NULL), cookie_(0) { #if defined(OS_POSIX) && !defined(OS_MACOSX) @@ -118,6 +126,10 @@ void PrintViewManager::set_observer(PrintViewManagerObserver* observer) { observer_ = observer; } +void PrintViewManager::ResetTitleOverride() { + is_title_overridden_ = false; +} + void PrintViewManager::StopNavigation() { // Cancel the current job, wait for the worker to finish. TerminatePrintJob(true); @@ -136,11 +148,15 @@ void PrintViewManager::RenderViewGone() { } } +void PrintViewManager::OverrideTitle(TabContents* tab_contents) { + is_title_overridden_ = true; + overridden_title_ = GenerateRenderSourceName(tab_contents); +} + string16 PrintViewManager::RenderSourceName() { - string16 name(tab_contents()->GetTitle()); - if (name.empty()) - name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); - return name; + if (is_title_overridden_) + return overridden_title_; + return GenerateRenderSourceName(tab_contents()); } void PrintViewManager::OnDidGetPrintedPagesCount(int cookie, int number_pages) { diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h index 58fcefb..d75e3d8 100644 --- a/chrome/browser/printing/print_view_manager.h +++ b/chrome/browser/printing/print_view_manager.h @@ -33,6 +33,10 @@ class PrintViewManager : public content::NotificationObserver, explicit PrintViewManager(TabContentsWrapper* tab); virtual ~PrintViewManager(); + // Override the title for this PrintViewManager's PrintJobs using the title + // in |tab_contents|. + void OverrideTitle(TabContents* tab_contents); + // Prints the current document immediately. Since the rendering is // asynchronous, the actual printing will not be completed on the return of // this function. Returns false if printing is impossible at the moment. @@ -61,6 +65,9 @@ class PrintViewManager : public content::NotificationObserver, // must be NULL if |observer| is non-NULL. void set_observer(PrintViewManagerObserver* observer); + // Reset |is_title_overridden_| to false. + void ResetTitleOverride(); + // PrintedPagesSource implementation. virtual string16 RenderSourceName() OVERRIDE; @@ -161,6 +168,10 @@ class PrintViewManager : public content::NotificationObserver, bool expecting_first_page_; #endif + // Title override. + bool is_title_overridden_; + string16 overridden_title_; + // Weak pointer to an observer that is notified when the print dialog is // shown. PrintViewManagerObserver* observer_; diff --git a/chrome/browser/resources/print_preview/print_header.js b/chrome/browser/resources/print_preview/print_header.js index 6443b59..4e8fcaf 100644 --- a/chrome/browser/resources/print_preview/print_header.js +++ b/chrome/browser/resources/print_preview/print_header.js @@ -53,14 +53,6 @@ cr.define('print_preview', function() { }, /** - * Enables the cancel button and attaches its keydown event listener. - */ - enableCancelButton: function() { - window.onkeydown = onKeyDown; - this.cancelButton_.disabled = false; - }, - - /** * Executes when a |customEvents.PDF_GENERATION_ERROR| event occurs. * @private */ diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js index dc7d77f..036f549 100644 --- a/chrome/browser/resources/print_preview/print_preview.js +++ b/chrome/browser/resources/print_preview/print_preview.js @@ -206,7 +206,6 @@ function onSystemDialogLinkClicked() { return; showingSystemDialog = true; disableInputElementsInSidebar(); - printHeader.disableCancelButton(); $('system-dialog-throbber').hidden = false; chrome.send('showSystemDialog'); } @@ -226,6 +225,42 @@ function launchNativePrintDialog() { } /** + * Disables the controls which need the initiator tab to generate preview + * data. This function is called when the initiator tab has crashed. + * @param {string} initiatorTabURL The URL of the initiator tab. + */ +function onInitiatorTabCrashed(initiatorTabURL) { + disableInputElementsInSidebar(); + if (initiatorTabURL) { + previewArea.displayErrorMessageWithButtonAndNotify( + localStrings.getString('initiatorTabCrashed'), + localStrings.getString('reopenPage'), + function() { chrome.send('reloadCrashedInitiatorTab'); }); + } else { + previewArea.displayErrorMessageAndNotify( + localStrings.getString('initiatorTabCrashed')); + } +} + +/** + * Disables the controls which need the initiator tab to generate preview + * data. This function is called when the initiator tab is closed. + * @param {string} initiatorTabURL The URL of the initiator tab. + */ +function onInitiatorTabClosed(initiatorTabURL) { + disableInputElementsInSidebar(); + if (initiatorTabURL) { + previewArea.displayErrorMessageWithButtonAndNotify( + localStrings.getString('initiatorTabClosed'), + localStrings.getString('reopenPage'), + function() { window.location = initiatorTabURL; }); + } else { + previewArea.displayErrorMessageAndNotify( + localStrings.getString('initiatorTabClosed')); + } +} + +/** * Gets the selected printer capabilities and updates the controls accordingly. */ function updateControlsWithSelectedPrinterCapabilities() { @@ -304,16 +339,6 @@ function updateWithPrinterCapabilities(settingInfo) { } /** - * Reloads the printer list. - */ -function reloadPrintersList() { - $('printer-list').length = 0; - firstCloudPrintOptionPos = 0; - lastCloudPrintOptionPos = 0; - chrome.send('getPrinters'); -} - -/** * Turn on the integration of Cloud Print. * @param {string} cloudPrintUrl The URL to use for cloud print servers. */ @@ -335,7 +360,7 @@ function printToCloud(data) { * Cloud print upload of the PDF file is finished, time to close the dialog. */ function finishedCloudPrinting() { - closePrintPreviewTab(); + window.location = cloudprint.getBaseURL(); } /** @@ -553,7 +578,7 @@ function requestPrintPreview() { * preview tab regarding the file selection cancel event. */ function fileSelectionCancelled() { - printHeader.enableCancelButton(); + // TODO(thestig) re-enable controls here. } /** @@ -594,7 +619,7 @@ function setDefaultPrinter(printerName, cloudPrintData) { /** * Fill the printer list drop down. - * Called from PrintPreviewHandler::SetupPrinterList(). + * Called from PrintPreviewHandler::SendPrinterList(). * @param {Array} printers Array of printer info objects. */ function setPrinters(printers) { @@ -1060,7 +1085,6 @@ function setInitiatorTabTitle(initiatorTabTitle) { */ function closePrintPreviewTab() { chrome.send('closePrintPreviewTab'); - chrome.send('DialogClose'); } /** @@ -1073,13 +1097,6 @@ function onKeyDown(e) { printHeader.disableCancelButton(); closePrintPreviewTab(); } - if (e.keyCode == 80) { - if ((cr.isMac && e.metaKey && e.altKey && !e.shiftKey && !e.ctrlKey) || - (!cr.isMac && e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey)) { - window.onkeydown = null; - onSystemDialogLinkClicked(); - } - } } window.addEventListener('DOMContentLoaded', onLoad); diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index a00469c..49d66f9 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -69,6 +69,7 @@ #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prerender/prerender_tab_helper.h" +#include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" #include "chrome/browser/printing/print_preview_tab_controller.h" #include "chrome/browser/printing/print_view_manager.h" @@ -3551,6 +3552,19 @@ void Browser::CloseContents(TabContents* source) { return; } + // Various sites have a pattern which open a new window with output formatted + // for printing, then include a print button, which does window.print(); + // window.close(); An example is printing Virgin America boarding + // pass. Instead of closing, when a print tab is associated with this tab, + // tell the BackgroundPrintingManager to own it, which causes it to be + // hidden and eventually closed when the print window is closed. + TabContentsWrapper* source_wrapper = + TabContentsWrapper::GetCurrentWrapperForContents(source); + if (g_browser_process->background_printing_manager()-> + OwnInitiatorTab(source_wrapper)) { + return; + } + int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source); if (index == TabStripModel::kNoTab) { NOTREACHED() << "CloseContents called for tab not in our strip"; @@ -3833,21 +3847,6 @@ void Browser::ContentRestrictionsChanged(TabContents* source) { } void Browser::RendererUnresponsive(TabContents* source) { - // Ignore hangs if print preview is open. - TabContentsWrapper* source_wrapper = - TabContentsWrapper::GetCurrentWrapperForContents(source); - if (source_wrapper) { - printing::PrintPreviewTabController* controller = - printing::PrintPreviewTabController::GetInstance(); - if (controller) { - TabContentsWrapper* preview_tab = - controller->GetPrintPreviewForTab(source_wrapper); - if (preview_tab && preview_tab != source_wrapper) { - return; - } - } - } - browser::ShowHungRendererDialog(source); } @@ -4791,7 +4790,9 @@ void Browser::UpdatePrintingState(int content_restrictions) { // where advanced printing is always enabled. printing::PrintPreviewTabController* controller = printing::PrintPreviewTabController::GetInstance(); - if (controller && controller->GetPrintPreviewForTab(wrapper)) { + if (controller && + wrapper && + wrapper == controller->GetPrintPreviewForTab(wrapper)) { advanced_print_enabled = true; } } diff --git a/chrome/browser/ui/browser_list_unittest.cc b/chrome/browser/ui/browser_list_unittest.cc index abb7077..f9e4716 100644 --- a/chrome/browser/ui/browser_list_unittest.cc +++ b/chrome/browser/ui/browser_list_unittest.cc @@ -158,8 +158,6 @@ TEST_F(BrowserListTest, TabContentsIteratorVerifyBrowser) { browser3->CloseAllTabs(); } -#if 0 -// TODO(thestig) Fix or remove this test. http://crbug.com/100309 TEST_F(BrowserListTest, TabContentsIteratorBackgroundPrinting) { // Make sure we have 1 window to start with. EXPECT_EQ(1U, BrowserList::size()); @@ -240,4 +238,3 @@ TEST_F(BrowserListTest, TabContentsIteratorBackgroundPrinting) { EXPECT_EQ(0U, CountAllTabs()); } -#endif diff --git a/chrome/browser/ui/webui/cloud_print_signin_dialog.cc b/chrome/browser/ui/webui/cloud_print_signin_dialog.cc index c163447..20f3bfc 100644 --- a/chrome/browser/ui/webui/cloud_print_signin_dialog.cc +++ b/chrome/browser/ui/webui/cloud_print_signin_dialog.cc @@ -4,9 +4,6 @@ #include "chrome/browser/ui/webui/cloud_print_signin_dialog.h" -#include <string> -#include <vector> - #include "base/bind.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/printing/cloud_print/cloud_print_url.h" @@ -14,7 +11,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/webui/html_dialog_ui.h" -#include "chrome/browser/ui/webui/print_preview_ui.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_view_host.h" @@ -83,8 +79,7 @@ void CloudPrintSigninFlowHandler::Observe( url.scheme() == dialog_url.scheme()) { StoreDialogSize(); web_ui_->tab_contents()->render_view_host()->ClosePage(); - static_cast<PrintPreviewUI*>( - parent_tab_->web_ui())->OnReloadPrintersList(); + parent_tab_->controller().Reload(false); } } } @@ -192,3 +187,4 @@ void CreateCloudPrintSigninDialog(TabContents* parent_tab) { base::Bind(&CreateCloudPrintSigninDialogImpl, parent_tab)); } } // namespace cloud_print_signin_dialog + diff --git a/chrome/browser/ui/webui/constrained_html_ui.h b/chrome/browser/ui/webui/constrained_html_ui.h index 03d2022..fd8f276 100644 --- a/chrome/browser/ui/webui/constrained_html_ui.h +++ b/chrome/browser/ui/webui/constrained_html_ui.h @@ -65,12 +65,11 @@ class ConstrainedHtmlUI : public ChromeWebUI { static PropertyAccessor<ConstrainedHtmlUIDelegate*>& GetPropertyAccessor(); - protected: + private: // Returns the TabContents' PropertyBag's ConstrainedHtmlUIDelegate. // Returns NULL if that property is not set. ConstrainedHtmlUIDelegate* GetConstrainedDelegate(); - private: // JS Message Handler void OnDialogCloseMessage(const base::ListValue* args); diff --git a/chrome/browser/ui/webui/print_preview_data_source.cc b/chrome/browser/ui/webui/print_preview_data_source.cc index b3a45d6..3621859 100644 --- a/chrome/browser/ui/webui/print_preview_data_source.cc +++ b/chrome/browser/ui/webui/print_preview_data_source.cc @@ -51,6 +51,12 @@ PrintPreviewDataSource::PrintPreviewDataSource() AddLocalizedString("previewFailed", IDS_PRINT_PREVIEW_FAILED); AddLocalizedString("invalidPrinterSettings", IDS_PRINT_PREVIEW_INVALID_PRINTER_SETTINGS); + AddLocalizedString("initiatorTabCrashed", + IDS_PRINT_PREVIEW_INITIATOR_TAB_CRASHED); + AddLocalizedString("initiatorTabClosed", + IDS_PRINT_PREVIEW_INITIATOR_TAB_CLOSED); + AddLocalizedString("reopenPage", IDS_PRINT_PREVIEW_REOPEN_PAGE); + AddLocalizedString("printButton", IDS_PRINT_PREVIEW_PRINT_BUTTON); AddLocalizedString("cancelButton", IDS_PRINT_PREVIEW_CANCEL_BUTTON); AddLocalizedString("printing", IDS_PRINT_PREVIEW_PRINTING); diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc index f3fb0df..5bf6e85 100644 --- a/chrome/browser/ui/webui/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview_handler.cc @@ -25,6 +25,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/cloud_print/cloud_print_url.h" #include "chrome/browser/printing/print_dialog_cloud.h" #include "chrome/browser/printing/print_job_manager.h" @@ -33,6 +34,8 @@ #include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/printing/printer_manager_dialog.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sessions/restore_tab_helper.h" +#include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/webui/cloud_print_signin_dialog.h" @@ -67,7 +70,7 @@ enum UserActionBuckets { FALLBACK_TO_ADVANCED_SETTINGS_DIALOG, PREVIEW_FAILED, PREVIEW_STARTED, - INITIATOR_TAB_CRASHED, // UNUSED + INITIATOR_TAB_CRASHED, INITIATOR_TAB_CLOSED, PRINT_WITH_CLOUD_PRINT, USERACTION_BUCKET_BOUNDARY @@ -173,6 +176,10 @@ void ReportPrintSettingsStats(const DictionaryValue& settings) { } } +printing::BackgroundPrintingManager* GetBackgroundPrintingManager() { + return g_browser_process->background_printing_manager(); +} + } // namespace // A Task implementation that stores a PDF file on disk. @@ -253,6 +260,9 @@ void PrintPreviewHandler::RegisterMessages() { web_ui_->RegisterMessageCallback("manageLocalPrinters", base::Bind(&PrintPreviewHandler::HandleManagePrinters, base::Unretained(this))); + web_ui_->RegisterMessageCallback("reloadCrashedInitiatorTab", + base::Bind(&PrintPreviewHandler::HandleReloadCrashedInitiatorTab, + base::Unretained(this))); web_ui_->RegisterMessageCallback("closePrintPreviewTab", base::Bind(&PrintPreviewHandler::HandleClosePreviewTab, base::Unretained(this))); @@ -312,7 +322,7 @@ void PrintPreviewHandler::HandleGetPreview(const ListValue* args) { TabContentsWrapper* initiator_tab = GetInitiatorTab(); if (!initiator_tab) { ReportUserActionHistogram(INITIATOR_TAB_CLOSED); - print_preview_ui->OnClosePrintPreviewTab(); + print_preview_ui->OnInitiatorTabClosed(); return; } @@ -422,8 +432,7 @@ void PrintPreviewHandler::HandlePrint(const ListValue* args) { // This tries to activate the initiator tab as well, so do not clear the // association with the initiator tab yet. - PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(web_ui_); - print_preview_ui->OnHidePreviewTab(); + HidePreviewTab(); // Do this so the initiator tab can open a new print preview tab. ClearInitiatorTabDetails(); @@ -467,8 +476,7 @@ void PrintPreviewHandler::HandlePrintToPdf( } void PrintPreviewHandler::HandleHidePreview(const ListValue* /*args*/) { - PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(web_ui_); - print_preview_ui->OnHidePreviewTab(); + HidePreviewTab(); } void PrintPreviewHandler::HandleCancelPendingPrintRequest( @@ -579,6 +587,21 @@ void PrintPreviewHandler::HandleManagePrinters(const ListValue* /*args*/) { printing::PrinterManagerDialog::ShowPrinterManagerDialog(); } +void PrintPreviewHandler::HandleReloadCrashedInitiatorTab( + const ListValue* /*args*/) { + ReportStats(); + ReportUserActionHistogram(INITIATOR_TAB_CRASHED); + + TabContentsWrapper* initiator_tab = GetInitiatorTab(); + if (!initiator_tab) + return; + + TabContents* contents = initiator_tab->tab_contents(); + contents->OpenURL(contents->GetURL(), GURL(), CURRENT_TAB, + content::PAGE_TRANSITION_RELOAD); + ActivateInitiatorTabAndClosePreviewTab(); +} + void PrintPreviewHandler::HandleClosePreviewTab(const ListValue* /*args*/) { ReportStats(); ReportUserActionHistogram(CANCEL); @@ -587,6 +610,8 @@ void PrintPreviewHandler::HandleClosePreviewTab(const ListValue* /*args*/) { // before cancelling. UMA_HISTOGRAM_COUNTS("PrintPreview.RegeneratePreviewRequest.BeforeCancel", regenerate_preview_request_count_); + + ActivateInitiatorTabAndClosePreviewTab(); } void PrintPreviewHandler::ReportStats() { @@ -663,8 +688,7 @@ void PrintPreviewHandler::ActivateInitiatorTabAndClosePreviewTab() { static_cast<RenderViewHostDelegate*>( initiator_tab->tab_contents())->Activate(); } - PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(web_ui_); - print_preview_ui->OnClosePrintPreviewTab(); + ClosePrintPreviewTab(); } void PrintPreviewHandler::SendPrinterCapabilities( @@ -703,7 +727,7 @@ void PrintPreviewHandler::SendCloudPrintJob(const DictionaryValue& settings, std::string print_job_title = UTF16ToUTF8(print_job_title_utf16); std::string printer_id; settings.GetString(printing::kSettingCloudPrintId, &printer_id); - // BASE64 encode the job data. +// BASE64 encode the job data. std::string raw_data(reinterpret_cast<const char*>(data->front()), data->size()); std::string base64_data; @@ -725,8 +749,8 @@ void PrintPreviewHandler::SendCloudPrintJob(const DictionaryValue& settings, "data:application/pdf;base64,%s\r\n" "--%s\r\n"; - // TODO(abodenha@chromium.org) This implies a large copy operation. - // Profile this and optimize if necessary. +// TODO(abodenha@chromium.org) This implies a large copy operation. +// Profile this and optimize if necessary. std::string final_data; base::SStringPrintf(&final_data, prolog, @@ -755,6 +779,25 @@ TabContentsWrapper* PrintPreviewHandler::GetInitiatorTab() const { return tab_controller->GetInitiatorTab(preview_tab_wrapper()); } +void PrintPreviewHandler::ClosePrintPreviewTab() { + TabContentsWrapper* tab = + TabContentsWrapper::GetCurrentWrapperForContents(preview_tab()); + if (!tab) + return; + Browser* preview_tab_browser = BrowserList::FindBrowserWithID( + tab->restore_tab_helper()->window_id().id()); + if (!preview_tab_browser) + return; + TabStripModel* tabstrip = preview_tab_browser->tabstrip_model(); + int index = tabstrip->GetIndexOfTabContents(tab); + if (index == TabStripModel::kNoTab) + return; + + // Keep print preview tab out of the recently closed tab list, because + // re-opening that page will just display a non-functional print preview page. + tabstrip->CloseTabContentsAt(index, TabStripModel::CLOSE_NONE); +} + void PrintPreviewHandler::OnPrintDialogShown() { ActivateInitiatorTabAndClosePreviewTab(); } @@ -843,6 +886,12 @@ void PrintPreviewHandler::FileSelectionCanceled(void* params) { print_preview_ui->OnFileSelectionCancelled(); } +void PrintPreviewHandler::HidePreviewTab() { + if (GetBackgroundPrintingManager()->HasPrintPreviewTab(preview_tab_wrapper())) + return; + GetBackgroundPrintingManager()->OwnPrintPreviewTab(preview_tab_wrapper()); +} + void PrintPreviewHandler::ClearInitiatorTabDetails() { TabContentsWrapper* initiator_tab = GetInitiatorTab(); if (!initiator_tab) diff --git a/chrome/browser/ui/webui/print_preview_handler.h b/chrome/browser/ui/webui/print_preview_handler.h index 8d0315c..20ea1c7 100644 --- a/chrome/browser/ui/webui/print_preview_handler.h +++ b/chrome/browser/ui/webui/print_preview_handler.h @@ -124,9 +124,9 @@ class PrintPreviewHandler : public WebUIMessageHandler, // |args| is unused. void HandleManageCloudPrint(const base::ListValue* args); - // Gathers UMA stats when the print preview tab is about to close. - // |args| is unused. - void HandleClosePreviewTab(const base::ListValue* args); + // Reloads the initiator tab and closes the associated preview tab. |args| is + // unused. + void HandleReloadCrashedInitiatorTab(const base::ListValue* args); // Asks the browser to show the native printer management dialog. // |args| is unused. @@ -135,6 +135,9 @@ class PrintPreviewHandler : public WebUIMessageHandler, // Asks the browser to show the cloud print dialog. void HandlePrintWithCloudPrint(); + // Asks the browser to close the preview tab. |args| is unused. + void HandleClosePreviewTab(const base::ListValue* args); + // Asks the browser for several settings that are needed before the first // preview is displayed. void HandleGetInitialSettings(const base::ListValue* args); @@ -160,12 +163,18 @@ class PrintPreviewHandler : public WebUIMessageHandler, // Gets the initiator tab for the print preview tab. TabContentsWrapper* GetInitiatorTab() const; + // Closes the print preview tab. + void ClosePrintPreviewTab(); + // Activates the initiator tab and close the preview tab. void ActivateInitiatorTabAndClosePreviewTab(); // Adds all the recorded stats taken so far to histogram counts. void ReportStats(); + // Hides the preview tab for printing. + void HidePreviewTab(); + // Clears initiator tab details for this preview tab. void ClearInitiatorTabDetails(); diff --git a/chrome/browser/ui/webui/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview_handler_unittest.cc index 3d7fdb3..d44ce53 100644 --- a/chrome/browser/ui/webui/print_preview_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview_handler_unittest.cc @@ -21,7 +21,7 @@ namespace { DictionaryValue* GetCustomMarginsDictionary( const double margin_top, const double margin_right, - const double margin_bottom, const double margin_left) { + const double margin_bottom,const double margin_left) { base::DictionaryValue* custom_settings = new base::DictionaryValue(); custom_settings->SetDouble(printing::kSettingMarginTop, margin_top); custom_settings->SetDouble(printing::kSettingMarginRight, margin_right); @@ -30,7 +30,7 @@ DictionaryValue* GetCustomMarginsDictionary( return custom_settings; } -} // namespace +} class PrintPreviewHandlerTest : public BrowserWithTestWindowTest { protected: @@ -65,6 +65,7 @@ class PrintPreviewHandlerTest : public BrowserWithTestWindowTest { preview_tab_ = controller->GetOrCreatePreviewTab(initiator_tab); ASSERT_TRUE(preview_tab_); + EXPECT_EQ(2, browser()->tab_count()); preview_ui_ = static_cast<PrintPreviewUI*>(preview_tab_->web_ui()); ASSERT_TRUE(preview_ui_); @@ -113,7 +114,7 @@ class PrintPreviewHandlerTest : public BrowserWithTestWindowTest { void RequestPrintWithCustomMargins( const double margin_top, const double margin_right, - const double margin_bottom, const double margin_left) { + const double margin_bottom,const double margin_left) { // Set the minimal dummy settings to make the HandlePrint() code happy. DictionaryValue settings; settings.SetBoolean(printing::kSettingPreviewModifiable, true); @@ -145,6 +146,7 @@ class PrintPreviewHandlerTest : public BrowserWithTestWindowTest { delete PrintPreviewHandler::last_used_page_size_margins_; PrintPreviewHandler::last_used_page_size_margins_ = NULL; } + }; // Tests that margin settings are saved correctly when printing with custom @@ -196,6 +198,7 @@ TEST_F(PrintPreviewHandlerTest, StickyMarginsCustomThenDefault) { CheckCustomMargins(kMarginTop, kMarginRight, kMarginBottom, kMarginLeft); OpenPrintPreviewTab(); + EXPECT_EQ(2, browser()->tab_count()); RequestPrintWithDefaultMargins(); // Checking that sticky settings were saved correctly. diff --git a/chrome/browser/ui/webui/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview_ui.cc index 0faac66..fc7684e4 100644 --- a/chrome/browser/ui/webui/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview_ui.cc @@ -11,12 +11,8 @@ #include "base/string_util.h" #include "base/synchronization/lock.h" #include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/print_preview_data_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/browser/ui/webui/html_dialog_ui.h" #include "chrome/browser/ui/webui/print_preview_data_source.h" #include "chrome/browser/ui/webui/print_preview_handler.h" #include "chrome/common/print_messages.h" @@ -71,9 +67,8 @@ base::LazyInstance<PrintPreviewRequestIdMapWithLock> } // namespace PrintPreviewUI::PrintPreviewUI(TabContents* contents) - : ConstrainedHtmlUI(contents), - initial_preview_start_time_(base::TimeTicks::Now()), - tab_closed_(false) { + : ChromeWebUI(contents), + initial_preview_start_time_(base::TimeTicks::Now()) { // WebUI owns |handler_|. handler_ = new PrintPreviewHandler(); AddMessageHandler(handler_->Attach(this)); @@ -146,25 +141,14 @@ std::string PrintPreviewUI::GetPrintPreviewUIAddress() const { return preview_ui_addr; } -void PrintPreviewUI::OnPrintPreviewTabClosed() { - TabContentsWrapper* preview_tab = - TabContentsWrapper::GetCurrentWrapperForContents(tab_contents()); - printing::BackgroundPrintingManager* background_printing_manager = - g_browser_process->background_printing_manager(); - if (background_printing_manager->HasPrintPreviewTab(preview_tab)) - return; - OnClosePrintPreviewTab(); +void PrintPreviewUI::OnInitiatorTabCrashed() { + StringValue initiator_tab_url(initiator_url_); + CallJavascriptFunction("onInitiatorTabCrashed", initiator_tab_url); } void PrintPreviewUI::OnInitiatorTabClosed() { - TabContentsWrapper* preview_tab = - TabContentsWrapper::GetCurrentWrapperForContents(tab_contents()); - printing::BackgroundPrintingManager* background_printing_manager = - g_browser_process->background_printing_manager(); - if (background_printing_manager->HasPrintPreviewTab(preview_tab)) - CallJavascriptFunction("cancelPendingPrintRequest"); - else - OnClosePrintPreviewTab(); + StringValue initiator_tab_url(initiator_url_); + CallJavascriptFunction("onInitiatorTabClosed", initiator_tab_url); } void PrintPreviewUI::OnPrintPreviewRequest(int request_id) { @@ -180,7 +164,7 @@ void PrintPreviewUI::OnDidGetPreviewPageCount( DCHECK_GT(params.page_count, 0); base::FundamentalValue count(params.page_count); base::FundamentalValue request_id(params.preview_request_id); - CallJavascriptFunction("onDidGetPreviewPageCount", count, request_id); + CallJavascriptFunction("onDidGetPreviewPageCount", count,request_id); } void PrintPreviewUI::OnDidGetDefaultPageLayout( @@ -261,34 +245,3 @@ void PrintPreviewUI::OnInvalidPrinterSettings() { PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() { return PrintPreviewDataService::GetInstance(); } - -void PrintPreviewUI::OnHidePreviewTab() { - TabContentsWrapper* preview_tab = - TabContentsWrapper::GetCurrentWrapperForContents(tab_contents()); - printing::BackgroundPrintingManager* background_printing_manager = - g_browser_process->background_printing_manager(); - if (background_printing_manager->HasPrintPreviewTab(preview_tab)) - return; - - ConstrainedHtmlUIDelegate* delegate = GetConstrainedDelegate(); - if (!delegate) - return; - delegate->ReleaseTabContentsOnDialogClose(); - background_printing_manager->OwnPrintPreviewTab(preview_tab); - OnClosePrintPreviewTab(); -} - -void PrintPreviewUI::OnClosePrintPreviewTab() { - if (tab_closed_) - return; - tab_closed_ = true; - ConstrainedHtmlUIDelegate* delegate = GetConstrainedDelegate(); - if (!delegate) - return; - delegate->GetHtmlDialogUIDelegate()->OnDialogClosed(""); - delegate->OnDialogCloseFromWebUI(); -} - -void PrintPreviewUI::OnReloadPrintersList() { - CallJavascriptFunction("reloadPrintersList"); -} diff --git a/chrome/browser/ui/webui/print_preview_ui.h b/chrome/browser/ui/webui/print_preview_ui.h index de59b47..0625ef0 100644 --- a/chrome/browser/ui/webui/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview_ui.h @@ -12,7 +12,7 @@ #include "base/memory/ref_counted_memory.h" #include "base/time.h" #include "chrome/browser/printing/print_preview_data_service.h" -#include "chrome/browser/ui/webui/constrained_html_ui.h" +#include "chrome/browser/ui/webui/chrome_web_ui.h" class PrintPreviewDataService; class PrintPreviewHandler; @@ -22,7 +22,7 @@ namespace printing { struct PageSizeMargins; } -class PrintPreviewUI : public ConstrainedHtmlUI { +class PrintPreviewUI : public ChromeWebUI { public: explicit PrintPreviewUI(TabContents* contents); virtual ~PrintPreviewUI(); @@ -100,14 +100,13 @@ class PrintPreviewUI : public ConstrainedHtmlUI { // Notifies the Web UI that the print preview failed to render. void OnPrintPreviewFailed(); - // Notified the Web UI that this print preview tab's RenderProcess has been - // closed, which may occur for several reasons, e.g. tab closure or crash. - void OnPrintPreviewTabClosed(); - // Notifies the Web UI that initiator tab is closed, so we can disable all the // controls that need the initiator tab for generating the preview data. void OnInitiatorTabClosed(); + // Notifies the Web UI that the initiator tab has crashed. + void OnInitiatorTabCrashed(); + // Notifies the Web UI renderer that file selection has been cancelled. void OnFileSelectionCancelled(); @@ -118,15 +117,6 @@ class PrintPreviewUI : public ConstrainedHtmlUI { // Notifies the Web UI to cancel the pending preview request. void OnCancelPendingPreviewRequest(); - // Hides the print preview tab. - void OnHidePreviewTab(); - - // Closes the print preview tab. - void OnClosePrintPreviewTab(); - - // Reload the printers list. - void OnReloadPrintersList(); - private: friend class PrintPreviewHandlerTest; FRIEND_TEST_ALL_PREFIXES(PrintPreviewHandlerTest, StickyMarginsCustom); @@ -162,9 +152,6 @@ class PrintPreviewUI : public ConstrainedHtmlUI { // title. string16 initiator_tab_title_; - // Keeps track of whether OnClosePrintPreviewTab() has been called or not. - bool tab_closed_; - DISALLOW_COPY_AND_ASSIGN(PrintPreviewUI); }; diff --git a/chrome/browser/ui/webui/print_preview_ui_uitest.cc b/chrome/browser/ui/webui/print_preview_ui_uitest.cc index 55e33d8..a8bba38 100644 --- a/chrome/browser/ui/webui/print_preview_ui_uitest.cc +++ b/chrome/browser/ui/webui/print_preview_ui_uitest.cc @@ -22,48 +22,88 @@ class PrintPreviewUITest : public UITest { dom_automation_enabled_ = true; launch_arguments_.AppendSwitch(switches::kEnablePrintPreview); } + + void AssertIsPrintPage(TabProxy* tab) { + std::wstring title; + ASSERT_TRUE(tab->GetTabTitle(&title)); + string16 expected_title = + l10n_util::GetStringUTF16(IDS_PRINT_PREVIEW_TITLE); + ASSERT_EQ(expected_title, WideToUTF16Hack(title)); + } }; -TEST_F(PrintPreviewUITest, PrintCommands) { +// TODO(thestig) Remove this test in the future if loading +// chrome::kChromeUIPrintURL directly does not make sense. +TEST_F(PrintPreviewUITest, LoadPrintPreviewByURL) { + scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(browser.get()); + + scoped_refptr<TabProxy> tab = browser->GetActiveTab(); + ASSERT_TRUE(tab.get()); + + // Go to the print preview tab via URL. + NavigateToURL(GURL(chrome::kChromeUIPrintURL)); + AssertIsPrintPage(tab); +} + +TEST_F(PrintPreviewUITest, PrintCommandDisabled) { scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); ASSERT_TRUE(browser.get()); // Go to the about:blank page. NavigateToURL(GURL(chrome::kAboutBlankURL)); - // Make sure there is 1 tab and print is enabled. + // Make sure there is 1 tab and print is enabled. Create print preview tab. int tab_count; ASSERT_TRUE(browser->GetTabCount(&tab_count)); ASSERT_EQ(1, tab_count); - - bool enabled = false; + bool enabled; ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_PRINT, &enabled)); ASSERT_TRUE(enabled); - - // Make sure advanced print command (Ctrl+Shift+p) is enabled. - enabled = false; - ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_ADVANCED_PRINT, &enabled)); - ASSERT_TRUE(enabled); - - // Create print preview tab. ASSERT_TRUE(browser->RunCommand(IDC_PRINT)); - // Make sure print is disabled. + // Make sure there are 2 tabs and print is disabled. + ASSERT_TRUE(browser->GetTabCount(&tab_count)); + ASSERT_EQ(2, tab_count); + scoped_refptr<TabProxy> tab = browser->GetActiveTab(); + ASSERT_TRUE(tab.get()); + AssertIsPrintPage(tab); ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_PRINT, &enabled)); ASSERT_FALSE(enabled); +} + +TEST_F(PrintPreviewUITest, AdvancedPrintCommandEnabled) { + scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(browser.get()); + + // Go to the about:blank page. + NavigateToURL(GURL(chrome::kAboutBlankURL)); + + // Make sure there is 1 tab and print is enabled. Create print preview tab. + int tab_count; + ASSERT_TRUE(browser->GetTabCount(&tab_count)); + ASSERT_EQ(1, tab_count); + bool enabled; + ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_PRINT, &enabled)); + ASSERT_TRUE(enabled); // Make sure advanced print command (Ctrl+Shift+p) is enabled. enabled = false; ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_ADVANCED_PRINT, &enabled)); ASSERT_TRUE(enabled); - ASSERT_TRUE(browser->RunCommand(IDC_RELOAD)); + ASSERT_TRUE(browser->RunCommand(IDC_PRINT)); - enabled = false; + // Make sure there are 2 tabs and print is disabled. + ASSERT_TRUE(browser->GetTabCount(&tab_count)); + ASSERT_EQ(2, tab_count); + scoped_refptr<TabProxy> tab = browser->GetActiveTab(); + ASSERT_TRUE(tab.get()); + AssertIsPrintPage(tab); ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_PRINT, &enabled)); - ASSERT_TRUE(enabled); + ASSERT_FALSE(enabled); - // Make sure advanced print command (Ctrl+Shift+p) is enabled. + // Make sure advanced print command (Ctrl+Shift+p) is enabled on preview tab. enabled = false; ASSERT_TRUE(browser->IsMenuCommandEnabled(IDC_ADVANCED_PRINT, &enabled)); ASSERT_TRUE(enabled); diff --git a/chrome/browser/ui/webui/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview_ui_unittest.cc index f2612a7..a7060cc 100644 --- a/chrome/browser/ui/webui/print_preview_ui_unittest.cc +++ b/chrome/browser/ui/webui/print_preview_ui_unittest.cc @@ -8,7 +8,6 @@ #include "base/memory/ref_counted_memory.h" #include "chrome/browser/printing/print_preview_tab_controller.h" #include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/constrained_window_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/webui/print_preview_ui.h" #include "chrome/common/chrome_switches.h" @@ -22,10 +21,6 @@ namespace { const unsigned char blob1[] = "12346102356120394751634516591348710478123649165419234519234512349134"; -size_t GetConstrainedWindowCount(TabContentsWrapper* tab) { - return tab->constrained_window_tab_helper()->constrained_window_count(); -} - } // namespace typedef BrowserWithTestWindowTest PrintPreviewUITest; @@ -41,7 +36,6 @@ TEST_F(PrintPreviewUITest, PrintPreviewData) { TabContentsWrapper* initiator_tab = browser()->GetSelectedTabContentsWrapper(); ASSERT_TRUE(initiator_tab); - EXPECT_EQ(0U, GetConstrainedWindowCount(initiator_tab)); scoped_refptr<printing::PrintPreviewTabController> controller(new printing::PrintPreviewTabController()); @@ -51,8 +45,7 @@ TEST_F(PrintPreviewUITest, PrintPreviewData) { controller->GetOrCreatePreviewTab(initiator_tab); EXPECT_NE(initiator_tab, preview_tab); - EXPECT_EQ(1, browser()->tab_count()); - EXPECT_EQ(1U, GetConstrainedWindowCount(initiator_tab)); + EXPECT_EQ(2, browser()->tab_count()); PrintPreviewUI* preview_ui = reinterpret_cast<PrintPreviewUI*>(preview_tab->web_ui()); @@ -112,8 +105,7 @@ TEST_F(PrintPreviewUITest, PrintPreviewDraftPages) { controller->GetOrCreatePreviewTab(initiator_tab); EXPECT_NE(initiator_tab, preview_tab); - EXPECT_EQ(1, browser()->tab_count()); - EXPECT_EQ(1U, GetConstrainedWindowCount(initiator_tab)); + EXPECT_EQ(2, browser()->tab_count()); PrintPreviewUI* preview_ui = reinterpret_cast<PrintPreviewUI*>(preview_tab->web_ui()); @@ -180,8 +172,7 @@ TEST_F(PrintPreviewUITest, GetCurrentPrintPreviewStatus) { controller->GetOrCreatePreviewTab(initiator_tab); EXPECT_NE(initiator_tab, preview_tab); - EXPECT_EQ(1, browser()->tab_count()); - EXPECT_EQ(1U, GetConstrainedWindowCount(initiator_tab)); + EXPECT_EQ(2, browser()->tab_count()); PrintPreviewUI* preview_ui = reinterpret_cast<PrintPreviewUI*>(preview_tab->web_ui()); diff --git a/chrome/browser/ui/webui/web_ui_browsertest.cc b/chrome/browser/ui/webui/web_ui_browsertest.cc index 2ceed0c..2c84f2df 100644 --- a/chrome/browser/ui/webui/web_ui_browsertest.cc +++ b/chrome/browser/ui/webui/web_ui_browsertest.cc @@ -12,7 +12,6 @@ #include "base/path_service.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/printing/print_preview_tab_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/webui/chrome_web_ui.h" @@ -207,13 +206,6 @@ void WebUIBrowserTest::BrowsePrintPreload( browser()->tabstrip_model(), this); browser()->Print(); tabstrip_observer.WaitForObservation(); - printing::PrintPreviewTabController* tab_controller = - printing::PrintPreviewTabController::GetInstance(); - ASSERT_TRUE(tab_controller); - TabContentsWrapper* preview_tab = tab_controller->GetPrintPreviewForTab( - browser()->GetSelectedTabContentsWrapper()); - ASSERT_TRUE(preview_tab); - SetWebUIInstance(preview_tab->web_ui()); } const char WebUIBrowserTest::kDummyURL[] = "chrome://DummyURL"; diff --git a/chrome/test/base/test_tab_strip_model_observer.cc b/chrome/test/base/test_tab_strip_model_observer.cc index c2307b7..e6a34f1 100644 --- a/chrome/test/base/test_tab_strip_model_observer.cc +++ b/chrome/test/base/test_tab_strip_model_observer.cc @@ -4,8 +4,6 @@ #include "chrome/test/base/test_tab_strip_model_observer.h" -#include "base/bind.h" -#include "chrome/browser/printing/print_preview_tab_controller.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "content/public/browser/notification_source.h" @@ -23,26 +21,8 @@ TestTabStripModelObserver::~TestTabStripModelObserver() { tab_strip_model_->RemoveObserver(this); } -void TestTabStripModelObserver::TabBlockedStateChanged( - TabContentsWrapper* contents, int index) { - // Need to do this later - the print preview tab has not been created yet. - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&TestTabStripModelObserver::ObservePrintPreviewTabContents, - base::Unretained(this), - contents)); -} - -void TestTabStripModelObserver::ObservePrintPreviewTabContents( - TabContentsWrapper* contents) { - printing::PrintPreviewTabController* tab_controller = - printing::PrintPreviewTabController::GetInstance(); - if (tab_controller) { - TabContentsWrapper* preview_tab = - tab_controller->GetPrintPreviewForTab(contents); - if (preview_tab) { - RegisterAsObserver( - content::Source<NavigationController>(&preview_tab->controller())); - } - } +void TestTabStripModelObserver::TabInsertedAt( + TabContentsWrapper* contents, int index, bool foreground) { + RegisterAsObserver( + content::Source<NavigationController>(&contents->controller())); } diff --git a/chrome/test/base/test_tab_strip_model_observer.h b/chrome/test/base/test_tab_strip_model_observer.h index 37cb147..aa71472 100644 --- a/chrome/test/base/test_tab_strip_model_observer.h +++ b/chrome/test/base/test_tab_strip_model_observer.h @@ -12,13 +12,13 @@ class TabStripModel; -// In order to support testing of print preview, we need to wait for the -// constrained window to block the current tab, and then observe notifications -// on the newly added tab's controller to wait for it to be loaded. -// To support tests registering javascript WebUI handlers, we need to inject -// the framework & registration javascript before the webui page loads by -// calling back through the TestTabStripModelObserver::LoadStartObserver when -// the new page starts loading. +// In order to support testing of print preview, we need to wait for the tab to +// be inserted, and then observe notifications on the newly added tab's +// controller to wait for it to be loaded. To support tests registering +// javascript WebUI handlers, we need to inject the framework & registration +// javascript before the webui page loads by calling back through the +// TestTabStripModelObserver::LoadStartObserver when the new page starts +// loading. class TestTabStripModelObserver : public TestNavigationObserver, public TabStripModelObserver { public: @@ -30,12 +30,9 @@ class TestTabStripModelObserver : public TestNavigationObserver, virtual ~TestTabStripModelObserver(); private: - // Callback to observer the print preview tab associated with |contents|. - void ObservePrintPreviewTabContents(TabContentsWrapper* contents); - // TabStripModelObserver: - virtual void TabBlockedStateChanged(TabContentsWrapper* contents, - int index) OVERRIDE; + virtual void TabInsertedAt(TabContentsWrapper* contents, int index, + bool foreground) OVERRIDE; // |tab_strip_model_| is the object this observes. The constructor will // register this as an observer, and the destructor will remove the observer. |