diff options
author | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-26 19:30:34 +0000 |
---|---|---|
committer | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-26 19:30:34 +0000 |
commit | d5f942bab2af72892413a3080fb7468b0bbef713 (patch) | |
tree | ec5e97ea265fba45bb1f6102bc1aed4001f9898b | |
parent | e711c4dded8a24f780c039e545d7378937e1388b (diff) | |
download | chromium_src-d5f942bab2af72892413a3080fb7468b0bbef713.zip chromium_src-d5f942bab2af72892413a3080fb7468b0bbef713.tar.gz chromium_src-d5f942bab2af72892413a3080fb7468b0bbef713.tar.bz2 |
Reorganize the declarations to have some grouping and logical ordering in tab contents and web contents. Reorder the derived classes overrides to match, and reorder the definitions of the functions to match the order in the header file.
This doesn't actually change any code. I removed a few functions that were declared but never implemented (!) as well as some that were marked vitual but were never overridden. I renamed some things to make them more consistent.
Review URL: http://codereview.chromium.org/5005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2634 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 1654 insertions, 1704 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 7b4f600..7705d94 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -169,7 +169,7 @@ class NavigationControllerRestoredObserver : public NotificationObserver { bool FinishedRestoring() { return (!controller_->needs_reload() && !controller_->GetPendingEntry() && - !controller_->active_contents()->IsLoading()); + !controller_->active_contents()->is_loading()); } void SendDone() { @@ -1637,8 +1637,8 @@ void AutomationProvider::GetConstrainedWindow(const IPC::Message& message, NavigationController* nav_controller = tab_tracker_->GetResource(handle); TabContents* tab = nav_controller->active_contents(); - if (tab && index < static_cast<int>(tab->child_windows().size())) { - ConstrainedWindow* window = tab->child_windows()[index]; + if (tab && index < static_cast<int>(tab->child_windows_.size())) { + ConstrainedWindow* window = tab->child_windows_[index]; cwindow_handle = cwindow_tracker_->Add(window); } } diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 4b8ac12..a7073d2 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -198,7 +198,7 @@ BrowserAboutHandler::BrowserAboutHandler(Profile* profile, SiteInstance* instance, RenderViewHostFactory* render_view_factory) : WebContents(profile, instance, render_view_factory, MSG_ROUTING_NONE, NULL) { - type_ = TAB_CONTENTS_ABOUT_UI; + set_type(TAB_CONTENTS_ABOUT_UI); // We only need to register the AboutSource once and it is // kept globally. There is currently no way to remove a data source. diff --git a/chrome/browser/browser_commands.cc b/chrome/browser/browser_commands.cc index 063e99a..8a760c1 100644 --- a/chrome/browser/browser_commands.cc +++ b/chrome/browser/browser_commands.cc @@ -230,7 +230,7 @@ bool Browser::IsCommandEnabled(int id) const { } case IDC_STOP: { TabContents* current_tab = GetSelectedTabContents(); - return (current_tab && current_tab->IsLoading()); + return (current_tab && current_tab->is_loading()); } case IDC_CLOSETAB: { return !IsApplication(); @@ -514,24 +514,30 @@ void Browser::ExecuteCommand(int id) { case IDC_ZOOM_PLUS: { UserMetrics::RecordAction(L"ZoomPlus", profile_); TabContents* current_tab = GetSelectedTabContents(); - DCHECK(current_tab); - current_tab->AlterTextSize(text_zoom::TEXT_LARGER); + if (current_tab->AsWebContents()) { + current_tab->AsWebContents()->render_view_host()->AlterTextSize( + text_zoom::TEXT_LARGER); + } break; } case IDC_ZOOM_MINUS: { UserMetrics::RecordAction(L"ZoomMinus", profile_); TabContents* current_tab = GetSelectedTabContents(); - DCHECK(current_tab); - current_tab->AlterTextSize(text_zoom::TEXT_SMALLER); + if (current_tab->AsWebContents()) { + current_tab->AsWebContents()->render_view_host()->AlterTextSize( + text_zoom::TEXT_SMALLER); + } break; } case IDC_ZOOM_NORMAL: { UserMetrics::RecordAction(L"ZoomNormal", profile_); TabContents* current_tab = GetSelectedTabContents(); - DCHECK(current_tab); - current_tab->AlterTextSize(text_zoom::TEXT_STANDARD); + if (current_tab->AsWebContents()) { + current_tab->AsWebContents()->render_view_host()->AlterTextSize( + text_zoom::TEXT_STANDARD); + } break; } @@ -629,7 +635,7 @@ void Browser::ExecuteCommand(int id) { CharacterEncoding::GetCanonicalEncodingNameByCommandId(id); TabContents* current_tab = GetSelectedTabContents(); if (!cur_encoding_name.empty() && current_tab) - current_tab->SetPageEncoding(cur_encoding_name); + current_tab->set_encoding(cur_encoding_name); // Update user recently selected encoding list. std::wstring new_selected_encoding_list; if (CharacterEncoding::UpdateRecentlySelectdEncoding( diff --git a/chrome/browser/debugger/debugger_contents.cc b/chrome/browser/debugger/debugger_contents.cc index e8eb8963..74758ca 100644 --- a/chrome/browser/debugger/debugger_contents.cc +++ b/chrome/browser/debugger/debugger_contents.cc @@ -103,7 +103,7 @@ class DebuggerHandler : public DOMMessageHandler { DebuggerContents::DebuggerContents(Profile* profile, SiteInstance* instance) : DOMUIHost(profile, instance, NULL) { - type_ = TAB_CONTENTS_DEBUGGER; + set_type(TAB_CONTENTS_DEBUGGER); } void DebuggerContents::AttachMessageHandlers() { diff --git a/chrome/browser/dom_ui/dom_ui_host.cc b/chrome/browser/dom_ui/dom_ui_host.cc index b46affd..2541e71 100644 --- a/chrome/browser/dom_ui/dom_ui_host.cc +++ b/chrome/browser/dom_ui/dom_ui_host.cc @@ -20,7 +20,7 @@ DOMUIHost::DOMUIHost(Profile* profile, MSG_ROUTING_NONE, NULL) { // Implementors of this class will have a specific tab contents type. - type_ = TAB_CONTENTS_UNKNOWN_TYPE; + set_type(TAB_CONTENTS_UNKNOWN_TYPE); } DOMUIHost::~DOMUIHost() { diff --git a/chrome/browser/dom_ui/html_dialog_contents.cc b/chrome/browser/dom_ui/html_dialog_contents.cc index 60314f3..50dbc0c 100644 --- a/chrome/browser/dom_ui/html_dialog_contents.cc +++ b/chrome/browser/dom_ui/html_dialog_contents.cc @@ -13,7 +13,7 @@ HtmlDialogContents::HtmlDialogContents(Profile* profile, RenderViewHostFactory* rvf) : DOMUIHost(profile, instance, rvf), delegate_(NULL) { - type_ = TAB_CONTENTS_HTML_DIALOG; + set_type(TAB_CONTENTS_HTML_DIALOG); } HtmlDialogContents::~HtmlDialogContents() { diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc index 3d0cdf1..c96a5b5 100644 --- a/chrome/browser/dom_ui/new_tab_ui.cc +++ b/chrome/browser/dom_ui/new_tab_ui.cc @@ -743,7 +743,7 @@ NewTabUIContents::NewTabUIContents(Profile* profile, motd_message_id_(0), incognito_(false), most_visited_handler_(NULL) { - type_ = TAB_CONTENTS_NEW_TAB_UI; + set_type(TAB_CONTENTS_NEW_TAB_UI); set_forced_title(l10n_util::GetString(IDS_NEW_TAB_TITLE)); if (profile->IsOffTheRecord()) diff --git a/chrome/browser/encoding_menu_controller_delegate.cc b/chrome/browser/encoding_menu_controller_delegate.cc index d7a7bc8..f5fd29a 100644 --- a/chrome/browser/encoding_menu_controller_delegate.cc +++ b/chrome/browser/encoding_menu_controller_delegate.cc @@ -28,7 +28,7 @@ bool EncodingMenuControllerDelegate::IsItemChecked(int id) const { TabContents* current_tab = browser_->GetSelectedTabContents(); if (!current_tab) return false; - std::wstring encoding_name = current_tab->GetEncoding(); + std::wstring encoding_name = current_tab->encoding(); if (encoding_name.empty()) encoding_name = profile->GetPrefs()->GetString(prefs::kDefaultCharset); switch (id) { diff --git a/chrome/browser/native_ui_contents.cc b/chrome/browser/native_ui_contents.cc index 0a1dfad..b54865c 100644 --- a/chrome/browser/native_ui_contents.cc +++ b/chrome/browser/native_ui_contents.cc @@ -322,7 +322,7 @@ void NativeUIContents::SetInitialFocus() { if (browser) browser->FocusLocationBar(); else - ::SetFocus(GetHWND()); + TabContents::SetInitialFocus(); // Will set focus to our HWND. } } diff --git a/chrome/browser/navigation_controller.cc b/chrome/browser/navigation_controller.cc index 38fcf65..0cecdc3 100644 --- a/chrome/browser/navigation_controller.cc +++ b/chrome/browser/navigation_controller.cc @@ -907,13 +907,13 @@ void NavigationController::DiscardPendingEntry() { NavigationEntry* last_entry = GetLastCommittedEntry(); if (last_entry && last_entry->tab_type() != active_contents_->type()) { TabContents* from_contents = active_contents_; - from_contents->SetActive(false); + from_contents->set_is_active(false); // Switch back to the previous tab contents. active_contents_ = GetTabContents(last_entry->tab_type()); DCHECK(active_contents_); - active_contents_->SetActive(true); + active_contents_->set_is_active(true); // If we are transitioning from two types of WebContents, we need to migrate // the download shelf if it is visible. The download shelf may have been @@ -992,14 +992,14 @@ void NavigationController::NavigateToPendingEntry(bool reload) { pending_entry_->ssl() = NavigationEntry::SSLStatus(); if (from_contents && from_contents->type() != pending_entry_->tab_type()) - from_contents->SetActive(false); + from_contents->set_is_active(false); HWND parent = from_contents ? GetParent(from_contents->GetContainerHWND()) : 0; TabContents* contents = GetTabContentsCreateIfNecessary(parent, *pending_entry_); - contents->SetActive(true); + contents->set_is_active(true); active_contents_ = contents; if (from_contents && from_contents != contents) { diff --git a/chrome/browser/render_view_host_delegate.h b/chrome/browser/render_view_host_delegate.h index 036a88cb..eb1cef6 100644 --- a/chrome/browser/render_view_host_delegate.h +++ b/chrome/browser/render_view_host_delegate.h @@ -235,12 +235,6 @@ class RenderViewHostDelegate { virtual void GetHistoryListCount(int* back_list_count, int* forward_list_count) { } - // The page wants to open a plugin to display the given URL, of a certain - // content type. |reply_msg| contains the name of the plugin. - virtual void OpenChannelToPlugin(const GURL& url, - const std::string& mime_type, - IPC::Message* reply_msg) { } - // A file chooser should be shown. virtual void RunFileChooser(const std::wstring& default_file) { } diff --git a/chrome/browser/tab_contents.cc b/chrome/browser/tab_contents.cc index 17fd07c..7794b32 100644 --- a/chrome/browser/tab_contents.cc +++ b/chrome/browser/tab_contents.cc @@ -19,17 +19,29 @@ #include "generated_resources.h" +namespace { + +BOOL CALLBACK InvalidateWindow(HWND hwnd, LPARAM lparam) { + // Note: erase is required to properly paint some widgets borders. This can be + // seen with textfields. + InvalidateRect(hwnd, NULL, TRUE); + return TRUE; +} + +} // namespace + TabContents::TabContents(TabContentsType type) - : is_loading_(false), - response_started_(false), - is_active_(true), - type_(type), + : type_(type), delegate_(NULL), controller_(NULL), - max_page_id_(-1), - saved_location_bar_state_(NULL), + is_loading_(false), + is_active_(true), is_crashed_(false), - shelf_visible_(false) { + waiting_for_response_(false), + saved_location_bar_state_(NULL), + shelf_visible_(false), + max_page_id_(-1), + capturing_contents_(false) { last_focused_view_storage_id_ = ChromeViews::ViewStorage::GetSharedInstance()->CreateStorageID(); } @@ -45,42 +57,49 @@ TabContents::~TabContents() { view_storage->RemoveView(last_focused_view_storage_id_); } -void TabContents::HideContents() { - // Hide the contents before adjusting its parent to avoid a full desktop - // flicker. - ShowWindow(GetContainerHWND(), SW_HIDE); - - // Reset the parent to NULL to ensure hidden tabs don't receive messages. - SetParent(GetContainerHWND(), NULL); +// static +void TabContents::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterBooleanPref(prefs::kBlockPopups, false); +} - // Remove any focus manager related information. - ChromeViews::FocusManager::UninstallFocusSubclass(GetContainerHWND()); - WasHidden(); +void TabContents::CloseContents() { + // Destroy our NavigationController, which will Destroy all tabs it owns. + controller_->Destroy(); + // Note that the controller may have deleted us at this point, + // so don't touch any member variables here. } -int32 TabContents::GetMaxPageID() { - if (GetSiteInstance()) - return GetSiteInstance()->max_page_id(); - else - return max_page_id_; -} +void TabContents::Destroy() { + // First cleanly close all child windows. + // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked + // some of these to close. CloseWindows is async, so it might get called + // twice before it runs. + int size = static_cast<int>(child_windows_.size()); + for (int i = size - 1; i >= 0; --i) { + ConstrainedWindow* window = child_windows_[i]; + if (window) + window->CloseConstrainedWindow(); + } -void TabContents::UpdateMaxPageID(int32 page_id) { - // Ensure both the SiteInstance and RenderProcessHost update their max page - // IDs in sync. Only WebContents will also have site instances, except during - // testing. - if (GetSiteInstance()) - GetSiteInstance()->UpdateMaxPageID(page_id); + // Notify any observer that have a reference on this tab contents. + NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_DESTROYED, + Source<TabContents>(this), + NotificationService::NoDetails()); - if (AsWebContents()) - AsWebContents()->process()->UpdateMaxPageID(page_id); - else - max_page_id_ = std::max(max_page_id_, page_id); -} + // If we still have a window handle, destroy it. GetContainerHWND can return + // NULL if this contents was part of a window that closed. + if (GetContainerHWND()) + ::DestroyWindow(GetContainerHWND()); -const std::wstring TabContents::GetDefaultTitle() const { - return l10n_util::GetString(IDS_DEFAULT_TAB_TITLE); + // Notify our NavigationController. Make sure we are deleted first, so + // that the controller is the last to die. + NavigationController* controller = controller_; + TabContentsType type = this->type(); + + delete this; + + controller->TabContentsWasDestroyed(type); } void TabContents::SetupController(Profile* profile) { @@ -88,19 +107,22 @@ void TabContents::SetupController(Profile* profile) { controller_ = new NavigationController(this, profile); } -const GURL& TabContents::GetURL() const { - DCHECK(controller_); - - static const GURL kEmptyURL; +bool TabContents::SupportsURL(GURL* url) { + GURL u(*url); + if (TabContents::TypeForURL(&u) == type()) { + *url = u; + return true; + } + return false; +} +const GURL& TabContents::GetURL() const { // We may not have a navigation entry yet NavigationEntry* entry = controller_->GetActiveEntry(); - return entry ? entry->display_url() : kEmptyURL; + return entry ? entry->display_url() : GURL::EmptyGURL(); } const std::wstring& TabContents::GetTitle() const { - DCHECK(controller_); - // We always want to use the title for the last committed entry rather than // a pending navigation entry. For example, when the user types in a URL, we // want to keep the old page's title until the new load has committed and we @@ -113,9 +135,31 @@ const std::wstring& TabContents::GetTitle() const { return EmptyWString(); } -SkBitmap TabContents::GetFavIcon() const { - DCHECK(controller_); +int32 TabContents::GetMaxPageID() { + if (GetSiteInstance()) + return GetSiteInstance()->max_page_id(); + else + return max_page_id_; +} +void TabContents::UpdateMaxPageID(int32 page_id) { + // Ensure both the SiteInstance and RenderProcessHost update their max page + // IDs in sync. Only WebContents will also have site instances, except during + // testing. + if (GetSiteInstance()) + GetSiteInstance()->UpdateMaxPageID(page_id); + + if (AsWebContents()) + AsWebContents()->process()->UpdateMaxPageID(page_id); + else + max_page_id_ = std::max(max_page_id_, page_id); +} + +const std::wstring TabContents::GetDefaultTitle() const { + return l10n_util::GetString(IDS_DEFAULT_TAB_TITLE); +} + +SkBitmap TabContents::GetFavIcon() const { // Like GetTitle(), we also want to use the favicon for the last committed // entry rather than a pending navigation entry. NavigationEntry* entry = controller_->GetLastCommittedEntry(); @@ -154,43 +198,51 @@ bool TabContents::GetSSLEVText(std::wstring* ev_text, return SSLManager::GetEVCertNames(*cert, ev_text, ev_tooltip_text); } -void TabContents::CloseContents() { - // Destroy our NavigationController, which will Destroy all tabs it owns. - controller_->Destroy(); - // Note that the controller may have deleted us at this point, - // so don't touch any member variables here. +void TabContents::SetIsCrashed(bool state) { + if (state == is_crashed_) + return; + + is_crashed_ = state; + if (delegate_) + delegate_->ContentsStateChanged(this); } -void TabContents::Destroy() { - // First cleanly close all child windows. - // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked - // some of these to close. CloseWindows is async, so it might get called - // twice before it runs. - int size = static_cast<int>(child_windows_.size()); - for (int i = size - 1; i >= 0; --i) { - ConstrainedWindow* window = child_windows_[i]; - if (window) - window->CloseConstrainedWindow(); - } +void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) { + if (delegate_) + delegate_->NavigationStateChanged(this, changed_flags); +} - // Notify any observer that have a reference on this tab contents. - NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_DESTROYED, +void TabContents::DidBecomeSelected() { + if (controller_) + controller_->SetActive(true); + + // Invalidate all descendants. (take care to exclude invalidating ourselves!) + EnumChildWindows(GetContainerHWND(), InvalidateWindow, 0); +} + +void TabContents::WasHidden() { + NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_HIDDEN, Source<TabContents>(this), NotificationService::NoDetails()); +} - // If we still have a window handle, destroy it. GetContainerHWND can return - // NULL if this contents was part of a window that closed. - if (GetContainerHWND()) - ::DestroyWindow(GetContainerHWND()); - - // Notify our NavigationController. Make sure we are deleted first, so - // that the controller is the last to die. - NavigationController* controller = controller_; - TabContentsType type = this->type(); +void TabContents::Activate() { + if (delegate_) + delegate_->ActivateContents(this); +} - delete this; +void TabContents::OpenURL(const GURL& url, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + if (delegate_) + delegate_->OpenURLFromTab(this, url, disposition, transition); +} - controller->TabContentsWasDestroyed(type); +bool TabContents::NavigateToPendingEntry(bool reload) { + // Our benavior is just to report that the entry was committed. + controller()->GetPendingEntry()->set_title(GetDefaultTitle()); + controller()->CommitPendingEntry(); + return true; } ConstrainedWindow* TabContents::CreateConstrainedDialog( @@ -236,66 +288,6 @@ void TabContents::AddConstrainedPopup(TabContents* new_contents, RepositionSupressedPopupsToFit(new_size); } -void TabContents::SetIsLoading(bool is_loading, - LoadNotificationDetails* details) { - if (is_loading == is_loading_) - return; - - is_loading_ = is_loading; - response_started_ = is_loading; - - // Suppress notifications for this TabContents if we are not active. - if (!is_active_) - return; - - if (delegate_) - delegate_->LoadingStateChanged(this); - - NotificationService::current()-> - Notify((is_loading ? NOTIFY_LOAD_START : NOTIFY_LOAD_STOP), - Source<NavigationController>(this->controller()), - details ? Details<LoadNotificationDetails>(details) : - NotificationService::NoDetails()); -} - -bool TabContents::NavigateToPendingEntry(bool reload) { - // Our benavior is just to report that the entry was committed. - controller()->GetPendingEntry()->set_title(GetDefaultTitle()); - controller()->CommitPendingEntry(); - return true; -} - -void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) { - if (delegate_) - delegate_->NavigationStateChanged(this, changed_flags); -} - -static BOOL CALLBACK InvalidateWindow(HWND hwnd, LPARAM lparam) { - // Note: erase is required to properly paint some widgets borders. This can be - // seen with textfields. - InvalidateRect(hwnd, NULL, TRUE); - return TRUE; -} - -void TabContents::DidBecomeSelected() { - if (controller_) - controller_->SetActive(true); - - // Invalidate all descendants. (take care to exclude invalidating ourselves!) - EnumChildWindows(GetContainerHWND(), InvalidateWindow, 0); -} - -void TabContents::WasHidden() { - NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_HIDDEN, - Source<TabContents>(this), - NotificationService::NoDetails()); -} - -void TabContents::Activate() { - if (delegate_) - delegate_->ActivateContents(this); -} - void TabContents::CloseAllSuppressedPopups() { // Close all auto positioned child windows to "clean up" the workspace. int count = static_cast<int>(child_windows_.size()); @@ -306,88 +298,20 @@ void TabContents::CloseAllSuppressedPopups() { } } -void TabContents::OnStartDownload(DownloadItem* download) { - DCHECK(download); - TabContents* tab_contents = this; - - // Download in a constrained popup is shown in the tab that opened it. - TabContents* constraining_tab = delegate()->GetConstrainingContents(this); - if (constraining_tab) - tab_contents = constraining_tab; - - // GetDownloadShelfView creates the download shelf if it was not yet created. - tab_contents->GetDownloadShelfView()->AddDownload(download); - tab_contents->SetDownloadShelfVisible(true); - - // This animation will delete itself when it finishes, or if we become hidden - // or destroyed. - if (IsWindowVisible(GetContainerHWND())) { // For minimized windows, unit - // tests, etc. - new DownloadStartedAnimation(tab_contents); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// TabContents, ConstrainedTabContentsDelegate implementation: - -void TabContents::AddNewContents(ConstrainedWindow* window, - TabContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) { - AddNewContents(new_contents, disposition, initial_pos, user_gesture); -} - -void TabContents::OpenURL(ConstrainedWindow* window, - const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - OpenURL(url, disposition, transition); -} - -void TabContents::WillClose(ConstrainedWindow* window) { - ConstrainedWindowList::iterator it = - find(child_windows_.begin(), child_windows_.end(), window); - if (it != child_windows_.end()) - child_windows_.erase(it); - - if (::IsWindow(GetContainerHWND())) { - CRect client_rect; - GetClientRect(GetContainerHWND(), &client_rect); - RepositionSupressedPopupsToFit( - gfx::Size(client_rect.Width(), client_rect.Height())); - } -} - -void TabContents::DetachContents(ConstrainedWindow* window, - TabContents* contents, - const gfx::Rect& contents_bounds, - const gfx::Point& mouse_pt, - int frame_component) { - WillClose(window); - if (delegate_) { - delegate_->StartDraggingDetachedContents( - this, contents, contents_bounds, mouse_pt, frame_component); - } -} +void TabContents::HideContents() { + // Hide the contents before adjusting its parent to avoid a full desktop + // flicker. + ShowWindow(GetContainerHWND(), SW_HIDE); -void TabContents::DidMoveOrResize(ConstrainedWindow* window) { - UpdateWindow(GetContainerHWND()); -} + // Reset the parent to NULL to ensure hidden tabs don't receive messages. + SetParent(GetContainerHWND(), NULL); -/////////////////////////////////////////////////////////////////////////////// -// PageNavigator methods + // Remove any focus manager related information. + ChromeViews::FocusManager::UninstallFocusSubclass(GetContainerHWND()); -void TabContents::OpenURL(const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - if (delegate_) - delegate_->OpenURLFromTab(this, url, disposition, transition); + WasHidden(); } -/////////////////////////////////////////////////////////////////////////////// - void TabContents::Focus() { ChromeViews::FocusManager* focus_manager = ChromeViews::FocusManager::GetFocusManager(GetContainerHWND()); @@ -456,21 +380,8 @@ void TabContents::RestoreFocus() { } } -void TabContents::RepositionSupressedPopupsToFit(const gfx::Size& new_size) { - // TODO(erg): There's no way to detect whether scroll bars are - // visible, so for beta, we're just going to assume that the - // vertical scroll bar is visible, and not care about covering up - // the horizontal scroll bar. Fixing this is half of - // http://b/1118139. - gfx::Point anchor_position( - new_size.width() - ChromeViews::NativeScrollBar::GetVerticalScrollBarWidth(), - new_size.height()); - int window_count = static_cast<int>(child_windows_.size()); - for (int i = window_count - 1; i >= 0; --i) { - ConstrainedWindow* window = child_windows_.at(i); - if (window->IsSuppressedConstrainedWindow()) - window->RepositionConstrainedWindowTo(anchor_position); - } +void TabContents::SetInitialFocus() { + ::SetFocus(GetContainerHWND()); } void TabContents::SetDownloadShelfVisible(bool visible) { @@ -491,40 +402,31 @@ void TabContents::SetDownloadShelfVisible(bool visible) { ToolbarSizeChanged(false); } -void TabContents::ReleaseDownloadShelfView() { - download_shelf_view_.release(); -} - -void TabContents::SetInitialFocus() { - ::SetFocus(GetContainerHWND()); +void TabContents::ToolbarSizeChanged(bool is_animating) { + TabContentsDelegate* d = delegate(); + if (d) + d->ToolbarSizeChanged(this, is_animating); } -void TabContents::SetIsCrashed(bool state) { - if (state == is_crashed_) - return; +void TabContents::OnStartDownload(DownloadItem* download) { + DCHECK(download); + TabContents* tab_contents = this; - is_crashed_ = state; - if (delegate_) - delegate_->ContentsStateChanged(this); -} + // Download in a constrained popup is shown in the tab that opened it. + TabContents* constraining_tab = delegate()->GetConstrainingContents(this); + if (constraining_tab) + tab_contents = constraining_tab; -bool TabContents::IsCrashed() const { - return is_crashed_; -} + // GetDownloadShelfView creates the download shelf if it was not yet created. + tab_contents->GetDownloadShelfView()->AddDownload(download); + tab_contents->SetDownloadShelfVisible(true); -bool TabContents::SupportsURL(GURL* url) { - GURL u(*url); - if (TabContents::TypeForURL(&u) == type()) { - *url = u; - return true; + // This animation will delete itself when it finishes, or if we become hidden + // or destroyed. + if (IsWindowVisible(GetContainerHWND())) { // For minimized windows, unit + // tests, etc. + new DownloadStartedAnimation(tab_contents); } - return false; -} - -void TabContents::ToolbarSizeChanged(bool is_animating) { - TabContentsDelegate* d = delegate(); - if (d) - d->ToolbarSizeChanged(this, is_animating); } DownloadShelfView* TabContents::GetDownloadShelfView() { @@ -542,6 +444,51 @@ void TabContents::MigrateShelfViewFrom(TabContents* tab_contents) { tab_contents->ReleaseDownloadShelfView(); } +void TabContents::AddNewContents(ConstrainedWindow* window, + TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) { + AddNewContents(new_contents, disposition, initial_pos, user_gesture); +} + +void TabContents::OpenURL(ConstrainedWindow* window, + const GURL& url, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + OpenURL(url, disposition, transition); +} + +void TabContents::WillClose(ConstrainedWindow* window) { + ConstrainedWindowList::iterator it = + find(child_windows_.begin(), child_windows_.end(), window); + if (it != child_windows_.end()) + child_windows_.erase(it); + + if (::IsWindow(GetContainerHWND())) { + CRect client_rect; + GetClientRect(GetContainerHWND(), &client_rect); + RepositionSupressedPopupsToFit( + gfx::Size(client_rect.Width(), client_rect.Height())); + } +} + +void TabContents::DetachContents(ConstrainedWindow* window, + TabContents* contents, + const gfx::Rect& contents_bounds, + const gfx::Point& mouse_pt, + int frame_component) { + WillClose(window); + if (delegate_) { + delegate_->StartDraggingDetachedContents( + this, contents, contents_bounds, mouse_pt, frame_component); + } +} + +void TabContents::DidMoveOrResize(ConstrainedWindow* window) { + UpdateWindow(GetContainerHWND()); +} + // static void TabContents::MigrateShelfView(TabContents* from, TabContents* to) { bool was_shelf_visible = from->IsDownloadShelfVisible(); @@ -550,8 +497,46 @@ void TabContents::MigrateShelfView(TabContents* from, TabContents* to) { to->SetDownloadShelfVisible(was_shelf_visible); } -// static -void TabContents::RegisterUserPrefs(PrefService* prefs) { - prefs->RegisterBooleanPref(prefs::kBlockPopups, false); +void TabContents::SetIsLoading(bool is_loading, + LoadNotificationDetails* details) { + if (is_loading == is_loading_) + return; + + is_loading_ = is_loading; + waiting_for_response_ = is_loading; + + // Suppress notifications for this TabContents if we are not active. + if (!is_active_) + return; + + if (delegate_) + delegate_->LoadingStateChanged(this); + + NotificationService::current()-> + Notify((is_loading ? NOTIFY_LOAD_START : NOTIFY_LOAD_STOP), + Source<NavigationController>(this->controller()), + details ? Details<LoadNotificationDetails>(details) : + NotificationService::NoDetails()); } +void TabContents::RepositionSupressedPopupsToFit(const gfx::Size& new_size) { + // TODO(erg): There's no way to detect whether scroll bars are + // visible, so for beta, we're just going to assume that the + // vertical scroll bar is visible, and not care about covering up + // the horizontal scroll bar. Fixing this is half of + // http://b/1118139. + gfx::Point anchor_position( + new_size.width() - + ChromeViews::NativeScrollBar::GetVerticalScrollBarWidth(), + new_size.height()); + int window_count = static_cast<int>(child_windows_.size()); + for (int i = window_count - 1; i >= 0; --i) { + ConstrainedWindow* window = child_windows_.at(i); + if (window->IsSuppressedConstrainedWindow()) + window->RepositionConstrainedWindowTo(anchor_position); + } +} + +void TabContents::ReleaseDownloadShelfView() { + download_shelf_view_.release(); +} diff --git a/chrome/browser/tab_contents.h b/chrome/browser/tab_contents.h index 5630cc4..187822b 100644 --- a/chrome/browser/tab_contents.h +++ b/chrome/browser/tab_contents.h @@ -17,8 +17,8 @@ #include "chrome/common/text_zoom.h" namespace gfx { - class Rect; - class Size; +class Rect; +class Size; } class DOMUIHost; @@ -50,14 +50,8 @@ class WebContents; // the NavigationController makes the active TabContents inactive, notifies the // TabContentsDelegate that the TabContents is being replaced, and then // activates the new TabContents. -// class TabContents : public PageNavigator, - public ConstrainedTabContentsDelegate, - public NotificationObserver { - // Used to access the child_windows_ (ConstrainedWindowList) for testing - // automation purposes. - friend class AutomationProvider; - + public ConstrainedTabContentsDelegate { public: // Flags passed to the TabContentsDelegate.NavigationStateChanged to tell it // what has changed. Combine them to update more than one thing. @@ -71,6 +65,11 @@ class TabContents : public PageNavigator, INVALIDATE_EVERYTHING = 0xFFFFFFFF }; + static void RegisterUserPrefs(PrefService* prefs); + + // Factory ------------------------------------------------------------------- + // (implemented in tab_contents_factory.cc) + // Creates a new TabContents of the given type. Will reuse the given // instance's renderer, if it is not null. static TabContents* CreateWithType(TabContentsType type, @@ -90,28 +89,24 @@ class TabContents : public PageNavigator, static TabContentsFactory* RegisterFactory(TabContentsType type, TabContentsFactory* factory); - // Tell the subclass to set up the view (e.g. create the container HWND if - // applicable) and any other create-time setup. - virtual void CreateView(HWND parent_hwnd, const gfx::Rect& initial_bounds) {} + // Creation & destruction ---------------------------------------------------- - // Returns the HWND associated with this TabContents. Outside of automation - // in the context of the UI, this is required to be implemented. - virtual HWND GetContainerHWND() const { return NULL; } + // Request this tab to shut down. This kills the tab's NavigationController, + // which then Destroy()s all tabs it controls. + void CloseContents(); - // Returns the bounds of this TabContents in the screen coordinate system. - virtual void GetContainerBounds(gfx::Rect *out) const { - out->SetRect(0, 0, 0, 0); - } + // Unregister/shut down any pending tasks involving this tab. + // This is called as the tab is shutting down, before the + // NavigationController (and consequently profile) are gone. + // + // If you override this, be sure to call this implementation at the end + // of yours. + // See also Close(). + virtual void Destroy(); - // Show, Hide and Size the TabContents. - // TODO(beng): (Cleanup) Show/Size TabContents should be made to actually - // show and size the View. For simplicity sake, for now they're - // just empty. This is currently a bit of a mess and is just a - // band-aid. - virtual void ShowContents() {} - virtual void HideContents(); - virtual void SizeContents(const gfx::Size& size) {} + // Intrinsic tab state ------------------------------------------------------- + // Returns the type of tab this is. See also the As* functions following. TabContentsType type() const { return type_; } // Returns this object as a WebContents if it is one, and NULL otherwise. @@ -123,40 +118,7 @@ class TabContents : public PageNavigator, } // Returns this object as a DOMUIHost if it is one, and NULL otherwise. - virtual DOMUIHost* AsDOMUIHost() { return NULL ; } - - // The max PageID of any page that this TabContents has loaded. PageIDs - // increase with each new page that is loaded by a tab. If this is a - // WebContents, then the max PageID is kept separately on each SiteInstance. - // Returns -1 if no PageIDs have yet been seen. - int32 GetMaxPageID(); - - // Updates the max PageID to be at least the given PageID. - void UpdateMaxPageID(int32 page_id); - - // Returns the site instance associated with the current page. By default, - // there is no site instance. WebContents overrides this to provide proper - // access to its site instance. - virtual SiteInstance* GetSiteInstance() const { return NULL; } - - // Initial title assigned to NavigationEntries from Navigate. - virtual const std::wstring GetDefaultTitle() const; - - // Defines whether the url should be displayed within the browser. If false - // is returned, the URL field is blank and grabs focus to invite the user - // to type a new url - virtual bool ShouldDisplayURL() { return true; } - - // Returns the favicon for this tab, or an isNull() bitmap if the tab does not - // have a favicon. The default implementation uses the current navigation - // entry. - virtual SkBitmap GetFavIcon() const; - - // Returns whether the favicon should be displayed. If this returns false, no - // space is provided for the favicon, and the favicon is never displayed. - virtual bool ShouldDisplayFavIcon() { - return true; - } + virtual DOMUIHost* AsDOMUIHost() { return NULL; } TabContentsDelegate* delegate() const { return delegate_; } void set_delegate(TabContentsDelegate* d) { delegate_ = d; } @@ -183,15 +145,17 @@ class TabContents : public PageNavigator, return controller_ ? controller_->profile() : NULL; } - // For use when switching tabs, these functions allow the tab contents to - // hold the per-tab state of the location bar. The tab contents takes - // ownership of the pointer. - void set_saved_location_bar_state(const AutocompleteEditState* state) { - saved_location_bar_state_.reset(state); - } - const AutocompleteEditState* saved_location_bar_state() const { - return saved_location_bar_state_.get(); - } + // Returns whether this tab contents supports the provided URL. By default, + // this method matches the tab contents type with the result of TypeForURL(). + // |url| points to the actual URL that will be used. It can be modified as + // needed. + // Override this method if your TabContents subclass supports various URL + // schemes but doesn't want to be the default handler for these schemes. + // For example, the NewTabUIContents overrides this method to support + // javascript: URLs. + virtual bool SupportsURL(GURL* url); + + // Tab navigation state ------------------------------------------------------ // Returns the current navigation properties, which if a navigation is // pending may be provisional (e.g., the navigation could result in a @@ -199,6 +163,38 @@ class TabContents : public PageNavigator, const GURL& GetURL() const; virtual const std::wstring& GetTitle() const; + // The max PageID of any page that this TabContents has loaded. PageIDs + // increase with each new page that is loaded by a tab. If this is a + // WebContents, then the max PageID is kept separately on each SiteInstance. + // Returns -1 if no PageIDs have yet been seen. + int32 GetMaxPageID(); + + // Updates the max PageID to be at least the given PageID. + void UpdateMaxPageID(int32 page_id); + + // Returns the site instance associated with the current page. By default, + // there is no site instance. WebContents overrides this to provide proper + // access to its site instance. + virtual SiteInstance* GetSiteInstance() const { return NULL; } + + // Initial title assigned to NavigationEntries from Navigate. + virtual const std::wstring GetDefaultTitle() const; + + // Defines whether this tab's URL should be displayed in the browser's URL + // bar. Normally this is true so you can see the URL. This is set to false + // for the new tab page and related pages so that the URL bar is empty and + // the user is invited to type into it. + virtual bool ShouldDisplayURL() { return true; } + + // Returns the favicon for this tab, or an isNull() bitmap if the tab does not + // have a favicon. The default implementation uses the current navigation + // entry. + virtual SkBitmap GetFavIcon() const; + + // Returns whether the favicon should be displayed. If this returns false, no + // space is provided for the favicon, and the favicon is never displayed. + virtual bool ShouldDisplayFavIcon() { return true; } + // SSL related states. SecurityStyle GetSecurityStyle() const; @@ -208,75 +204,72 @@ class TabContents : public PageNavigator, // not served over HTTPS or if HTTPS does not use an EV cert. bool GetSSLEVText(std::wstring* ev_text, std::wstring* ev_tooltip_text) const; - // Request this tab to shut down. - // This kills the tab's NavigationController, which then Destroy()s all - // tabs it controls. - void CloseContents(); - - // Unregister/shut down any pending tasks involving this tab. - // This is called as the tab is shutting down, before the - // NavigationController (and consequently profile) are gone. - // - // If you override this, be sure to call this implementation at the end - // of yours. - // See also Close(). - virtual void Destroy(); - - // Create a new window constrained to this TabContents' clip and visibility. - // The window is initialized by using the supplied delegate to obtain basic - // window characteristics, and the supplied view for the content. The window - // is sized according to the preferred size of the content_view, and centered - // within the contents. - ConstrainedWindow* CreateConstrainedDialog( - ChromeViews::WindowDelegate* window_delegate, - ChromeViews::View* contents_view); - - // Adds a new tab or window with the given already-created contents - void AddNewContents(TabContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture); - - // Builds a ConstrainedWindow* for the incoming |new_contents| and - // adds it to child_windows_. - void AddConstrainedPopup(TabContents* new_contents, - const gfx::Rect& initial_pos); + // Returns a human-readable description the tab's loading state. + virtual std::wstring GetStatusText() const { return std::wstring(); } - // An asynchronous call to trigger the string search in the page. - // It sends an IPC message to the Renderer that handles the string - // search, selecting the matches and setting the caret positions. - // This function also starts the asynchronous scoping effort. - virtual void StartFinding(int request_id, - const std::wstring& string, - bool forward, bool match_case, - bool find_next) { } + const std::wstring& encoding() { return encoding_name_; } + void set_encoding(const std::wstring& encoding_name) { + encoding_name_ = encoding_name; + } - // An asynchronous call to stop the string search in the page. If - // |clear_selection| is true, it will also clear the selection on the - // focused frame. - virtual void StopFinding(bool clear_selection) { } + // Return whether this tab contents is loading a resource. + bool is_loading() const { return is_loading_; } - // Asynchronous calls to change the text zoom level. - virtual void AlterTextSize(text_zoom::TextSize size) { } + // Returns whether this tab contents is waiting for a first-response for the + // main resource of the page. This controls whether the throbber state is + // "waiting" or "loading." + bool waiting_for_response() const { return waiting_for_response_; } - // Asynchronous call to turn on/off encoding auto detector. - virtual void SetEncodingAutoDetector(bool encoding_auto_detector) { } + // Internal state ------------------------------------------------------------ - // Asynchronous call to change page encoding. - virtual void SetPageEncoding(const std::wstring& encoding_name) { } + // For use when switching tabs, these functions allow the tab contents to + // hold the per-tab state of the location bar. The tab contents takes + // ownership of the pointer. + void set_saved_location_bar_state(const AutocompleteEditState* state) { + saved_location_bar_state_.reset(state); + } + const AutocompleteEditState* saved_location_bar_state() const { + return saved_location_bar_state_.get(); + } - // Return whether this tab contents is loading a resource. - bool is_loading() const { return is_loading_; } + // This flag indicates whether the tab contents is currently being + // screenshotted by the DraggedTabController. + bool capturing_contents() const { return capturing_contents_; } + void set_capturing_contents(bool cap) { capturing_contents_ = cap; } - // Returns whether this tab contents is waiting for an first-response from - // and external resource. - bool response_started() const { return response_started_; } + // Indicates whether this tab should be considered crashed. The setter will + // also notify the delegate when the flag is changed. + bool is_crashed() const { return is_crashed_; } + void SetIsCrashed(bool state); // Set whether this tab contents is active. A tab content is active for a // given tab if it is currently being used to display some contents. Note that // this is different from whether a tab is selected. - virtual void SetActive(bool active) { is_active_ = active; } bool is_active() const { return is_active_; } + void set_is_active(bool active) { is_active_ = active; } + + // Convenience method for notifying the delegate of a navigation state + // change. See TabContentsDelegate. + void NotifyNavigationStateChanged(unsigned changed_flags); + + // Invoked when the tab contents becomes selected. If you override, be sure + // and invoke super's implementation. + virtual void DidBecomeSelected(); + + // Invoked when the tab contents becomes hidden. + // NOTE: If you override this, call the superclass version too! + virtual void WasHidden(); + + // Activates this contents within its containing window, bringing that window + // to the foreground if necessary. + virtual void Activate(); + + // Commands ------------------------------------------------------------------ + + // Implementation of PageNavigator. + virtual void OpenURL(const GURL& url, + WindowOpenDisposition disposition, + PageTransition::Type transition); // Called by the NavigationController to cause the TabContents to navigate to // the current pending entry. The NavigationController should be called back @@ -294,21 +287,57 @@ class TabContents : public PageNavigator, // Stop any pending navigation. virtual void Stop() {} - // Convenience method for notifying the delegate of a navigation state - // change. See TabContentsDelegate. - void NotifyNavigationStateChanged(unsigned changed_flags); + // An asynchronous call to trigger the string search in the page. + // It sends an IPC message to the Renderer that handles the string + // search, selecting the matches and setting the caret positions. + // This function also starts the asynchronous scoping effort. + virtual void StartFinding(int request_id, + const std::wstring& string, + bool forward, bool match_case, + bool find_next) { } - // Invoked when the tab contents becomes selected. If you override, be sure - // and invoke super's implementation. - virtual void DidBecomeSelected(); + // An asynchronous call to stop the string search in the page. If + // |clear_selection| is true, it will also clear the selection on the + // focused frame. + virtual void StopFinding(bool clear_selection) { } - // Invoked when the tab contents becomes hidden. - // NOTE: If you override this, call the superclass version too! - virtual void WasHidden(); + // TODO(erg): HACK ALERT! This was thrown together for beta and + // needs to be completely removed after we ship it. Right now, the + // cut/copy/paste menu items are always enabled and will send a + // cut/copy/paste command to the currently visible + // TabContents. Post-beta, this needs to be replaced with a unified + // interface for supporting cut/copy/paste, and managing who has + // cut/copy/paste focus. (http://b/1117225) + virtual void Cut() { } + virtual void Copy() { } + virtual void Paste() { } - // Activates this contents within its containing window, bringing that window - // to the foreground if necessary. - virtual void Activate(); + // Window management --------------------------------------------------------- + + // Create a new window constrained to this TabContents' clip and visibility. + // The window is initialized by using the supplied delegate to obtain basic + // window characteristics, and the supplied view for the content. The window + // is sized according to the preferred size of the content_view, and centered + // within the contents. + ConstrainedWindow* CreateConstrainedDialog( + ChromeViews::WindowDelegate* window_delegate, + ChromeViews::View* contents_view); + + // Adds a new tab or window with the given already-created contents + void AddNewContents(TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture); + + // Builds a ConstrainedWindow* for the incoming |new_contents| and + // adds it to child_windows_. + void AddConstrainedPopup(TabContents* new_contents, + const gfx::Rect& initial_pos); + + // When a tab is closed, this method is called for all the remaining tabs. If + // they all return false or if no tabs are left, the window is closed. The + // default is to return true + virtual bool ShouldPreventWindowClose() { return true; } // Closes all constrained windows that represent web popups that have not yet // been activated by the user and are as such auto-positioned in the bottom @@ -316,41 +345,34 @@ class TabContents : public PageNavigator, // of unwanted popups. void CloseAllSuppressedPopups(); - // Displays the download shelf and animation when a download occurs. - void OnStartDownload(DownloadItem* download); + // Show, Hide and Size the TabContents. + // TODO(beng): (Cleanup) Show/Size TabContents should be made to actually + // show and size the View. For simplicity sake, for now they're + // just empty. This is currently a bit of a mess and is just a + // band-aid. + virtual void ShowContents() {} + virtual void HideContents(); + virtual void SizeContents(const gfx::Size& size) {} - // ConstrainedTabContentsDelegate methods: - virtual void AddNewContents(ConstrainedWindow* window, - TabContents* contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture); - virtual void OpenURL(ConstrainedWindow* window, - const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition); - virtual void WillClose(ConstrainedWindow* window); - virtual void DetachContents(ConstrainedWindow* window, - TabContents* contents, - const gfx::Rect& contents_bounds, - const gfx::Point& mouse_pt, - int frame_component); - virtual void DidMoveOrResize(ConstrainedWindow* window); + // Views and focus ----------------------------------------------------------- // Returns the actual window that is focused when this TabContents is shown. virtual HWND GetContentHWND() { return GetContainerHWND(); } - // PageNavigator methods: - virtual void OpenURL(const GURL& url, - WindowOpenDisposition disposition, - PageTransition::Type transition); + // Tell the subclass to set up the view (e.g. create the container HWND if + // applicable) and any other create-time setup. + virtual void CreateView(HWND parent_hwnd, const gfx::Rect& initial_bounds) {} - // NotificationObserver implementation. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { } + // Returns the HWND associated with this TabContents. Outside of automation + // in the context of the UI, this is required to be implemented. + virtual HWND GetContainerHWND() const { return NULL; } + + // Returns the bounds of this TabContents in the screen coordinate system. + virtual void GetContainerBounds(gfx::Rect *out) const { + out->SetRect(0, 0, 0, 0); + } // Make the tab the focused window. virtual void Focus(); @@ -362,20 +384,16 @@ class TabContents : public PageNavigator, // invoked, SetInitialFocus is invoked. virtual void RestoreFocus(); - // When a tab is closed, this method is called for all the remaining tabs. If - // they all return false or if no tabs are left, the window is closed. The - // default is to return true - virtual bool ShouldPreventWindowClose() { - return true; - } - - // Returns the View to display at the top of the tab. - virtual InfoBarView* GetInfoBarView() { return NULL; } - - // Returns whether the info bar is visible. - // If the visibility dynamically changes, invoke ToolbarSizeChanged - // on the delegate. Which forces the frame to layout if size has changed. - virtual bool IsInfoBarVisible() { return false; } + // Invoked the first time this tab is getting the focus through TAB traversal. + // By default this does nothing, but is overridden to set the focus for the + // first element in the page. + // + // |reverse| indicates if the user is going forward or backward, so we know + // whether to set the first or last element focus. + // + // See also SetInitialFocus(no arg). + // FIXME(brettw) having two SetInitialFocus that do different things is silly. + virtual void SetInitialFocus(bool reverse) { } // TabContents that contain View hierarchy (such as NativeUIContents) should // return their RootView. Other TabContents (such as WebContents) should @@ -388,54 +406,18 @@ class TabContents : public PageNavigator, // the focus is passed to the RootView. virtual ChromeViews::RootView* GetContentsRootView() { return NULL; } - // Invoked the first time this tab is getting the focus through TAB traversal. - virtual void SetInitialFocus(bool reverse) { } - + // Toolbars and such --------------------------------------------------------- + // Returns whether the bookmark bar should be visible. virtual bool IsBookmarkBarAlwaysVisible() { return false; } - // Called before and after capturing an image of this tab contents. The tab - // contents may be temporarily re-parented after WillCaptureContents. - virtual void WillCaptureContents() {} - virtual void DidCaptureContents() {} - - // Returns true if the tab is currently loading a resource. - virtual bool IsLoading() const { return is_loading_; } - - // Returns a human-readable description the tab's loading state. - virtual std::wstring GetStatusText() const { return std::wstring(); } - - const std::wstring& GetEncoding() { return encoding_name_; } - void SetEncoding(const std::wstring& encoding_name) { - encoding_name_ = encoding_name; - } - - // Changes the IsCrashed state and notifies the delegate as needed. - void SetIsCrashed(bool state); - - // Return whether this tab should be considered crashed. - bool IsCrashed() const; - - // Returns whether this tab contents supports the provided URL. By default, - // this method matches the tab contents type with the result of TypeForURL(). - // |url| points to the actual URL that will be used. It can be modified as - // needed. - // Override this method if your TabContents subclass supports various URL - // schemes but doesn't want to be the default handler for these schemes. - // For example, the NewTabUIContents overrides this method to support - // javascript: URLs. - virtual bool SupportsURL(GURL* url); + // Returns the View to display at the top of the tab. + virtual InfoBarView* GetInfoBarView() { return NULL; } - // TODO(erg): HACK ALERT! This was thrown together for beta and - // needs to be completely removed after we ship it. Right now, the - // cut/copy/paste menu items are always enabled and will send a - // cut/copy/paste command to the currently visible - // TabContents. Post-beta, this needs to be replaced with a unified - // interface for supporting cut/copy/paste, and managing who has - // cut/copy/paste focus. (http://b/1117225) - virtual void Cut() { } - virtual void Copy() { } - virtual void Paste() { } + // Returns whether the info bar is visible. + // If the visibility dynamically changes, invoke ToolbarSizeChanged + // on the delegate. Which forces the frame to layout if size has changed. + virtual bool IsInfoBarVisible() { return false; } // Whether or not the shelf view is visible. virtual void SetDownloadShelfVisible(bool visible); @@ -444,6 +426,9 @@ class TabContents : public PageNavigator, // Notify our delegate that some of our content has animated. void ToolbarSizeChanged(bool is_animating); + // Displays the download shelf and animation when a download occurs. + void OnStartDownload(DownloadItem* download); + // Returns the DownloadShelfView, creating it if necessary. DownloadShelfView* GetDownloadShelfView(); @@ -457,13 +442,36 @@ class TabContents : public PageNavigator, // want to generalize this if we need to migrate some other state. static void MigrateShelfView(TabContents* from, TabContents* to); - static void RegisterUserPrefs(PrefService* prefs); + // ConstrainedTabContentsDelegate -------------------------------------------- + + virtual void AddNewContents(ConstrainedWindow* window, + TabContents* contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture); + virtual void OpenURL(ConstrainedWindow* window, + const GURL& url, + WindowOpenDisposition disposition, + PageTransition::Type transition); + virtual void WillClose(ConstrainedWindow* window); + virtual void DetachContents(ConstrainedWindow* window, + TabContents* contents, + const gfx::Rect& contents_bounds, + const gfx::Point& mouse_pt, + int frame_component); + virtual void DidMoveOrResize(ConstrainedWindow* window); protected: friend class NavigationController; + // Used to access the child_windows_ (ConstrainedWindowList) for testing + // automation purposes. + friend class AutomationProvider; explicit TabContents(TabContentsType type); + // Some tab contents types need to override the type. + void set_type(TabContentsType type) { type_ = type; } + // NOTE: the TabContents destructor can run after the NavigationController // has gone away, so any complicated unregistering that expects the profile // or other shared objects to still be around does not belong in a @@ -472,14 +480,16 @@ class TabContents : public PageNavigator, // Protected so that others don't try to delete this directly. virtual ~TabContents(); - // Set focus on the initial component. This is invoked from - // RestoreFocus if SetLastFocusOwner has not yet been invoked. + // Sets focus to the tab contents window, but doesn't actuall set focus to + // a particular element in it (see also SetInitialFocus(bool) which does + // that in different circumstances). + // FIXME(brettw) having two SetInitialFocus that do different things is silly. virtual void SetInitialFocus(); // Changes the IsLoading state and notifies delegate as needed // |details| is used to provide details on the load that just finished - // (but can be null if not applicable) - void SetIsLoading(bool is_loading, LoadNotificationDetails* details); + // (but can be null if not applicable). Can be overridden. + virtual void SetIsLoading(bool is_loading, LoadNotificationDetails* details); // Called by a derived class when the TabContents is resized, causing // suppressed constrained web popups to be repositioned to the new bounds @@ -491,26 +501,33 @@ class TabContents : public PageNavigator, // invoke TabContents::ReleaseDownloadShelfView(). virtual void ReleaseDownloadShelfView(); - bool is_loading_; // true if currently loading a resource. - bool response_started_; // true if waiting for a response. - bool is_active_; - bool is_crashed_; // true if the tab is considered crashed. + // Called by derived classes to indicate that we're no longer waiting for a + // response. This won't actually update the throbber, but it will get picked + // up at the next animation step if the throbber is going. + void SetNotWaitingForResponse() { waiting_for_response_ = false; } typedef std::vector<ConstrainedWindow*> ConstrainedWindowList; ConstrainedWindowList child_windows_; - TabContentsType type_; - private: - ConstrainedWindowList child_windows() const { return child_windows_; } + // Data ---------------------------------------------------------------------- - // Clear the last focus view and unregister the notification associated with - // it. - void ClearLastFocusedView(); + TabContentsType type_; TabContentsDelegate* delegate_; NavigationController* controller_; + // Indicates whether we're currently loading a resource. + bool is_loading_; + + // See is_active() getter above. + bool is_active_; + + bool is_crashed_; // true if the tab is considered crashed. + + // See waiting_for_response() above. + bool waiting_for_response_; + scoped_ptr<const AutocompleteEditState> saved_location_bar_state_; // The download shelf view (view at the bottom of the page). @@ -528,7 +545,11 @@ class TabContents : public PageNavigator, int last_focused_view_storage_id_; std::wstring encoding_name_; + + // See capturing_contents() above. + bool capturing_contents_; + + DISALLOW_COPY_AND_ASSIGN(TabContents); }; #endif // CHROME_BROWSER_TAB_CONTENTS_H_ - diff --git a/chrome/browser/view_source_contents.cc b/chrome/browser/view_source_contents.cc index 8e0c052..6ba3fc7 100644 --- a/chrome/browser/view_source_contents.cc +++ b/chrome/browser/view_source_contents.cc @@ -9,7 +9,7 @@ ViewSourceContents::ViewSourceContents(Profile* profile, SiteInstance* instance) : WebContents(profile, instance, NULL, MSG_ROUTING_NONE, NULL) { - type_ = TAB_CONTENTS_VIEW_SOURCE; + set_type(TAB_CONTENTS_VIEW_SOURCE); } void ViewSourceContents::RendererCreated(RenderViewHost* host) { diff --git a/chrome/browser/views/tab_contents_container_view.cc b/chrome/browser/views/tab_contents_container_view.cc index 582726a..d6881652 100644 --- a/chrome/browser/views/tab_contents_container_view.cc +++ b/chrome/browser/views/tab_contents_container_view.cc @@ -170,7 +170,7 @@ bool TabContentsContainerView::GetAccessibleRole(VARIANT* role) { bool TabContentsContainerView::ShouldLookupAccelerators( const ChromeViews::KeyEvent& e) { - if (tab_contents_ && !tab_contents_->IsCrashed() && + if (tab_contents_ && !tab_contents_->is_crashed() && tab_contents_->AsWebContents()) return false; return true; diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc index 82c002e..cd8bd69 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.cc +++ b/chrome/browser/views/tabs/dragged_tab_controller.cc @@ -463,7 +463,7 @@ void DraggedTabController::Attach(TabStrip* attached_tabstrip, original_delegate_ = NULL; // Return the TabContents' to normalcy. - dragged_contents_->DidCaptureContents(); + dragged_contents_->set_capturing_contents(false); // We need to ask the TabStrip we're attached to to ensure that the ideal // bounds for all its tabs are correctly generated, because the calculation @@ -497,7 +497,7 @@ void DraggedTabController::Attach(TabStrip* attached_tabstrip, void DraggedTabController::Detach() { // Prevent the TabContents' HWND from being hidden by any of the model // operations performed during the drag. - dragged_contents_->WillCaptureContents(); + dragged_contents_->set_capturing_contents(true); // Update the Model. TabStripModel* attached_model = attached_tabstrip_->model(); diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc index 2dd430d..e4505a3 100644 --- a/chrome/browser/views/tabs/tab_renderer.cc +++ b/chrome/browser/views/tabs/tab_renderer.cc @@ -270,7 +270,7 @@ void TabRenderer::UpdateData(TabContents* contents) { data_.off_the_record = contents->profile()->IsOffTheRecord(); data_.show_icon = contents->ShouldDisplayFavIcon(); data_.show_download_icon = contents->IsDownloadShelfVisible(); - data_.crashed = contents->IsCrashed(); + data_.crashed = contents->is_crashed(); } void TabRenderer::UpdateFromModel() { diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 768604c..ec1a705 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -1277,7 +1277,7 @@ void TabStrip::LoadingAnimationCallback() { TabContents* contents = model_->GetTabContentsAt(index); if (!contents || !contents->is_loading()) { current_tab->ValidateLoadingAnimation(Tab::ANIMATION_NONE); - } else if (contents->response_started()) { + } else if (contents->waiting_for_response()) { current_tab->ValidateLoadingAnimation(Tab::ANIMATION_WAITING); } else { current_tab->ValidateLoadingAnimation(Tab::ANIMATION_LOADING); diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc index 9549f4b..782df56 100644 --- a/chrome/browser/web_contents.cc +++ b/chrome/browser/web_contents.cc @@ -5,6 +5,7 @@ #include "chrome/browser/web_contents.h" #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/file_version_info.h" #include "chrome/app/locales/locale_settings.h" #include "chrome/browser/bookmarks/bookmark_model.h" @@ -50,6 +51,45 @@ #include "generated_resources.h" +// Cross-Site Navigations +// +// If a WebContents is told to navigate to a different web site (as determined +// by SiteInstance), it will replace its current RenderViewHost with a new +// RenderViewHost dedicated to the new SiteInstance. This works as follows: +// +// - Navigate determines whether the destination is cross-site, and if so, +// it creates a pending_render_view_host_ and moves into the PENDING +// RendererState. +// - The pending RVH is "suspended," so that no navigation messages are sent to +// its renderer until the onbeforeunload JavaScript handler has a chance to +// run in the current RVH. +// - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton) +// that it has a pending cross-site request. ResourceDispatcherHost will +// check for this when the response arrives. +// - The current RVH runs its onbeforeunload handler. If it returns false, we +// cancel all the pending logic and go back to NORMAL. Otherwise we allow +// the pending RVH to send the navigation request to its renderer. +// - ResourceDispatcherHost receives a ResourceRequest on the IO thread. It +// checks CrossSiteRequestManager to see that the RVH responsible has a +// pending cross-site request, and then installs a CrossSiteEventHandler. +// - When RDH receives a response, the BufferedEventHandler determines whether +// it is a download. If so, it sends a message to the new renderer causing +// it to cancel the request, and the download proceeds in the download +// thread. For now, we stay in a PENDING state (with a pending RVH) until +// the next DidNavigate event for this WebContents. This isn't ideal, but it +// doesn't affect any functionality. +// - After RDH receives a response and determines that it is safe and not a +// download, it pauses the response to first run the old page's onunload +// handler. It does this by asynchronously calling the OnCrossSiteResponse +// method of WebContents on the UI thread, which sends a ClosePage message +// to the current RVH. +// - Once the onunload handler is finished, a ClosePage_ACK message is sent to +// the ResourceDispatcherHost, who unpauses the response. Data is then sent +// to the pending RVH. +// - The pending renderer sends a FrameNavigate message that invokes the +// DidNavigate method. This replaces the current RVH with the +// pending RVH and goes back to the NORMAL RendererState. + namespace { // Amount of time we wait between when a key event is received and the renderer @@ -104,10 +144,13 @@ void InitWebContentsClass() { } } -} // namespace +// Returns true if the entry's transition type is FORM_SUBMIT. +bool IsFormSubmit(const NavigationEntry* entry) { + return (PageTransition::StripQualifier(entry->transition_type()) == + PageTransition::FORM_SUBMIT); +} -/////////////////////////////////////////////////////////////////////////////// -// WebContents +} // namespace class WebContents::GearsCreateShortcutCallbackFunctor { public: @@ -127,6 +170,53 @@ class WebContents::GearsCreateShortcutCallbackFunctor { WebContents* contents_; }; +WebContents::WebContents(Profile* profile, + SiteInstance* site_instance, + RenderViewHostFactory* render_view_factory, + int routing_id, + HANDLE modal_dialog_event) + : TabContents(TAB_CONTENTS_WEB), + ALLOW_THIS_IN_INITIALIZER_LIST( + render_manager_(render_view_factory, this, this)), + render_view_factory_(render_view_factory), + has_page_title_(false), + info_bar_visible_(false), + is_starred_(false), + printing_(*this), + notify_disconnection_(false), + message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), + ALLOW_THIS_IN_INITIALIZER_LIST(fav_icon_helper_(this)), + crashed_plugin_info_bar_(NULL), + suppress_javascript_messages_(false), + load_state_(net::LOAD_STATE_IDLE) { + InitWebContentsClass(); + + pending_install_.page_id = 0; + pending_install_.callback_functor = NULL; + + render_manager_.Init(profile, site_instance, routing_id, modal_dialog_event); + + // Register for notifications about all interested prefs change. + PrefService* prefs = profile->GetPrefs(); + if (prefs) + for (int i = 0; i < kPrefsToObserveLength; ++i) + prefs->AddPrefObserver(kPrefsToObserve[i], this); + + // Register for notifications about URL starredness changing on any profile. + NotificationService::current()-> + AddObserver(this, NOTIFY_URLS_STARRED, NotificationService::AllSources()); + NotificationService::current()-> + AddObserver(this, NOTIFY_BOOKMARK_MODEL_LOADED, + NotificationService::AllSources()); +} + +WebContents::~WebContents() { + if (web_app_.get()) + web_app_->RemoveObserver(this); + if (pending_install_.callback_functor) + pending_install_.callback_functor->Cancel(); +} + // static void WebContents::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true); @@ -181,104 +271,16 @@ void WebContents::RegisterUserPrefs(PrefService* prefs) { IDS_STATIC_ENCODING_LIST); } -WebContents::WebContents(Profile* profile, - SiteInstance* site_instance, - RenderViewHostFactory* render_view_factory, - int routing_id, - HANDLE modal_dialog_event) - : TabContents(TAB_CONTENTS_WEB), -#pragma warning(suppress: 4355) // Okay to pass "this" here. - render_manager_(render_view_factory, this, this), - render_view_factory_(render_view_factory), - has_page_title_(false), - info_bar_visible_(false), - is_starred_(false), - printing_(*this), - notify_disconnection_(false), - message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), - capturing_contents_(false), -#pragma warning(suppress: 4355) // Okay to pass "this" here. - fav_icon_helper_(this), - crashed_plugin_info_bar_(NULL), - suppress_javascript_messages_(false), - load_state_(net::LOAD_STATE_IDLE) { - InitWebContentsClass(); - - pending_install_.page_id = 0; - pending_install_.callback_functor = NULL; - - render_manager_.Init(profile, site_instance, routing_id, modal_dialog_event); - - // Register for notifications about all interested prefs change. - PrefService* prefs = profile->GetPrefs(); - if (prefs) - for (int i = 0; i < kPrefsToObserveLength; ++i) - prefs->AddPrefObserver(kPrefsToObserve[i], this); - - // Register for notifications about URL starredness changing on any profile. - NotificationService::current()-> - AddObserver(this, NOTIFY_URLS_STARRED, NotificationService::AllSources()); - NotificationService::current()-> - AddObserver(this, NOTIFY_BOOKMARK_MODEL_LOADED, - NotificationService::AllSources()); -} - -WebContents::~WebContents() { - if (web_app_.get()) - web_app_->RemoveObserver(this); - if (pending_install_.callback_functor) - pending_install_.callback_functor->Cancel(); -} - -void WebContents::CreateView(HWND parent_hwnd, - const gfx::Rect& initial_bounds) { - set_delete_on_destroy(false); - HWNDViewContainer::Init(parent_hwnd, initial_bounds, false); - - // Remove the root view drop target so we can register our own. - RevokeDragDrop(GetHWND()); - drop_target_ = new WebDropTarget(GetHWND(), this); -} - -void WebContents::GetContainerBounds(gfx::Rect *out) const { - CRect r; - GetBounds(&r, false); - *out = r; -} - -void WebContents::ShowContents() { - if (view()) - view()->DidBecomeSelected(); - - // Loop through children and send DidBecomeSelected to them, too. - int count = static_cast<int>(child_windows_.size()); - for (int i = count - 1; i >= 0; --i) { - ConstrainedWindow* window = child_windows_.at(i); - window->DidBecomeSelected(); - } - - // If we have a FindInPage dialog, notify it that its tab was selected. - if (find_in_page_controller_.get()) - find_in_page_controller_->DidBecomeSelected(); -} - -void WebContents::HideContents() { - // TODO(pkasting): http://b/1239839 Right now we purposefully don't call - // our superclass HideContents(), because some callers want to be very picky - // about the order in which these get called. In addition to making the code - // here practically impossible to understand, this also means we end up - // calling TabContents::WasHidden() twice if callers call both versions of - // HideContents() on a WebContents. - - WasHidden(); +PasswordManager* WebContents::GetPasswordManager() { + if (password_manager_.get() == NULL) + password_manager_.reset(new PasswordManager(this)); + return password_manager_.get(); } -void WebContents::SizeContents(const gfx::Size& size) { - if (view()) - view()->SetSize(size); - if (find_in_page_controller_.get()) - find_in_page_controller_->RespondToResize(size); - RepositionSupressedPopupsToFit(size); +PluginInstaller* WebContents::GetPluginInstaller() { + if (plugin_installer_.get() == NULL) + plugin_installer_.reset(new PluginInstaller(this)); + return plugin_installer_.get(); } void WebContents::Destroy() { @@ -316,290 +318,43 @@ void WebContents::Destroy() { TabContents::Destroy(); } -/////////////////////////////////////////////////////////////////////////////// -// Event Handlers - -void WebContents::OnDestroy() { - if (drop_target_.get()) { - RevokeDragDrop(GetHWND()); - drop_target_ = NULL; - } -} - -void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) { - if (window_pos->flags & SWP_HIDEWINDOW) { - HideContents(); - } else { - // The WebContents was shown by a means other than the user selecting a - // Tab, e.g. the window was minimized then restored. - if (window_pos->flags & SWP_SHOWWINDOW) - ShowContents(); - // Unless we were specifically told not to size, cause the renderer to be - // sized to the new bounds, which forces a repaint. Not required for the - // simple minimize-restore case described above, for example, since the - // size hasn't changed. - if (!(window_pos->flags & SWP_NOSIZE)) { - gfx::Size size(window_pos->cx, window_pos->cy); - SizeContents(size); - } - - // If we have a FindInPage dialog, notify it that the window changed. - if (find_in_page_controller_.get() && find_in_page_controller_->IsVisible()) - find_in_page_controller_->MoveWindowIfNecessary(gfx::Rect()); - } -} - -void WebContents::OnPaint(HDC junk_dc) { - if (render_view_host() && !render_view_host()->IsRenderViewLive()) { - if (!sad_tab_.get()) - sad_tab_.reset(new SadTabView); - CRect cr; - GetClientRect(&cr); - sad_tab_->SetBounds(cr); - ChromeCanvasPaint canvas(GetHWND(), true); - sad_tab_->ProcessPaint(&canvas); - return; - } - - // We need to do this to validate the dirty area so we don't end up in a - // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not - // firing etc). It doesn't matter that we don't have any non-clipped area. - CPaintDC dc(GetHWND()); - SetMsgHandled(FALSE); -} - -LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) { - switch (msg) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - // Make sure this TabContents is activated when it is clicked on. - if (delegate()) - delegate()->ActivateContents(this); - break; - case WM_MOUSEMOVE: - // Let our delegate know that the mouse moved (useful for resetting status - // bubble state). - if (delegate()) - delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE); - break; - default: - break; - } - - return 0; +SiteInstance* WebContents::GetSiteInstance() const { + return render_manager_.current_host()->site_instance(); } -void WebContents::OnMouseLeave() { - // Let our delegate know that the mouse moved (useful for resetting status - // bubble state). - if (delegate()) - delegate()->ContentsMouseEvent(this, WM_MOUSELEAVE); - SetMsgHandled(FALSE); -} - -// A message is reflected here from view(). -// Return non-zero to indicate that it is handled here. -// Return 0 to allow view() to further process it. -LRESULT WebContents::OnReflectedMessage(UINT msg, WPARAM w_param, - LPARAM l_param) { - MSG* message = reinterpret_cast<MSG*>(l_param); - switch (message->message) { - case WM_MOUSEWHEEL: - // This message is reflected from the view() to this window. - if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) { - WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam)); - return 1; - } - break; - case WM_HSCROLL: - case WM_VSCROLL: - if (ScrollZoom(LOWORD(message->wParam))) - return 1; - default: - break; - } - - return 0; -} - -void WebContents::OnSize(UINT param, const CSize& size) { - HWNDViewContainer::OnSize(param, size); - - // Hack for thinkpad touchpad driver. - // Set fake scrollbars so that we can get scroll messages, - SCROLLINFO si = {0}; - si.cbSize = sizeof(si); - si.fMask = SIF_ALL; - - si.nMin = 1; - si.nMax = 100; - si.nPage = 10; - si.nTrackPos = 50; - - ::SetScrollInfo(GetHWND(), SB_HORZ, &si, FALSE); - ::SetScrollInfo(GetHWND(), SB_VERT, &si, FALSE); -} - -LRESULT WebContents::OnNCCalcSize(BOOL w_param, LPARAM l_param) { - // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars - // to receive scroll messages from thinkpad touchpad driver. Suppress - // painting of scrollbars by returning 0 size for them. - return 0; -} - -void WebContents::OnNCPaint(HRGN rgn) { - // Suppress default WM_NCPAINT handling. We don't need to do anything - // here since the view will draw everything correctly. -} - -void WebContents::OnHScroll(int scroll_type, short position, HWND scrollbar) { - ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar); -} - -void WebContents::OnVScroll(int scroll_type, short position, HWND scrollbar) { - ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar); -} - -void WebContents::ScrollCommon(UINT message, int scroll_type, short position, - HWND scrollbar) { - // This window can receive scroll events as a result of the ThinkPad's - // Trackpad scroll wheel emulation. - if (!ScrollZoom(scroll_type)) { - // Reflect scroll message to the view() to give it a chance - // to process scrolling. - SendMessage(GetContentHWND(), message, MAKELONG(scroll_type, position), - (LPARAM) scrollbar); - } -} - -bool WebContents::ScrollZoom(int scroll_type) { - // If ctrl is held, zoom the UI. There are three issues with this: - // 1) Should the event be eaten or forwarded to content? We eat the event, - // which is like Firefox and unlike IE. - // 2) Should wheel up zoom in or out? We zoom in (increase font size), which - // is like IE and Google maps, but unlike Firefox. - // 3) Should the mouse have to be over the content area? We zoom as long as - // content has focus, although FF and IE require that the mouse is over - // content. This is because all events get forwarded when content has - // focus. - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { - int distance = 0; - switch (scroll_type) { - case SB_LINEUP: - distance = WHEEL_DELTA; - break; - case SB_LINEDOWN: - distance = -WHEEL_DELTA; - break; - // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, - // and SB_THUMBTRACK for completeness - default: - break; - } - - WheelZoom(distance); - return true; - } - return false; -} - -void WebContents::WheelZoom(int distance) { - if (delegate()) { - bool zoom_in = distance > 0; - delegate()->ContentsZoomChange(zoom_in); +SkBitmap WebContents::GetFavIcon() { + if (web_app_.get() && IsWebApplicationActive()) { + SkBitmap app_icon = web_app_->GetFavIcon(); + if (!app_icon.isNull()) + return app_icon; } + return TabContents::GetFavIcon(); } -void WebContents::OnSetFocus(HWND window) { - // TODO(jcampan): figure out why removing this prevents tabs opened in the - // background from properly taking focus. - // We NULL-check the render_view_host_ here because Windows can send us - // messages during the destruction process after it has been destroyed. - if (view()) { - HWND inner_hwnd = view()->GetPluginHWND(); - if (::IsWindow(inner_hwnd)) - ::SetFocus(inner_hwnd); - } -} +std::wstring WebContents::GetStatusText() const { + if (!is_loading() || load_state_ == net::LOAD_STATE_IDLE) + return std::wstring(); -void WebContents::OnSavePage() { - // If we can not save the page, try to download it. - if (!SavePackage::IsSavableContents(contents_mime_type())) { - DownloadManager* dlm = profile()->GetDownloadManager(); - const GURL& current_page_url = GetURL(); - if (dlm && current_page_url.is_valid()) - dlm->DownloadUrl(current_page_url, GURL(), this); - return; + switch (load_state_) { + case net::LOAD_STATE_WAITING_FOR_CACHE: + return l10n_util::GetString(IDS_LOAD_STATE_WAITING_FOR_CACHE); + case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL: + return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL); + case net::LOAD_STATE_RESOLVING_HOST: + return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_HOST); + case net::LOAD_STATE_CONNECTING: + return l10n_util::GetString(IDS_LOAD_STATE_CONNECTING); + case net::LOAD_STATE_SENDING_REQUEST: + return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST); + case net::LOAD_STATE_WAITING_FOR_RESPONSE: + return l10n_util::GetStringF(IDS_LOAD_STATE_WAITING_FOR_RESPONSE, + load_state_host_); + // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE } - // Get our user preference state. - PrefService* prefs = profile()->GetPrefs(); - DCHECK(prefs); - - std::wstring suggest_name = - SavePackage::GetSuggestNameForSaveAs(prefs, GetTitle()); - - SavePackage::SavePackageParam param(contents_mime_type()); - param.prefs = prefs; - - // TODO(rocking): Use new asynchronous dialog boxes to prevent the SaveAs - // dialog blocking the UI thread. See bug: http://b/issue?id=1129694. - if (SavePackage::GetSaveInfo(suggest_name, GetContainerHWND(), ¶m)) - SavePage(param.saved_main_file_path, param.dir, param.save_type); -} - -void WebContents::SavePage(const std::wstring& main_file, - const std::wstring& dir_path, - SavePackage::SavePackageType save_type) { - // Stop the page from navigating. - Stop(); - - save_package_ = new SavePackage(this, save_type, main_file, dir_path); - save_package_->Init(); + return std::wstring(); } -/////////////////////////////////////////////////////////////////////////////// - -// Cross-Site Navigations -// -// If a WebContents is told to navigate to a different web site (as determined -// by SiteInstance), it will replace its current RenderViewHost with a new -// RenderViewHost dedicated to the new SiteInstance. This works as follows: -// -// - Navigate determines whether the destination is cross-site, and if so, -// it creates a pending_render_view_host_ and moves into the PENDING -// RendererState. -// - The pending RVH is "suspended," so that no navigation messages are sent to -// its renderer until the onbeforeunload JavaScript handler has a chance to -// run in the current RVH. -// - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton) -// that it has a pending cross-site request. ResourceDispatcherHost will -// check for this when the response arrives. -// - The current RVH runs its onbeforeunload handler. If it returns false, we -// cancel all the pending logic and go back to NORMAL. Otherwise we allow -// the pending RVH to send the navigation request to its renderer. -// - ResourceDispatcherHost receives a ResourceRequest on the IO thread. It -// checks CrossSiteRequestManager to see that the RVH responsible has a -// pending cross-site request, and then installs a CrossSiteEventHandler. -// - When RDH receives a response, the BufferedEventHandler determines whether -// it is a download. If so, it sends a message to the new renderer causing -// it to cancel the request, and the download proceeds in the download -// thread. For now, we stay in a PENDING state (with a pending RVH) until -// the next DidNavigate event for this WebContents. This isn't ideal, but it -// doesn't affect any functionality. -// - After RDH receives a response and determines that it is safe and not a -// download, it pauses the response to first run the old page's onunload -// handler. It does this by asynchronously calling the OnCrossSiteResponse -// method of WebContents on the UI thread, which sends a ClosePage message -// to the current RVH. -// - Once the onunload handler is finished, a ClosePage_ACK message is sent to -// the ResourceDispatcherHost, who unpauses the response. Data is then sent -// to the pending RVH. -// - The pending renderer sends a FrameNavigate message that invokes the -// DidNavigate method. This replaces the current RVH with the -// pending RVH and goes back to the NORMAL RendererState. - bool WebContents::NavigateToPendingEntry(bool reload) { NavigationEntry* entry = controller()->GetPendingEntry(); RenderViewHost* dest_render_view_host = render_manager_.Navigate(*entry); @@ -637,6 +392,31 @@ void WebContents::Stop() { printing_.Stop(); } +void WebContents::StartFinding(int request_id, + const std::wstring& search_string, + bool forward, + bool match_case, + bool find_next) { + render_view_host()->StartFinding(request_id, search_string, forward, + match_case, find_next); +} + +void WebContents::StopFinding(bool clear_selection) { + render_view_host()->StopFinding(clear_selection); +} + +void WebContents::Cut() { + render_view_host()->Cut(); +} + +void WebContents::Copy() { + render_view_host()->Copy(); +} + +void WebContents::Paste() { + render_view_host()->Paste(); +} + void WebContents::DidBecomeSelected() { TabContents::DidBecomeSelected(); @@ -647,7 +427,7 @@ void WebContents::DidBecomeSelected() { } void WebContents::WasHidden() { - if (!capturing_contents_) { + if (!capturing_contents()) { // |render_view_host()| can be NULL if the user middle clicks a link to open // a tab in then background, then closes the tab before selecting it. This // is because closing the tab calls WebContents::Destroy(), which removes @@ -671,17 +451,78 @@ void WebContents::WasHidden() { TabContents::WasHidden(); } -void WebContents::StartFinding(int request_id, - const std::wstring& search_string, - bool forward, - bool match_case, - bool find_next) { - render_view_host()->StartFinding(request_id, search_string, forward, - match_case, find_next); +void WebContents::ShowContents() { + if (view()) + view()->DidBecomeSelected(); + + // Loop through children and send DidBecomeSelected to them, too. + int count = static_cast<int>(child_windows_.size()); + for (int i = count - 1; i >= 0; --i) { + ConstrainedWindow* window = child_windows_.at(i); + window->DidBecomeSelected(); + } + + // If we have a FindInPage dialog, notify it that its tab was selected. + if (find_in_page_controller_.get()) + find_in_page_controller_->DidBecomeSelected(); } -void WebContents::StopFinding(bool clear_selection) { - render_view_host()->StopFinding(clear_selection); +void WebContents::HideContents() { + // TODO(pkasting): http://b/1239839 Right now we purposefully don't call + // our superclass HideContents(), because some callers want to be very picky + // about the order in which these get called. In addition to making the code + // here practically impossible to understand, this also means we end up + // calling TabContents::WasHidden() twice if callers call both versions of + // HideContents() on a WebContents. + WasHidden(); +} + +void WebContents::SizeContents(const gfx::Size& size) { + if (view()) + view()->SetSize(size); + if (find_in_page_controller_.get()) + find_in_page_controller_->RespondToResize(size); + RepositionSupressedPopupsToFit(size); +} + +HWND WebContents::GetContentHWND() { + if (!view()) + return NULL; + return view()->GetPluginHWND(); +} + +void WebContents::CreateView(HWND parent_hwnd, + const gfx::Rect& initial_bounds) { + set_delete_on_destroy(false); + HWNDViewContainer::Init(parent_hwnd, initial_bounds, false); + + // Remove the root view drop target so we can register our own. + RevokeDragDrop(GetHWND()); + drop_target_ = new WebDropTarget(GetHWND(), this); +} + +void WebContents::GetContainerBounds(gfx::Rect *out) const { + CRect r; + GetBounds(&r, false); + *out = r; +} + +InfoBarView* WebContents::GetInfoBarView() { + if (info_bar_view_.get() == NULL) { + info_bar_view_.reset(new InfoBarView(this)); + // The WebContents owns the info-bar. + info_bar_view_->SetParentOwned(false); + } + return info_bar_view_.get(); +} + +void WebContents::SetDownloadShelfVisible(bool visible) { + TabContents::SetDownloadShelfVisible(visible); + if (visible) { + // Always set this value as it reflects the last time the download shelf + // was made visible (even if it was already visible). + last_download_shelf_show_ = TimeTicks::Now(); + } } void WebContents::OpenFindInPageWindow(const Browser& browser) { @@ -736,146 +577,6 @@ bool WebContents::GetFindInPageWindowLocation(int* x, int* y) { return false; } -void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, - bool success, - const std::wstring& prompt) { - last_javascript_message_dismissal_ = TimeTicks::Now(); - render_manager_.OnJavaScriptMessageBoxClosed(reply_msg, success, prompt); -} - -// Generic NotificationObserver callback. -void WebContents::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - TabContents::Observe(type, source, details); - switch (type) { - case NOTIFY_BOOKMARK_MODEL_LOADED: // BookmarkModel finished loading, fall - // through to update starred state. - case NOTIFY_URLS_STARRED: { // Somewhere, a URL has been starred. - // Ignore notifications for profiles other than our current one. - Profile* source_profile = Source<Profile>(source).ptr(); - if (!source_profile->IsSameProfile(profile())) - return; - - UpdateStarredStateForCurrentURL(); - break; - } - case NOTIFY_PREF_CHANGED: { - std::wstring* pref_name_in = Details<std::wstring>(details).ptr(); - DCHECK(Source<PrefService>(source).ptr() == profile()->GetPrefs()); - if (*pref_name_in == prefs::kAlternateErrorPagesEnabled) { - UpdateAlternateErrorPageURL(); - } else if (*pref_name_in == prefs::kDefaultCharset || - StartsWithASCII(WideToUTF8(*pref_name_in), "webkit.webprefs.", true) - ) { - UpdateWebPreferences(); - } else { - NOTREACHED() << "unexpected pref change notification" << *pref_name_in; - } - break; - } - default: { - NOTREACHED(); - break; - } - } -} - -void WebContents::NotifySwapped() { - // After sending out a swap notification, we need to send a disconnect - // notification so that clients that pick up a pointer to |this| can NULL the - // pointer. See Bug 1230284. - notify_disconnection_ = true; - NotificationService::current()-> - Notify(NOTIFY_WEB_CONTENTS_SWAPPED, - Source<WebContents>(this), - NotificationService::NoDetails()); -} - -void WebContents::NotifyConnected() { - notify_disconnection_ = true; - NotificationService::current()-> - Notify(NOTIFY_WEB_CONTENTS_CONNECTED, - Source<WebContents>(this), - NotificationService::NoDetails()); -} - -void WebContents::NotifyDisconnected() { - if (!notify_disconnection_) - return; - - notify_disconnection_ = false; - NotificationService::current()-> - Notify(NOTIFY_WEB_CONTENTS_DISCONNECTED, - Source<WebContents>(this), - NotificationService::NoDetails()); -} - -void WebContents::UpdateHistoryForNavigation(const GURL& display_url, - const ViewHostMsg_FrameNavigate_Params& params) { - if (profile()->IsOffTheRecord()) - return; - - // Add to history service. - HistoryService* hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); - if (hs) { - if (PageTransition::IsMainFrame(params.transition) && - display_url != params.url) { - // Hack on the "display" URL so that it will appear in history. For some - // types of URLs, we will display a magic URL that is different from where - // the page is actually navigated. We want the user to see in history - // what they saw in the URL bar, so we add the display URL as a redirect. - // This only applies to the main frame, as the display URL doesn't apply - // to sub-frames. - std::vector<GURL> redirects = params.redirects; - if (!redirects.empty()) - redirects.back() = display_url; - hs->AddPage(display_url, this, params.page_id, params.referrer, - params.transition, redirects); - } else { - hs->AddPage(params.url, this, params.page_id, params.referrer, - params.transition, params.redirects); - } - } -} - -void WebContents::MaybeCloseChildWindows( - const ViewHostMsg_FrameNavigate_Params& params) { - if (net::RegistryControlledDomainService::SameDomainOrHost( - last_url_, params.url)) - return; - last_url_ = params.url; - - // Clear out any child windows since we are leaving this page entirely. - // We use indices instead of iterators in case CloseWindow does something - // that may invalidate an iterator. - int size = static_cast<int>(child_windows_.size()); - for (int i = size - 1; i >= 0; --i) { - ConstrainedWindow* window = child_windows_[i]; - if (window) - window->CloseConstrainedWindow(); - } -} - -void WebContents::SetDownloadShelfVisible(bool visible) { - TabContents::SetDownloadShelfVisible(visible); - if (visible) { - // Always set this value as it reflects the last time the download shelf - // was made visible (even if it was already visible). - last_download_shelf_show_ = TimeTicks::Now(); - } -} - -void WebContents::SetInfoBarVisible(bool visible) { - if (info_bar_visible_ != visible) { - info_bar_visible_ = visible; - if (info_bar_visible_) { - // Invoke GetInfoBarView to force the info bar to be created. - GetInfoBarView(); - } - ToolbarSizeChanged(false); - } -} void WebContents::SetFindInPageVisible(bool visible) { if (find_in_page_controller_.get()) { @@ -886,15 +587,6 @@ void WebContents::SetFindInPageVisible(bool visible) { } } -InfoBarView* WebContents::GetInfoBarView() { - if (info_bar_view_.get() == NULL) { - info_bar_view_.reset(new InfoBarView(this)); - // The WebContents owns the info-bar. - info_bar_view_->SetParentOwned(false); - } - return info_bar_view_.get(); -} - void WebContents::SetWebApp(WebApp* web_app) { if (web_app_.get()) { web_app_->RemoveObserver(this); @@ -936,16 +628,83 @@ void WebContents::CreateShortcut() { render_view_host()->GetApplicationInfo(pending_install_.page_id); } -PasswordManager* WebContents::GetPasswordManager() { - if (password_manager_.get() == NULL) - password_manager_.reset(new PasswordManager(this)); - return password_manager_.get(); +void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt) { + last_javascript_message_dismissal_ = TimeTicks::Now(); + render_manager_.OnJavaScriptMessageBoxClosed(reply_msg, success, prompt); } -PluginInstaller* WebContents::GetPluginInstaller() { - if (plugin_installer_.get() == NULL) - plugin_installer_.reset(new PluginInstaller(this)); - return plugin_installer_.get(); +void WebContents::SetInfoBarVisible(bool visible) { + if (info_bar_visible_ != visible) { + info_bar_visible_ = visible; + if (info_bar_visible_) { + // Invoke GetInfoBarView to force the info bar to be created. + GetInfoBarView(); + } + ToolbarSizeChanged(false); + } +} + +void WebContents::OnSavePage() { + // If we can not save the page, try to download it. + if (!SavePackage::IsSavableContents(contents_mime_type())) { + DownloadManager* dlm = profile()->GetDownloadManager(); + const GURL& current_page_url = GetURL(); + if (dlm && current_page_url.is_valid()) + dlm->DownloadUrl(current_page_url, GURL(), this); + return; + } + + // Get our user preference state. + PrefService* prefs = profile()->GetPrefs(); + DCHECK(prefs); + + std::wstring suggest_name = + SavePackage::GetSuggestNameForSaveAs(prefs, GetTitle()); + + SavePackage::SavePackageParam param(contents_mime_type()); + param.prefs = prefs; + + // TODO(rocking): Use new asynchronous dialog boxes to prevent the SaveAs + // dialog blocking the UI thread. See bug: http://b/issue?id=1129694. + if (SavePackage::GetSaveInfo(suggest_name, GetContainerHWND(), ¶m)) + SavePage(param.saved_main_file_path, param.dir, param.save_type); +} + +void WebContents::SavePage(const std::wstring& main_file, + const std::wstring& dir_path, + SavePackage::SavePackageType save_type) { + // Stop the page from navigating. + Stop(); + + save_package_ = new SavePackage(this, save_type, main_file, dir_path); + save_package_->Init(); +} + +void WebContents::PrintPreview() { + // We can't print interstitial page for now. + if (render_manager_.showing_interstitial_page()) + return; + + // If we have a FindInPage dialog, notify it that its tab was hidden. + if (find_in_page_controller_.get()) + find_in_page_controller_->DidBecomeUnselected(); + + // We don't show the print preview for the beta, only the print dialog. + printing_.ShowPrintDialog(); +} + +bool WebContents::PrintNow() { + // We can't print interstitial page for now. + if (render_manager_.showing_interstitial_page()) + return false; + + // If we have a FindInPage dialog, notify it that its tab was hidden. + if (find_in_page_controller_.get()) + find_in_page_controller_->DidBecomeUnselected(); + + return printing_.PrintNow(); } bool WebContents::IsActiveEntry(int32 page_id) { @@ -955,8 +714,22 @@ bool WebContents::IsActiveEntry(int32 page_id) { active_entry->page_id() == page_id); } -/////////////////////////////////////////////////////////////////////////////// -// RenderViewHostDelegate implementation: +void WebContents::SetInitialFocus(bool reverse) { + render_view_host()->SetInitialFocus(reverse); +} + +// Notifies the RenderWidgetHost instance about the fact that the page is +// loading, or done loading and calls the base implementation. +void WebContents::SetIsLoading(bool is_loading, + LoadNotificationDetails* details) { + if (!is_loading) { + load_state_ = net::LOAD_STATE_IDLE; + load_state_host_.clear(); + } + + TabContents::SetIsLoading(is_loading, details); + render_manager_.SetIsLoading(is_loading); +} RenderViewHostDelegate::FindInPage* WebContents::GetFindInPageDelegate() const { // The find in page controller implements this interface for us. Our return @@ -1122,7 +895,7 @@ void WebContents::DidNavigate(RenderViewHost* rvh, return; // We can't do anything about navigations when we're inactive. - if (!controller() || !is_active_) + if (!controller() || !is_active()) return; // Update the site of the SiteInstance if it doesn't have one yet, unless we @@ -1154,144 +927,6 @@ void WebContents::DidNavigate(RenderViewHost* rvh, DidNavigateAnyFramePostCommit(rvh, details, params); } -void WebContents::DidNavigateMainFramePostCommit( - const NavigationController::LoadCommittedDetails& details, - const ViewHostMsg_FrameNavigate_Params& params) { - // Hide the download shelf if all the following conditions are true: - // - there are no active downloads. - // - this is a navigation to a different TLD. - // - at least 5 seconds have elapsed since the download shelf was shown. - // TODO(jcampan): bug 1156075 when user gestures are reliable, they should - // be used to ensure we are hiding only on user initiated - // navigations. - DownloadManager* download_manager = profile()->GetDownloadManager(); - // download_manager can be NULL in unit test context. - if (download_manager && download_manager->in_progress_count() == 0 && - !details.previous_url.is_empty() && - !net::RegistryControlledDomainService::SameDomainOrHost( - details.previous_url, details.entry->url())) { - TimeDelta time_delta( - TimeTicks::Now() - last_download_shelf_show_); - if (time_delta > - TimeDelta::FromMilliseconds(kDownloadShelfHideDelay)) { - SetDownloadShelfVisible(false); - } - } - - if (details.is_user_initiated_main_frame_load()) { - // Clear the status bubble. This is a workaround for a bug where WebKit - // doesn't let us know that the cursor left an element during a - // transition (this is also why the mouse cursor remains as a hand after - // clicking on a link); see bugs 1184641 and 980803. We don't want to - // clear the bubble when a user navigates to a named anchor in the same - // page. - UpdateTargetURL(details.entry->page_id(), GURL()); - - // UpdateHelpersForDidNavigate will handle the case where the password_form - // origin is valid. - // TODO(brettw) bug 1343111: Password manager stuff in here needs to be - // cleaned up and covered by tests. - if (!params.password_form.origin.is_valid()) - GetPasswordManager()->DidNavigate(); - } - - // The keyword generator uses the navigation entries, so must be called after - // the commit. - GenerateKeywordIfNecessary(params); - - // We no longer know the title after this navigation. - has_page_title_ = false; - - // Update contents MIME type of the main webframe. - contents_mime_type_ = params.contents_mime_type; - - // Get the favicon, either from history or request it from the net. - fav_icon_helper_.FetchFavIcon(details.entry->url()); - - // Close constrained popups if necessary. - MaybeCloseChildWindows(params); - - // We hide the FindInPage window when the user navigates away, except on - // reload. - if (PageTransition::StripQualifier(params.transition) != - PageTransition::RELOAD) - SetFindInPageVisible(false); - - // Update the starred state. - UpdateStarredStateForCurrentURL(); -} - -void WebContents::DidNavigateAnyFramePostCommit( - RenderViewHost* render_view_host, - const NavigationController::LoadCommittedDetails& details, - const ViewHostMsg_FrameNavigate_Params& params) { - // If we navigate, start showing messages again. This does nothing to prevent - // a malicious script from spamming messages, since the script could just - // reload the page to stop blocking. - suppress_javascript_messages_ = false; - - // Update history. Note that this needs to happen after the entry is complete, - // which WillNavigate[Main,Sub]Frame will do before this function is called. - if (params.should_update_history) { - // Most of the time, the displayURL matches the loaded URL, but for about: - // URLs, we use a data: URL as the real value. We actually want to save - // the about: URL to the history db and keep the data: URL hidden. This is - // what the TabContents' URL getter does. - UpdateHistoryForNavigation(GetURL(), params); - } - - // Notify the password manager of the navigation or form submit. - // TODO(brettw) bug 1343111: Password manager stuff in here needs to be - // cleaned up and covered by tests. - if (params.password_form.origin.is_valid()) - GetPasswordManager()->ProvisionallySavePassword(params.password_form); -} - -bool WebContents::IsWebApplicationActive() const { - if (!web_app_.get()) - return false; - - // If we are inside an application, the application is always active. For - // example, this allows us to display the GMail icon even when we are bounced - // the login page. - if (delegate() && delegate()->IsApplication()) - return true; - - return (GetURL() == web_app_->url()); -} - -void WebContents::WebAppImagesChanged(WebApp* web_app) { - DCHECK(web_app == web_app_.get()); - if (delegate() && IsWebApplicationActive()) - delegate()->NavigationStateChanged(this, TabContents::INVALIDATE_FAVICON); -} - -void WebContents::UpdateStarredStateForCurrentURL() { - BookmarkModel* model = profile()->GetBookmarkModel(); - const bool old_state = is_starred_; - is_starred_ = (model && model->IsBookmarked(GetURL())); - - if (is_starred_ != old_state && delegate()) - delegate()->URLStarredChanged(this, is_starred_); -} - -void WebContents::UpdateAlternateErrorPageURL() { - GURL url = GetAlternateErrorPageURL(); - render_view_host()->SetAlternateErrorPageURL(url); -} - -void WebContents::UpdateWebPreferences() { - render_view_host()->UpdateWebPreferences(GetWebkitPrefs()); -} - -void WebContents::UpdateRenderViewSize() { - // Using same technique as OnPaint, which sets size of SadTab. - CRect cr; - GetClientRect(&cr); - gfx::Size new_size(cr.Width(), cr.Height()); - SizeContents(new_size); -} - void WebContents::UpdateState(RenderViewHost* rvh, int32 page_id, const GURL& url, @@ -1375,7 +1010,7 @@ void WebContents::UpdateTitle(RenderViewHost* rvh, // If we have a title, that's a pretty good indication that we've started // getting useful data. - response_started_ = false; + SetNotWaitingForResponse(); NavigationEntry* entry; if (render_manager_.showing_interstitial_page() && @@ -1418,7 +1053,7 @@ void WebContents::UpdateTitle(RenderViewHost* rvh, void WebContents::UpdateEncoding(RenderViewHost* render_view_host, const std::wstring& encoding_name) { - SetEncoding(encoding_name); + set_encoding(encoding_name); } void WebContents::UpdateTargetURL(int32 page_id, const GURL& url) { @@ -1769,6 +1404,121 @@ void WebContents::TakeFocus(bool reverse) { } } +// Checks to see if we should generate a keyword based on the OSDD, and if +// necessary uses TemplateURLFetcher to download the OSDD and create a keyword. +void WebContents::PageHasOSDD(RenderViewHost* render_view_host, + int32 page_id, const GURL& url, + bool autodetected) { + // Make sure page_id is the current page, and the TemplateURLModel is loaded. + DCHECK(url.is_valid()); + if (!controller() || !IsActiveEntry(page_id)) + return; + TemplateURLModel* url_model = profile()->GetTemplateURLModel(); + if (!url_model) + return; + if (!url_model->loaded()) { + url_model->Load(); + return; + } + if (!profile()->GetTemplateURLFetcher()) + return; + + if (profile()->IsOffTheRecord()) + return; + + const NavigationEntry* entry = controller()->GetLastCommittedEntry(); + DCHECK(entry); + + const NavigationEntry* base_entry = entry; + if (IsFormSubmit(base_entry)) { + // If the current page is a form submit, find the last page that was not + // a form submit and use its url to generate the keyword from. + int index = controller()->GetLastCommittedEntryIndex() - 1; + while (index >= 0 && IsFormSubmit(controller()->GetEntryAtIndex(index))) + index--; + if (index >= 0) + base_entry = controller()->GetEntryAtIndex(index); + else + base_entry = NULL; + } + + // We want to use the user typed URL if available since that represents what + // the user typed to get here, and fall back on the regular URL if not. + if (!base_entry) + return; + GURL keyword_url = base_entry->user_typed_url().is_valid() ? + base_entry->user_typed_url() : base_entry->url(); + if (!keyword_url.is_valid()) + return; + std::wstring keyword = TemplateURLModel::GenerateKeyword(keyword_url, + autodetected); + if (keyword.empty()) + return; + const TemplateURL* template_url = + url_model->GetTemplateURLForKeyword(keyword); + if (template_url && (!template_url->safe_for_autoreplace() || + template_url->originating_url() == url)) { + // Either there is a user created TemplateURL for this keyword, or the + // keyword has the same OSDD url and we've parsed it. + return; + } + + // Download the OpenSearch description document. If this is successful a + // new keyword will be created when done. + profile()->GetTemplateURLFetcher()->ScheduleDownload( + keyword, + url, + base_entry->favicon().url(), + GetAncestor(GetHWND(), GA_ROOT), + autodetected); +} + +void WebContents::InspectElementReply(int num_resources) { + // We have received reply from inspect element request. Notify the + // automation provider in case we need to notify automation client. + NotificationService::current()-> + Notify(NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE, Source<WebContents>(this), + Details<int>(&num_resources)); +} + +void WebContents::DidGetPrintedPagesCount(int cookie, int number_pages) { + printing_.DidGetPrintedPagesCount(cookie, number_pages); +} + +void WebContents::DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) { + printing_.DidPrintPage(params); +} + +// The renderer sends back to the browser the key events it did not process. +void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) { + // The renderer returned a keyboard event it did not process. This may be + // a keyboard shortcut that we have to process. + if (event.type == WebInputEvent::KEY_DOWN) { + ChromeViews::FocusManager* focus_manager = + ChromeViews::FocusManager::GetFocusManager(GetHWND()); + // We may not have a focus_manager at this point (if the tab has been + // switched by the time this message returned). + if (focus_manager) { + ChromeViews::Accelerator accelerator(event.key_code, + (event.modifiers & WebInputEvent::SHIFT_KEY) == + WebInputEvent::SHIFT_KEY, + (event.modifiers & WebInputEvent::CTRL_KEY) == + WebInputEvent::CTRL_KEY, + (event.modifiers & WebInputEvent::ALT_KEY) == + WebInputEvent::ALT_KEY); + if (focus_manager->ProcessAccelerator(accelerator, false)) + return; + } + } + + // Any unhandled keyboard/character messages should be defproced. + // This allows stuff like Alt+F4, etc to work correctly. + DefWindowProc(event.actual_message.hwnd, + event.actual_message.message, + event.actual_message.wParam, + event.actual_message.lParam); +} + GURL WebContents::GetAlternateErrorPageURL() const { GURL url; PrefService* prefs = profile()->GetPrefs(); @@ -1899,78 +1649,27 @@ void WebContents::OnJSOutOfMemory() { } } -// Returns true if the entry's transition type is FORM_SUBMIT. -static bool IsFormSubmit(const NavigationEntry* entry) { - DCHECK(entry); - return (PageTransition::StripQualifier(entry->transition_type()) == - PageTransition::FORM_SUBMIT); +bool WebContents::CanBlur() const { + return delegate() ? delegate()->CanBlur() : true; } -void WebContents::PageHasOSDD(RenderViewHost* render_view_host, - int32 page_id, const GURL& url, - bool autodetected) { - // Make sure page_id is the current page, and the TemplateURLModel is loaded. - DCHECK(url.is_valid()); - if (!controller() || !IsActiveEntry(page_id)) - return; - TemplateURLModel* url_model = profile()->GetTemplateURLModel(); - if (!url_model) - return; - if (!url_model->loaded()) { - url_model->Load(); - return; - } - if (!profile()->GetTemplateURLFetcher()) - return; - - if (profile()->IsOffTheRecord()) - return; - - const NavigationEntry* entry = controller()->GetLastCommittedEntry(); - DCHECK(entry); - - const NavigationEntry* base_entry = entry; - if (IsFormSubmit(base_entry)) { - // If the current page is a form submit, find the last page that was not - // a form submit and use its url to generate the keyword from. - int index = controller()->GetLastCommittedEntryIndex() - 1; - while (index >= 0 && IsFormSubmit(controller()->GetEntryAtIndex(index))) - index--; - if (index >= 0) - base_entry = controller()->GetEntryAtIndex(index); - else - base_entry = NULL; - } +void WebContents::RendererUnresponsive(RenderViewHost* rvh) { + if (render_view_host() && render_view_host()->IsRenderViewLive()) + HungRendererWarning::ShowForWebContents(this); +} - // We want to use the user typed URL if available since that represents what - // the user typed to get here, and fall back on the regular URL if not. - if (!base_entry) - return; - GURL keyword_url = base_entry->user_typed_url().is_valid() ? - base_entry->user_typed_url() : base_entry->url(); - if (!keyword_url.is_valid()) - return; - std::wstring keyword = TemplateURLModel::GenerateKeyword(keyword_url, - autodetected); - if (keyword.empty()) - return; - const TemplateURL* template_url = - url_model->GetTemplateURLForKeyword(keyword); - if (template_url && (!template_url->safe_for_autoreplace() || - template_url->originating_url() == url)) { - // Either there is a user created TemplateURL for this keyword, or the - // keyword has the same OSDD url and we've parsed it. - return; - } +void WebContents::RendererResponsive(RenderViewHost* render_view_host) { + HungRendererWarning::HideForWebContents(this); +} - // Download the OpenSearch description document. If this is successful a - // new keyword will be created when done. - profile()->GetTemplateURLFetcher()->ScheduleDownload( - keyword, - url, - base_entry->favicon().url(), - GetAncestor(GetHWND(), GA_ROOT), - autodetected); +void WebContents::LoadStateChanged(const GURL& url, + net::LoadState load_state) { + load_state_ = load_state; + load_state_host_ = UTF8ToWide(url.host()); + if (load_state_ == net::LOAD_STATE_READING_RESPONSE) + SetNotWaitingForResponse(); + if (is_loading()) + NotifyNavigationStateChanged(INVALIDATE_LOAD); } void WebContents::OnDidGetApplicationInfo( @@ -1987,6 +1686,433 @@ void WebContents::OnDidGetApplicationInfo( &GearsCreateShortcutCallbackFunctor::Run)); } +void WebContents::FileSelected(const std::wstring& path, void* params) { + render_view_host()->FileSelected(path); +} + +void WebContents::FileSelectionCanceled(void* params) { + // If the user cancels choosing a file to upload we need to pass back the + // empty string. + render_view_host()->FileSelected(std::wstring()); +} + +void WebContents::BeforeUnloadFiredFromRenderManager( + bool proceed, + bool* proceed_to_fire_unload) { + delegate()->BeforeUnloadFired(this, proceed, proceed_to_fire_unload); +} + +void WebContents::UpdateRenderViewSizeForRenderManager() { + // Using same technique as OnPaint, which sets size of SadTab. + CRect cr; + GetClientRect(&cr); + gfx::Size new_size(cr.Width(), cr.Height()); + SizeContents(new_size); +} + +bool WebContents::CreateRenderViewForRenderManager( + RenderViewHost* render_view_host) { + RenderWidgetHostHWND* view = CreatePageView(render_view_host); + + bool ok = render_view_host->CreateRenderView(); + if (ok) { + CRect client_rect; + ::GetClientRect(GetHWND(), &client_rect); + view->SetSize(gfx::Size(client_rect.Width(), client_rect.Height())); + UpdateMaxPageIDIfNecessary(render_view_host->site_instance(), + render_view_host); + } + return ok; +} + +void WebContents::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + switch (type) { + case NOTIFY_BOOKMARK_MODEL_LOADED: // BookmarkModel finished loading, fall + // through to update starred state. + case NOTIFY_URLS_STARRED: { // Somewhere, a URL has been starred. + // Ignore notifications for profiles other than our current one. + Profile* source_profile = Source<Profile>(source).ptr(); + if (!source_profile->IsSameProfile(profile())) + return; + + UpdateStarredStateForCurrentURL(); + break; + } + case NOTIFY_PREF_CHANGED: { + std::wstring* pref_name_in = Details<std::wstring>(details).ptr(); + DCHECK(Source<PrefService>(source).ptr() == profile()->GetPrefs()); + if (*pref_name_in == prefs::kAlternateErrorPagesEnabled) { + UpdateAlternateErrorPageURL(); + } else if (*pref_name_in == prefs::kDefaultCharset || + StartsWithASCII(WideToUTF8(*pref_name_in), "webkit.webprefs.", true) + ) { + UpdateWebPreferences(); + } else { + NOTREACHED() << "unexpected pref change notification" << *pref_name_in; + } + break; + } + default: { + NOTREACHED(); + break; + } + } +} + +void WebContents::OnDestroy() { + if (drop_target_.get()) { + RevokeDragDrop(GetHWND()); + drop_target_ = NULL; + } +} + +void WebContents::OnHScroll(int scroll_type, short position, HWND scrollbar) { + ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar); +} + +void WebContents::OnMouseLeave() { + // Let our delegate know that the mouse moved (useful for resetting status + // bubble state). + if (delegate()) + delegate()->ContentsMouseEvent(this, WM_MOUSELEAVE); + SetMsgHandled(FALSE); +} + +LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) { + switch (msg) { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + // Make sure this TabContents is activated when it is clicked on. + if (delegate()) + delegate()->ActivateContents(this); + break; + case WM_MOUSEMOVE: + // Let our delegate know that the mouse moved (useful for resetting status + // bubble state). + if (delegate()) + delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE); + break; + default: + break; + } + + return 0; +} + +void WebContents::OnPaint(HDC junk_dc) { + if (render_view_host() && !render_view_host()->IsRenderViewLive()) { + if (!sad_tab_.get()) + sad_tab_.reset(new SadTabView); + CRect cr; + GetClientRect(&cr); + sad_tab_->SetBounds(cr); + ChromeCanvasPaint canvas(GetHWND(), true); + sad_tab_->ProcessPaint(&canvas); + return; + } + + // We need to do this to validate the dirty area so we don't end up in a + // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not + // firing etc). It doesn't matter that we don't have any non-clipped area. + CPaintDC dc(GetHWND()); + SetMsgHandled(FALSE); +} + +// A message is reflected here from view(). +// Return non-zero to indicate that it is handled here. +// Return 0 to allow view() to further process it. +LRESULT WebContents::OnReflectedMessage(UINT msg, WPARAM w_param, + LPARAM l_param) { + MSG* message = reinterpret_cast<MSG*>(l_param); + switch (message->message) { + case WM_MOUSEWHEEL: + // This message is reflected from the view() to this window. + if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) { + WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam)); + return 1; + } + break; + case WM_HSCROLL: + case WM_VSCROLL: + if (ScrollZoom(LOWORD(message->wParam))) + return 1; + default: + break; + } + + return 0; +} + +void WebContents::OnSetFocus(HWND window) { + // TODO(jcampan): figure out why removing this prevents tabs opened in the + // background from properly taking focus. + // We NULL-check the render_view_host_ here because Windows can send us + // messages during the destruction process after it has been destroyed. + if (view()) { + HWND inner_hwnd = view()->GetPluginHWND(); + if (::IsWindow(inner_hwnd)) + ::SetFocus(inner_hwnd); + } +} + +void WebContents::OnVScroll(int scroll_type, short position, HWND scrollbar) { + ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar); +} + +void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) { + if (window_pos->flags & SWP_HIDEWINDOW) { + HideContents(); + } else { + // The WebContents was shown by a means other than the user selecting a + // Tab, e.g. the window was minimized then restored. + if (window_pos->flags & SWP_SHOWWINDOW) + ShowContents(); + // Unless we were specifically told not to size, cause the renderer to be + // sized to the new bounds, which forces a repaint. Not required for the + // simple minimize-restore case described above, for example, since the + // size hasn't changed. + if (!(window_pos->flags & SWP_NOSIZE)) { + gfx::Size size(window_pos->cx, window_pos->cy); + SizeContents(size); + } + + // If we have a FindInPage dialog, notify it that the window changed. + if (find_in_page_controller_.get() && find_in_page_controller_->IsVisible()) + find_in_page_controller_->MoveWindowIfNecessary(gfx::Rect()); + } +} + +void WebContents::OnSize(UINT param, const CSize& size) { + HWNDViewContainer::OnSize(param, size); + + // Hack for thinkpad touchpad driver. + // Set fake scrollbars so that we can get scroll messages, + SCROLLINFO si = {0}; + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + + si.nMin = 1; + si.nMax = 100; + si.nPage = 10; + si.nTrackPos = 50; + + ::SetScrollInfo(GetHWND(), SB_HORZ, &si, FALSE); + ::SetScrollInfo(GetHWND(), SB_VERT, &si, FALSE); +} + +LRESULT WebContents::OnNCCalcSize(BOOL w_param, LPARAM l_param) { + // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars + // to receive scroll messages from thinkpad touchpad driver. Suppress + // painting of scrollbars by returning 0 size for them. + return 0; +} + +void WebContents::OnNCPaint(HRGN rgn) { + // Suppress default WM_NCPAINT handling. We don't need to do anything + // here since the view will draw everything correctly. +} + +void WebContents::ScrollCommon(UINT message, int scroll_type, short position, + HWND scrollbar) { + // This window can receive scroll events as a result of the ThinkPad's + // Trackpad scroll wheel emulation. + if (!ScrollZoom(scroll_type)) { + // Reflect scroll message to the view() to give it a chance + // to process scrolling. + SendMessage(GetContentHWND(), message, MAKELONG(scroll_type, position), + (LPARAM) scrollbar); + } +} + +bool WebContents::ScrollZoom(int scroll_type) { + // If ctrl is held, zoom the UI. There are three issues with this: + // 1) Should the event be eaten or forwarded to content? We eat the event, + // which is like Firefox and unlike IE. + // 2) Should wheel up zoom in or out? We zoom in (increase font size), which + // is like IE and Google maps, but unlike Firefox. + // 3) Should the mouse have to be over the content area? We zoom as long as + // content has focus, although FF and IE require that the mouse is over + // content. This is because all events get forwarded when content has + // focus. + if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { + int distance = 0; + switch (scroll_type) { + case SB_LINEUP: + distance = WHEEL_DELTA; + break; + case SB_LINEDOWN: + distance = -WHEEL_DELTA; + break; + // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, + // and SB_THUMBTRACK for completeness + default: + break; + } + + WheelZoom(distance); + return true; + } + return false; +} + +void WebContents::WheelZoom(int distance) { + if (delegate()) { + bool zoom_in = distance > 0; + delegate()->ContentsZoomChange(zoom_in); + } +} + +void WebContents::DidNavigateMainFramePostCommit( + const NavigationController::LoadCommittedDetails& details, + const ViewHostMsg_FrameNavigate_Params& params) { + // Hide the download shelf if all the following conditions are true: + // - there are no active downloads. + // - this is a navigation to a different TLD. + // - at least 5 seconds have elapsed since the download shelf was shown. + // TODO(jcampan): bug 1156075 when user gestures are reliable, they should + // be used to ensure we are hiding only on user initiated + // navigations. + DownloadManager* download_manager = profile()->GetDownloadManager(); + // download_manager can be NULL in unit test context. + if (download_manager && download_manager->in_progress_count() == 0 && + !details.previous_url.is_empty() && + !net::RegistryControlledDomainService::SameDomainOrHost( + details.previous_url, details.entry->url())) { + TimeDelta time_delta( + TimeTicks::Now() - last_download_shelf_show_); + if (time_delta > + TimeDelta::FromMilliseconds(kDownloadShelfHideDelay)) { + SetDownloadShelfVisible(false); + } + } + + if (details.is_user_initiated_main_frame_load()) { + // Clear the status bubble. This is a workaround for a bug where WebKit + // doesn't let us know that the cursor left an element during a + // transition (this is also why the mouse cursor remains as a hand after + // clicking on a link); see bugs 1184641 and 980803. We don't want to + // clear the bubble when a user navigates to a named anchor in the same + // page. + UpdateTargetURL(details.entry->page_id(), GURL()); + + // UpdateHelpersForDidNavigate will handle the case where the password_form + // origin is valid. + // TODO(brettw) bug 1343111: Password manager stuff in here needs to be + // cleaned up and covered by tests. + if (!params.password_form.origin.is_valid()) + GetPasswordManager()->DidNavigate(); + } + + // The keyword generator uses the navigation entries, so must be called after + // the commit. + GenerateKeywordIfNecessary(params); + + // We no longer know the title after this navigation. + has_page_title_ = false; + + // Update contents MIME type of the main webframe. + contents_mime_type_ = params.contents_mime_type; + + // Get the favicon, either from history or request it from the net. + fav_icon_helper_.FetchFavIcon(details.entry->url()); + + // Close constrained popups if necessary. + MaybeCloseChildWindows(params); + + // We hide the FindInPage window when the user navigates away, except on + // reload. + if (PageTransition::StripQualifier(params.transition) != + PageTransition::RELOAD) + SetFindInPageVisible(false); + + // Update the starred state. + UpdateStarredStateForCurrentURL(); +} + +void WebContents::DidNavigateAnyFramePostCommit( + RenderViewHost* render_view_host, + const NavigationController::LoadCommittedDetails& details, + const ViewHostMsg_FrameNavigate_Params& params) { + // If we navigate, start showing messages again. This does nothing to prevent + // a malicious script from spamming messages, since the script could just + // reload the page to stop blocking. + suppress_javascript_messages_ = false; + + // Update history. Note that this needs to happen after the entry is complete, + // which WillNavigate[Main,Sub]Frame will do before this function is called. + if (params.should_update_history) { + // Most of the time, the displayURL matches the loaded URL, but for about: + // URLs, we use a data: URL as the real value. We actually want to save + // the about: URL to the history db and keep the data: URL hidden. This is + // what the TabContents' URL getter does. + UpdateHistoryForNavigation(GetURL(), params); + } + + // Notify the password manager of the navigation or form submit. + // TODO(brettw) bug 1343111: Password manager stuff in here needs to be + // cleaned up and covered by tests. + if (params.password_form.origin.is_valid()) + GetPasswordManager()->ProvisionallySavePassword(params.password_form); +} + +void WebContents::MaybeCloseChildWindows( + const ViewHostMsg_FrameNavigate_Params& params) { + if (net::RegistryControlledDomainService::SameDomainOrHost( + last_url_, params.url)) + return; + last_url_ = params.url; + + // Clear out any child windows since we are leaving this page entirely. + // We use indices instead of iterators in case CloseWindow does something + // that may invalidate an iterator. + int size = static_cast<int>(child_windows_.size()); + for (int i = size - 1; i >= 0; --i) { + ConstrainedWindow* window = child_windows_[i]; + if (window) + window->CloseConstrainedWindow(); + } +} + +void WebContents::UpdateStarredStateForCurrentURL() { + BookmarkModel* model = profile()->GetBookmarkModel(); + const bool old_state = is_starred_; + is_starred_ = (model && model->IsBookmarked(GetURL())); + + if (is_starred_ != old_state && delegate()) + delegate()->URLStarredChanged(this, is_starred_); +} + +void WebContents::UpdateAlternateErrorPageURL() { + GURL url = GetAlternateErrorPageURL(); + render_view_host()->SetAlternateErrorPageURL(url); +} + +void WebContents::UpdateWebPreferences() { + render_view_host()->UpdateWebPreferences(GetWebkitPrefs()); +} + +bool WebContents::IsWebApplicationActive() const { + if (!web_app_.get()) + return false; + + // If we are inside an application, the application is always active. For + // example, this allows us to display the GMail icon even when we are bounced + // the login page. + if (delegate() && delegate()->IsApplication()) + return true; + + return (GetURL() == web_app_->url()); +} + +void WebContents::WebAppImagesChanged(WebApp* web_app) { + DCHECK(web_app == web_app_.get()); + if (delegate() && IsWebApplicationActive()) + delegate()->NavigationStateChanged(this, TabContents::INVALIDATE_FAVICON); +} + void WebContents::OnGearsCreateShortcutDone( const GearsShortcutData& shortcut_data, bool success) { NavigationEntry* current_entry = controller()->GetLastCommittedEntry(); @@ -2031,77 +2157,86 @@ void WebContents::UpdateMaxPageIDIfNecessary(SiteInstance* site_instance, } } -void WebContents::BeforeUnloadFiredFromRenderManager( - bool proceed, - bool* proceed_to_fire_unload) { - delegate()->BeforeUnloadFired(this, proceed, proceed_to_fire_unload); -} - - -HWND WebContents::GetContentHWND() { - if (!view()) - return NULL; - return view()->GetPluginHWND(); -} - -bool WebContents::CanDisplayFile(const std::wstring& full_path) { - bool allow_wildcard = false; - std::string mime_type; - net::GetMimeTypeFromFile(full_path, &mime_type); - if (net::IsSupportedMimeType(mime_type) || - (PluginService::GetInstance() && - PluginService::GetInstance()->HavePluginFor(mime_type, allow_wildcard))) - return true; - return false; -} - -void WebContents::PrintPreview() { - // We can't print interstitial page for now. - if (render_manager_.showing_interstitial_page()) +void WebContents::UpdateHistoryForNavigation(const GURL& display_url, + const ViewHostMsg_FrameNavigate_Params& params) { + if (profile()->IsOffTheRecord()) return; - // If we have a FindInPage dialog, notify it that its tab was hidden. - if (find_in_page_controller_.get()) - find_in_page_controller_->DidBecomeUnselected(); - - // We don't show the print preview for the beta, only the print dialog. - printing_.ShowPrintDialog(); + // Add to history service. + HistoryService* hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); + if (hs) { + if (PageTransition::IsMainFrame(params.transition) && + display_url != params.url) { + // Hack on the "display" URL so that it will appear in history. For some + // types of URLs, we will display a magic URL that is different from where + // the page is actually navigated. We want the user to see in history + // what they saw in the URL bar, so we add the display URL as a redirect. + // This only applies to the main frame, as the display URL doesn't apply + // to sub-frames. + std::vector<GURL> redirects = params.redirects; + if (!redirects.empty()) + redirects.back() = display_url; + hs->AddPage(display_url, this, params.page_id, params.referrer, + params.transition, redirects); + } else { + hs->AddPage(params.url, this, params.page_id, params.referrer, + params.transition, params.redirects); + } + } } -bool WebContents::PrintNow() { - // We can't print interstitial page for now. - if (render_manager_.showing_interstitial_page()) - return false; - - // If we have a FindInPage dialog, notify it that its tab was hidden. - if (find_in_page_controller_.get()) - find_in_page_controller_->DidBecomeUnselected(); - - return printing_.PrintNow(); +RenderWidgetHostHWND* WebContents::CreatePageView( + RenderViewHost* render_view_host) { + // Create the View as well. Its lifetime matches the child process'. + DCHECK(!render_view_host->view()); + RenderWidgetHostHWND* view = new RenderWidgetHostHWND(render_view_host); + render_view_host->set_view(view); + view->Create(GetHWND()); + view->ShowWindow(SW_SHOW); + return view; } -void WebContents::WillCaptureContents() { - capturing_contents_ = true; +void WebContents::DetachPluginWindows() { + EnumChildWindows(GetHWND(), WebContents::EnumPluginWindowsCallback, NULL); } -void WebContents::DidCaptureContents() { - capturing_contents_ = false; -} +BOOL WebContents::EnumPluginWindowsCallback(HWND window, LPARAM) { + if (WebPluginDelegateImpl::IsPluginDelegateWindow(window)) { + ::ShowWindow(window, SW_HIDE); + SetParent(window, NULL); + } -void WebContents::Cut() { - render_view_host()->Cut(); + return TRUE; } -void WebContents::Copy() { - render_view_host()->Copy(); +void WebContents::NotifySwapped() { + // After sending out a swap notification, we need to send a disconnect + // notification so that clients that pick up a pointer to |this| can NULL the + // pointer. See Bug 1230284. + notify_disconnection_ = true; + NotificationService::current()-> + Notify(NOTIFY_WEB_CONTENTS_SWAPPED, + Source<WebContents>(this), + NotificationService::NoDetails()); } -void WebContents::Paste() { - render_view_host()->Paste(); +void WebContents::NotifyConnected() { + notify_disconnection_ = true; + NotificationService::current()-> + Notify(NOTIFY_WEB_CONTENTS_CONNECTED, + Source<WebContents>(this), + NotificationService::NoDetails()); } -void WebContents::SetInitialFocus(bool reverse) { - render_view_host()->SetInitialFocus(reverse); +void WebContents::NotifyDisconnected() { + if (!notify_disconnection_) + return; + + notify_disconnection_ = false; + NotificationService::current()-> + Notify(NOTIFY_WEB_CONTENTS_DISCONNECTED, + Source<WebContents>(this), + NotificationService::NoDetails()); } void WebContents::GenerateKeywordIfNecessary( @@ -2178,167 +2313,3 @@ void WebContents::GenerateKeywordIfNecessary( new_url->set_safe_for_autoreplace(true); url_model->Add(new_url); } - -void WebContents::InspectElementReply(int num_resources) { - // We have received reply from inspect element request. Notify the - // automation provider in case we need to notify automation client. - NotificationService::current()-> - Notify(NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE, Source<WebContents>(this), - Details<int>(&num_resources)); -} - -// The renderer sends back to the browser the key events it did not process. -void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) { - // The renderer returned a keyboard event it did not process. This may be - // a keyboard shortcut that we have to process. - if (event.type == WebInputEvent::KEY_DOWN) { - ChromeViews::FocusManager* focus_manager = - ChromeViews::FocusManager::GetFocusManager(GetHWND()); - // We may not have a focus_manager at this point (if the tab has been - // switched by the time this message returned). - if (focus_manager) { - ChromeViews::Accelerator accelerator(event.key_code, - (event.modifiers & WebInputEvent::SHIFT_KEY) == - WebInputEvent::SHIFT_KEY, - (event.modifiers & WebInputEvent::CTRL_KEY) == - WebInputEvent::CTRL_KEY, - (event.modifiers & WebInputEvent::ALT_KEY) == - WebInputEvent::ALT_KEY); - if (focus_manager->ProcessAccelerator(accelerator, false)) - return; - } - } - - // Any unhandled keyboard/character messages should be defproced. - // This allows stuff like Alt+F4, etc to work correctly. - DefWindowProc(event.actual_message.hwnd, - event.actual_message.message, - event.actual_message.wParam, - event.actual_message.lParam); -} - -bool WebContents::CreateRenderViewForRenderManager( - RenderViewHost* render_view_host) { - RenderWidgetHostHWND* view = CreatePageView(render_view_host); - - bool ok = render_view_host->CreateRenderView(); - if (ok) { - CRect client_rect; - ::GetClientRect(GetHWND(), &client_rect); - view->SetSize(gfx::Size(client_rect.Width(), client_rect.Height())); - UpdateMaxPageIDIfNecessary(render_view_host->site_instance(), - render_view_host); - } - return ok; -} - -RenderWidgetHostHWND* WebContents::CreatePageView( - RenderViewHost* render_view_host) { - // Create the View as well. Its lifetime matches the child process'. - DCHECK(!render_view_host->view()); - RenderWidgetHostHWND* view = new RenderWidgetHostHWND(render_view_host); - render_view_host->set_view(view); - view->Create(GetHWND()); - view->ShowWindow(SW_SHOW); - return view; -} - -void WebContents::DidGetPrintedPagesCount(int cookie, int number_pages) { - printing_.DidGetPrintedPagesCount(cookie, number_pages); -} - -void WebContents::DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) { - printing_.DidPrintPage(params); -} - -void WebContents::SetIsLoading(bool is_loading, - LoadNotificationDetails* details) { - if (!is_loading) { - load_state_ = net::LOAD_STATE_IDLE; - load_state_host_.clear(); - } - - TabContents::SetIsLoading(is_loading, details); - render_manager_.SetIsLoading(is_loading); -} - -void WebContents::FileSelected(const std::wstring& path, void* params) { - render_view_host()->FileSelected(path); -} - -void WebContents::FileSelectionCanceled(void* params) { - // If the user cancels choosing a file to upload we need to pass back the - // empty string. - render_view_host()->FileSelected(std::wstring()); -} - -/////////////////////////////////////////////////////////////////////////////// - -SkBitmap WebContents::GetFavIcon() { - if (web_app_.get() && IsWebApplicationActive()) { - SkBitmap app_icon = web_app_->GetFavIcon(); - if (!app_icon.isNull()) - return app_icon; - } - return TabContents::GetFavIcon(); -} - -std::wstring WebContents::GetStatusText() const { - if (!is_loading() || load_state_ == net::LOAD_STATE_IDLE) - return std::wstring(); - - switch (load_state_) { - case net::LOAD_STATE_WAITING_FOR_CACHE: - return l10n_util::GetString(IDS_LOAD_STATE_WAITING_FOR_CACHE); - case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL: - return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL); - case net::LOAD_STATE_RESOLVING_HOST: - return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_HOST); - case net::LOAD_STATE_CONNECTING: - return l10n_util::GetString(IDS_LOAD_STATE_CONNECTING); - case net::LOAD_STATE_SENDING_REQUEST: - return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST); - case net::LOAD_STATE_WAITING_FOR_RESPONSE: - return l10n_util::GetStringF(IDS_LOAD_STATE_WAITING_FOR_RESPONSE, - load_state_host_); - // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE - } - - return std::wstring(); -} - -bool WebContents::CanBlur() const { - return delegate() ? delegate()->CanBlur() : true; -} - -void WebContents::RendererUnresponsive(RenderViewHost* rvh) { - if (render_view_host() && render_view_host()->IsRenderViewLive()) - HungRendererWarning::ShowForWebContents(this); -} - -void WebContents::RendererResponsive(RenderViewHost* render_view_host) { - HungRendererWarning::HideForWebContents(this); -} - -void WebContents::LoadStateChanged(const GURL& url, - net::LoadState load_state) { - load_state_ = load_state; - load_state_host_ = UTF8ToWide(url.host()); - if (load_state_ == net::LOAD_STATE_READING_RESPONSE) - response_started_ = false; - if (is_loading()) - NotifyNavigationStateChanged(INVALIDATE_LOAD); -} - -void WebContents::DetachPluginWindows() { - EnumChildWindows(GetHWND(), WebContents::EnumPluginWindowsCallback, NULL); -} - -BOOL WebContents::EnumPluginWindowsCallback(HWND window, LPARAM) { - if (WebPluginDelegateImpl::IsPluginDelegateWindow(window)) { - ::ShowWindow(window, SW_HIDE); - SetParent(window, NULL); - } - - return TRUE; -} diff --git a/chrome/browser/web_contents.h b/chrome/browser/web_contents.h index 1e23645..780b34a 100644 --- a/chrome/browser/web_contents.h +++ b/chrome/browser/web_contents.h @@ -28,11 +28,14 @@ class SadTabView; struct WebDropData; class WebDropTarget; +// WebContents represents the contents of a tab that shows web pages. It embeds +// a RenderViewHost (via RenderViewHostManager) to actually display the page. class WebContents : public TabContents, public RenderViewHostDelegate, public RenderViewHostManager::Delegate, public ChromeViews::HWNDViewContainer, public SelectFileDialog::Listener, + public NotificationObserver, public WebApp::Observer { public: // If instance is NULL, then creates a new process for this view. Otherwise @@ -48,82 +51,78 @@ class WebContents : public TabContents, static void RegisterUserPrefs(PrefService* prefs); - virtual void CreateView(HWND parent_hwnd, const gfx::Rect& initial_bounds); - virtual HWND GetContainerHWND() const { return GetHWND(); } - virtual void GetContainerBounds(gfx::Rect *out) const; - virtual void ShowContents(); - virtual void HideContents(); - virtual void SizeContents(const gfx::Size& size); + // Getters ------------------------------------------------------------------- - // TabContents - virtual WebContents* AsWebContents() { return this; } - virtual SiteInstance* GetSiteInstance() const { - return render_manager_.current_host()->site_instance(); + // Returns the PasswordManager, creating it if necessary. + PasswordManager* GetPasswordManager(); + + // Returns the PluginInstaller, creating it if necessary. + PluginInstaller* GetPluginInstaller(); + + // Returns the SavePackage which manages the page saving job. May be NULL. + SavePackage* save_package() const { return save_package_.get(); } + + // Return the currently active RenderProcessHost, RenderViewHost, and + // SiteInstance, respectively. Each of these may change over time. Callers + // should be aware that the SiteInstance could be deleted if its ref count + // drops to zero (i.e., if all RenderViewHosts and NavigationEntries that + // use it are deleted). + RenderProcessHost* process() const { + return render_manager_.current_host()->process(); } - virtual bool NavigateToPendingEntry(bool reload); - virtual void Stop(); - virtual void DidBecomeSelected(); - virtual void WasHidden(); + RenderViewHost* render_view_host() const { + return render_manager_.current_host(); + } + RenderWidgetHostView* view() const { + return render_manager_.current_view(); + } + + bool is_starred() const { return is_starred_; } + + // TabContents (public overrides) -------------------------------------------- + virtual void Destroy(); + virtual WebContents* AsWebContents() { return this; } + virtual SiteInstance* GetSiteInstance() const; virtual SkBitmap GetFavIcon(); virtual std::wstring GetStatusText() const; - - // Find functions + virtual bool NavigateToPendingEntry(bool reload); + virtual void Stop(); virtual void StartFinding(int request_id, const std::wstring& search_string, bool forward, bool match_case, bool find_next); virtual void StopFinding(bool clear_selection); - virtual void OpenFindInPageWindow(const Browser& browser); - virtual void ReparentFindWindow(HWND new_parent); - virtual bool AdvanceFindSelection(bool forward_direction); - virtual bool IsFindWindowFullyVisible(); - virtual bool GetFindInPageWindowLocation(int* x, int* y); - - bool is_starred() const { return is_starred_; } - - // Set whether the contents should block javascript message boxes or not. - // Default is not to block any message boxes. - void set_suppress_javascript_messages( - bool suppress_javascript_messages) { - suppress_javascript_messages_ = suppress_javascript_messages; - } - - // Various other systems need to know about our interstitials. - bool showing_interstitial_page() const { - return render_manager_.showing_interstitial_page(); - } - bool showing_repost_interstitial() const { - return render_manager_.showing_repost_interstitial(); - } - - // Overridden from TabContents to remember at what time the download bar was - // shown. - void SetDownloadShelfVisible(bool visible); - - // Returns the SavePackage which manages the page saving job. May be NULL. - SavePackage* save_package() const { return save_package_.get(); } - - // Whether or not the info bar is visible. This delegates to - // the ChromeFrame method InfoBarVisibilityChanged. - void SetInfoBarVisible(bool visible); - virtual bool IsInfoBarVisible() { return info_bar_visible_; } - - // Whether or not the FindInPage bar is visible. - void SetFindInPageVisible(bool visible); - + virtual void Cut(); + virtual void Copy(); + virtual void Paste(); + virtual void DidBecomeSelected(); + virtual void WasHidden(); + virtual void ShowContents(); + virtual void HideContents(); + virtual void SizeContents(const gfx::Size& size); + virtual HWND GetContentHWND(); + virtual void CreateView(HWND parent_hwnd, const gfx::Rect& initial_bounds); + virtual HWND GetContainerHWND() const { return GetHWND(); } + virtual void GetContainerBounds(gfx::Rect *out) const; // Create the InfoBarView and returns it if none has been created. // Just returns existing InfoBarView if it is already created. virtual InfoBarView* GetInfoBarView(); + virtual bool IsInfoBarVisible() { return info_bar_visible_; } + virtual void SetDownloadShelfVisible(bool visible); - // Prepare for saving page. - void OnSavePage(); + // Find in page -------------------------------------------------------------- - // Save page with the main HTML file path, the directory for saving resources, - // and the save type: HTML only or complete web page. - void SavePage(const std::wstring& main_file, const std::wstring& dir_path, - SavePackage::SavePackageType save_type); + // TODO(brettw) these should be commented. + void OpenFindInPageWindow(const Browser& browser); + void ReparentFindWindow(HWND new_parent); + bool AdvanceFindSelection(bool forward_direction); + bool IsFindWindowFullyVisible(); + bool GetFindInPageWindowLocation(int* x, int* y); + void SetFindInPageVisible(bool visible); + + // Web apps ------------------------------------------------------------------ // Sets the WebApp for this WebContents. void SetWebApp(WebApp* web_app); @@ -135,57 +134,16 @@ class WebContents : public TabContents, // Tell Gears to create a shortcut for the current page. void CreateShortcut(); - // JavascriptMessageBoxHandler calls this when the dialog is closed. - void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, bool success, - const std::wstring& prompt); + // Interstitials ------------------------------------------------------------- - // Returns the PasswordManager, creating it if necessary. - PasswordManager* GetPasswordManager(); - - // Returns the PluginInstaller, creating it if necessary. - PluginInstaller* GetPluginInstaller(); - - // Return the currently active RenderProcessHost, RenderViewHost, and - // SiteInstance, respectively. Each of these may change over time. Callers - // should be aware that the SiteInstance could be deleted if its ref count - // drops to zero (i.e., if all RenderViewHosts and NavigationEntries that - // use it are deleted). - RenderProcessHost* process() const { - return render_manager_.current_host()->process(); - } - RenderViewHost* render_view_host() const { - return render_manager_.current_host(); + // Various other systems need to know about our interstitials. + bool showing_interstitial_page() const { + return render_manager_.showing_interstitial_page(); } - RenderWidgetHostView* view() const { - return render_manager_.current_view(); + bool showing_repost_interstitial() const { + return render_manager_.showing_repost_interstitial(); } - // Overridden from TabContents to return the window of the - // RenderWidgetHostView. - virtual HWND GetContentHWND(); - - // Handling the drag and drop of files into the content area. - virtual bool CanDisplayFile(const std::wstring& full_path); - - // Displays asynchronously a print preview (generated by the renderer) if not - // already displayed and ask the user for its preferred print settings with - // the "Print..." dialog box. (managed by the print worker thread). - // TODO(maruel): Creates a snapshot of the renderer to be used for the new - // tab for the printing facility. - void PrintPreview(); - - // 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. - bool PrintNow(); - - virtual void WillCaptureContents(); - virtual void DidCaptureContents(); - - virtual void Cut(); - virtual void Copy(); - virtual void Paste(); - // The rest of the system wants to interact with the delegate our render view // host manager has. See those setters for more. InterstitialPageDelegate* interstitial_page_delegate() const { @@ -215,15 +173,45 @@ class WebContents : public TabContents, render_manager_.HideInterstitialPage(wait_for_navigation, proceed); } - // Allows the WebContents to react when a cross-site response is ready to be - // delivered to a pending RenderViewHost. We must first run the onunload - // handler of the old RenderViewHost before we can allow it to proceed. - void OnCrossSiteResponse(int new_render_process_host_id, - int new_request_id) { - render_manager_.OnCrossSiteResponse(new_render_process_host_id, - new_request_id); + // Misc state & callbacks ---------------------------------------------------- + + // Set whether the contents should block javascript message boxes or not. + // Default is not to block any message boxes. + void set_suppress_javascript_messages( + bool suppress_javascript_messages) { + suppress_javascript_messages_ = suppress_javascript_messages; } + // JavascriptMessageBoxHandler calls this when the dialog is closed. + void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt); + + // Whether or not the info bar is visible. This delegates to + // the ChromeFrame method InfoBarVisibilityChanged. See also IsInfoBarVisible + // (a TabContents override). + void SetInfoBarVisible(bool visible); + + // Prepare for saving page. + void OnSavePage(); + + // Save page with the main HTML file path, the directory for saving resources, + // and the save type: HTML only or complete web page. + void SavePage(const std::wstring& main_file, const std::wstring& dir_path, + SavePackage::SavePackageType save_type); + + // Displays asynchronously a print preview (generated by the renderer) if not + // already displayed and ask the user for its preferred print settings with + // the "Print..." dialog box. (managed by the print worker thread). + // TODO(maruel): Creates a snapshot of the renderer to be used for the new + // tab for the printing facility. + void PrintPreview(); + + // 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. + bool PrintNow(); + // Returns true if the active NavigationEntry's page_id equals page_id. bool IsActiveEntry(int32 page_id); @@ -235,17 +223,19 @@ class WebContents : public TabContents, bool notify_disconnection() const { return notify_disconnection_; } protected: - FRIEND_TEST(WebContentsTest, UpdateTitle); - // Should be deleted via CloseContents. virtual ~WebContents(); - // RenderViewHostDelegate + // TabContents (private overrides) ------------------------------------------- + + virtual void SetInitialFocus(bool reverse); + virtual void SetIsLoading(bool is_loading, LoadNotificationDetails* details); + + // RenderViewHostDelegate ---------------------------------------------------- + virtual RenderViewHostDelegate::FindInPage* GetFindInPageDelegate() const; virtual RenderViewHostDelegate::Save* GetSaveDelegate() const; - virtual Profile* GetProfile() const; - virtual void CreateView(int route_id, HANDLE modal_dialog_event); virtual void CreateWidget(int route_id); virtual void ShowView(int route_id, @@ -257,7 +247,6 @@ class WebContents : public TabContents, virtual void RendererGone(RenderViewHost* render_view_host); virtual void DidNavigate(RenderViewHost* render_view_host, const ViewHostMsg_FrameNavigate_Params& params); - virtual void UpdateRenderViewSize(); virtual void UpdateState(RenderViewHost* render_view_host, int32 page_id, const GURL& url, @@ -321,8 +310,12 @@ class WebContents : public TabContents, IPC::Message* reply_msg); virtual void PasswordFormsSeen(const std::vector<PasswordForm>& forms); virtual void TakeFocus(bool reverse); + virtual void PageHasOSDD(RenderViewHost* render_view_host, + int32 page_id, const GURL& url, bool autodetected); + virtual void InspectElementReply(int num_resources); virtual void DidGetPrintedPagesCount(int cookie, int number_pages); virtual void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params); + virtual void HandleKeyboardEvent(const WebKeyboardEvent& event); virtual GURL GetAlternateErrorPageURL() const; virtual WebPreferences GetWebkitPrefs(); virtual void OnMissingPluginStatus(int status); @@ -331,41 +324,47 @@ class WebContents : public TabContents, virtual void ShouldClosePage(bool proceed) { render_manager_.ShouldClosePage(proceed); } + // Allows the WebContents to react when a cross-site response is ready to be + // delivered to a pending RenderViewHost. We must first run the onunload + // handler of the old RenderViewHost before we can allow it to proceed. + void OnCrossSiteResponse(int new_render_process_host_id, + int new_request_id) { + render_manager_.OnCrossSiteResponse(new_render_process_host_id, + new_request_id); + } virtual bool CanBlur() const; virtual void RendererUnresponsive(RenderViewHost* render_view_host); virtual void RendererResponsive(RenderViewHost* render_view_host); virtual void LoadStateChanged(const GURL& url, net::LoadState load_state); - - // Notification that a page has an OpenSearch description document available - // at url. This checks to see if we should generate a keyword based on the - // OSDD, and if necessary uses TemplateURLFetcher to download the OSDD - // and create a keyword. - virtual void PageHasOSDD(RenderViewHost* render_view_host, - int32 page_id, const GURL& url, bool autodetected); - virtual void OnDidGetApplicationInfo( int32 page_id, const webkit_glue::WebApplicationInfo& info); - // Overridden from TabContents. - virtual void SetInitialFocus(bool reverse); - - // Handle reply from inspect element request - virtual void InspectElementReply(int num_resources); - - // Handle keyboard events not processed by the renderer. - virtual void HandleKeyboardEvent(const WebKeyboardEvent& event); - - // Notifies the RenderWidgetHost instance about the fact that the - // page is loading, or done loading and calls the base implementation. - void SetIsLoading(bool is_loading, LoadNotificationDetails* details); + // SelectFileDialog::Listener ------------------------------------------------ - // Overridden from SelectFileDialog::Listener: virtual void FileSelected(const std::wstring& path, void* params); virtual void FileSelectionCanceled(void* params); - // Another part of RenderViewHostManager::Delegate. - // + // RenderViewHostManager::Delegate ------------------------------------------- + + virtual void BeforeUnloadFiredFromRenderManager( + bool proceed, + bool* proceed_to_fire_unload); + virtual void DidStartLoadingFromRenderManager( + RenderViewHost* render_view_host, int32 page_id) { + DidStartLoading(render_view_host, page_id); + } + virtual void RendererGoneFromRenderManager(RenderViewHost* render_view_host) { + RendererGone(render_view_host); + } + virtual void UpdateRenderViewSizeForRenderManager(); + virtual void NotifySwappedFromRenderManager() { + NotifySwapped(); + } + virtual NavigationController* GetControllerForRenderManager() { + return controller(); + } + // Initializes the given renderer if necessary and creates the view ID // corresponding to this view host. If this method is not called and the // process is not shared, then the WebContents will act as though the renderer @@ -382,6 +381,7 @@ class WebContents : public TabContents, RenderViewHost* render_view_host); private: + FRIEND_TEST(WebContentsTest, UpdateTitle); friend class TestWebContents; // When CreateShortcut is invoked RenderViewHost::GetApplicationInfo is @@ -400,17 +400,14 @@ class WebContents : public TabContents, GearsCreateShortcutCallbackFunctor* callback_functor; }; - void ScrollCommon(UINT message, int scroll_type, short position, - HWND scrollbar); - bool ScrollZoom(int scroll_type); - void WheelZoom(int distance); + // NotificationObserver ------------------------------------------------------ - // Backend for LoadURL that optionally creates a history entry. The - // transition type will be ignored if a history entry is not created. - void LoadURL(const std::wstring& url, bool create_history_entry, - PageTransition::Type transition); + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Windows events ------------------------------------------------------------ - // Windows Event handlers virtual void OnDestroy(); virtual void OnHScroll(int scroll_type, short position, HWND scrollbar); virtual void OnMouseLeave(); @@ -424,33 +421,14 @@ class WebContents : public TabContents, virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param); virtual void OnNCPaint(HRGN rgn); - // Callback from HistoryService for our request for a favicon. - void OnFavIconData(HistoryService::Handle handle, - bool know_favicon, - scoped_refptr<RefCountedBytes> data, - bool expired); - - // NotificationObserver implementation. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Helper functions for sending notifications. - void NotifySwapped(); - void NotifyConnected(); - void NotifyDisconnected(); - - // Called by OnMsgNavigate to update history state. - virtual void UpdateHistoryForNavigation(const GURL& display_url, - const ViewHostMsg_FrameNavigate_Params& params); - - // If params has a searchable form, this tries to create a new keyword. - void GenerateKeywordIfNecessary( - const ViewHostMsg_FrameNavigate_Params& params); + // Backend for all scroll messages, the |message| parameter indicates which + // one it is. + void ScrollCommon(UINT message, int scroll_type, short position, + HWND scrollbar); - // Sets up the View that holds the rendered web page, receives messages for - // it and contains page plugins. - RenderWidgetHostHWND* CreatePageView(RenderViewHost* render_view_host); + // TODO(brettw) comment these. They're confusing. + bool ScrollZoom(int scroll_type); + void WheelZoom(int distance); // Navigation helpers -------------------------------------------------------- // @@ -505,35 +483,33 @@ class WebContents : public TabContents, void UpdateMaxPageIDIfNecessary(SiteInstance* site_instance, RenderViewHost* rvh); - // RenderViewHostManager::Delegate pass-throughs ----------------------------- + // Called by OnMsgNavigate to update history state. Overridden by subclasses + // that don't want to be added to history. + virtual void UpdateHistoryForNavigation(const GURL& display_url, + const ViewHostMsg_FrameNavigate_Params& params); - virtual void BeforeUnloadFiredFromRenderManager( - bool proceed, - bool* proceed_to_fire_unload); - virtual void DidStartLoadingFromRenderManager( - RenderViewHost* render_view_host, int32 page_id) { - DidStartLoading(render_view_host, page_id); - } - virtual void RendererGoneFromRenderManager(RenderViewHost* render_view_host) { - RendererGone(render_view_host); - } - virtual void UpdateRenderViewSizeForRenderManager() { - UpdateRenderViewSize(); - } - virtual void NotifySwappedFromRenderManager() { - NotifySwapped(); - } - virtual NavigationController* GetControllerForRenderManager() { - return controller(); - } + // Misc view stuff ----------------------------------------------------------- - // --------------------------------------------------------------------------- + // Sets up the View that holds the rendered web page, receives messages for + // it and contains page plugins. + RenderWidgetHostHWND* CreatePageView(RenderViewHost* render_view_host); // Enumerate and 'un-parent' any plugin windows that are children // of this web contents. void DetachPluginWindows(); static BOOL CALLBACK EnumPluginWindowsCallback(HWND window, LPARAM param); + // Misc non-view stuff ------------------------------------------------------- + + // Helper functions for sending notifications. + void NotifySwapped(); + void NotifyConnected(); + void NotifyDisconnected(); + + // If params has a searchable form, this tries to create a new keyword. + void GenerateKeywordIfNecessary( + const ViewHostMsg_FrameNavigate_Params& params); + // Data ---------------------------------------------------------------------- // Manages creation and swapping of render views. @@ -603,9 +579,6 @@ class WebContents : public TabContents, // The SadTab renderer. scoped_ptr<SadTabView> sad_tab_; - // This flag is true while we are in the photo-booth. See dragged_tab.cc. - bool capturing_contents_; - // Handles downloading favicons. FavIconHelper fav_icon_helper_; |