blob: 1c7e08f333d17a9c569ce52bac6d5c51a11e6781 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]f3ec7742009-01-15 00:59:165#include "chrome/browser/tab_contents/tab_contents.h"
initial.commit09911bf2008-07-26 23:55:296
7#include "chrome/browser/cert_store.h"
[email protected]bcef0dc02009-02-28 00:35:028#include "chrome/browser/download/download_item_model.h"
9#include "chrome/browser/download/download_shelf.h"
[email protected]f3ec7742009-01-15 00:59:1610#include "chrome/browser/tab_contents/navigation_entry.h"
11#include "chrome/browser/tab_contents/tab_contents_delegate.h"
12#include "chrome/browser/tab_contents/web_contents.h"
[email protected]a4feef82008-10-02 15:11:2213#include "chrome/common/l10n_util.h"
[email protected]bfd04a62009-02-01 18:16:5614#include "chrome/common/notification_service.h"
initial.commit09911bf2008-07-26 23:55:2915#include "chrome/common/pref_names.h"
[email protected]1eb89e82008-08-15 12:27:0316#include "chrome/common/pref_service.h"
[email protected]34ac8f32009-02-22 23:03:2717#include "grit/generated_resources.h"
[email protected]3e45ba92009-02-20 21:09:0018
19#if defined(OS_WIN)
20// TODO(port): some of these headers should be ported.
21#include "chrome/browser/tab_contents/infobar_delegate.h"
[email protected]3e45ba92009-02-20 21:09:0022#include "chrome/browser/views/download_started_animation.h"
23#include "chrome/browser/views/blocked_popup_container.h"
[email protected]6f329092009-03-17 04:56:5524#include "chrome/views/controls/scrollbar/native_scroll_bar.h"
[email protected]3e45ba92009-02-20 21:09:0025#endif
initial.commit09911bf2008-07-26 23:55:2926
[email protected]3e45ba92009-02-20 21:09:0027#if defined(OS_WIN)
[email protected]d5f942ba2008-09-26 19:30:3428namespace {
29
30BOOL CALLBACK InvalidateWindow(HWND hwnd, LPARAM lparam) {
[email protected]4d0bd102008-10-16 00:26:3031 // Note: erase is required to properly paint some widgets borders. This can
32 // be seen with textfields.
[email protected]d5f942ba2008-09-26 19:30:3433 InvalidateRect(hwnd, NULL, TRUE);
34 return TRUE;
35}
36
37} // namespace
[email protected]332af7732009-03-11 13:21:3538#endif
[email protected]d5f942ba2008-09-26 19:30:3439
[email protected]b680ad22009-04-15 23:19:4240TabContents::TabContents()
41 : delegate_(NULL),
initial.commit09911bf2008-07-26 23:55:2942 controller_(NULL),
[email protected]d5f942ba2008-09-26 19:30:3443 is_loading_(false),
initial.commit09911bf2008-07-26 23:55:2944 is_crashed_(false),
[email protected]d5f942ba2008-09-26 19:30:3445 waiting_for_response_(false),
[email protected]d5f942ba2008-09-26 19:30:3446 shelf_visible_(false),
47 max_page_id_(-1),
[email protected]2d843e62008-11-26 21:16:3548 capturing_contents_(false),
[email protected]332af7732009-03-11 13:21:3549 blocked_popups_(NULL),
[email protected]2d843e62008-11-26 21:16:3550 is_being_destroyed_(false) {
[email protected]332af7732009-03-11 13:21:3551}
initial.commit09911bf2008-07-26 23:55:2952
53TabContents::~TabContents() {
initial.commit09911bf2008-07-26 23:55:2954}
55
[email protected]d5f942ba2008-09-26 19:30:3456// static
57void TabContents::RegisterUserPrefs(PrefService* prefs) {
58 prefs->RegisterBooleanPref(prefs::kBlockPopups, false);
initial.commit09911bf2008-07-26 23:55:2959}
60
initial.commit09911bf2008-07-26 23:55:2961void TabContents::CloseContents() {
62 // Destroy our NavigationController, which will Destroy all tabs it owns.
63 controller_->Destroy();
64 // Note that the controller may have deleted us at this point,
65 // so don't touch any member variables here.
66}
67
68void TabContents::Destroy() {
[email protected]9501428d2008-11-27 01:44:4469 DCHECK(!is_being_destroyed_);
[email protected]2d843e62008-11-26 21:16:3570 is_being_destroyed_ = true;
71
initial.commit09911bf2008-07-26 23:55:2972 // First cleanly close all child windows.
73 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
74 // some of these to close. CloseWindows is async, so it might get called
75 // twice before it runs.
76 int size = static_cast<int>(child_windows_.size());
77 for (int i = size - 1; i >= 0; --i) {
78 ConstrainedWindow* window = child_windows_[i];
79 if (window)
80 window->CloseConstrainedWindow();
81 }
82
[email protected]b6187132009-01-21 23:20:4883 // Notify any lasting InfobarDelegates that have not yet been removed that
84 // whatever infobar they were handling in this TabContents has closed,
85 // because the TabContents is going away entirely.
86 for (int i = 0; i < infobar_delegate_count(); ++i) {
87 InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
88 delegate->InfoBarClosed();
89 }
90 infobar_delegates_.clear();
91
initial.commit09911bf2008-07-26 23:55:2992 // Notify any observer that have a reference on this tab contents.
[email protected]bfd04a62009-02-01 18:16:5693 NotificationService::current()->Notify(
94 NotificationType::TAB_CONTENTS_DESTROYED,
95 Source<TabContents>(this),
96 NotificationService::NoDetails());
initial.commit09911bf2008-07-26 23:55:2997
[email protected]76f68dc2009-03-10 20:31:3298#if defined(OS_WIN)
[email protected]92edc472009-02-10 20:32:0699 // If we still have a window handle, destroy it. GetNativeView can return
initial.commit09911bf2008-07-26 23:55:29100 // NULL if this contents was part of a window that closed.
[email protected]92edc472009-02-10 20:32:06101 if (GetNativeView())
102 ::DestroyWindow(GetNativeView());
[email protected]76f68dc2009-03-10 20:31:32103#endif
initial.commit09911bf2008-07-26 23:55:29104
105 // Notify our NavigationController. Make sure we are deleted first, so
106 // that the controller is the last to die.
107 NavigationController* controller = controller_;
initial.commit09911bf2008-07-26 23:55:29108
109 delete this;
110
[email protected]7f0005a2009-04-15 03:25:11111 controller->TabContentsWasDestroyed();
initial.commit09911bf2008-07-26 23:55:29112}
113
[email protected]d5f942ba2008-09-26 19:30:34114void TabContents::SetupController(Profile* profile) {
115 DCHECK(!controller_);
116 controller_ = new NavigationController(this, profile);
117}
118
119bool TabContents::SupportsURL(GURL* url) {
[email protected]9423d9412009-04-14 22:13:55120 return true;
[email protected]d5f942ba2008-09-26 19:30:34121}
122
123const GURL& TabContents::GetURL() const {
124 // We may not have a navigation entry yet
125 NavigationEntry* entry = controller_->GetActiveEntry();
126 return entry ? entry->display_url() : GURL::EmptyGURL();
127}
128
[email protected]4c4d8d22009-03-04 05:29:27129const string16& TabContents::GetTitle() const {
[email protected]cbab76d2008-10-13 22:42:47130 // We use the title for the last committed entry rather than a pending
131 // navigation entry. For example, when the user types in a URL, we want to
132 // keep the old page's title until the new load has committed and we get a new
133 // title.
134 // The exception is with transient pages, for which we really want to use
135 // their title, as they are not committed.
136 NavigationEntry* entry = controller_->GetTransientEntry();
[email protected]3d627bbc2008-10-23 20:49:07137 if (entry)
[email protected]4c4d8d22009-03-04 05:29:27138 return entry->GetTitleForDisplay(controller_);
[email protected]f0a51fb52009-03-05 12:46:38139
[email protected]cbab76d2008-10-13 22:42:47140 entry = controller_->GetLastCommittedEntry();
[email protected]d5f942ba2008-09-26 19:30:34141 if (entry)
[email protected]4c4d8d22009-03-04 05:29:27142 return entry->GetTitleForDisplay(controller_);
[email protected]d5f942ba2008-09-26 19:30:34143 else if (controller_->LoadingURLLazily())
144 return controller_->GetLazyTitle();
[email protected]4c4d8d22009-03-04 05:29:27145 return EmptyString16();
[email protected]d5f942ba2008-09-26 19:30:34146}
147
148int32 TabContents::GetMaxPageID() {
149 if (GetSiteInstance())
150 return GetSiteInstance()->max_page_id();
151 else
152 return max_page_id_;
153}
154
155void TabContents::UpdateMaxPageID(int32 page_id) {
156 // Ensure both the SiteInstance and RenderProcessHost update their max page
157 // IDs in sync. Only WebContents will also have site instances, except during
158 // testing.
159 if (GetSiteInstance())
160 GetSiteInstance()->UpdateMaxPageID(page_id);
161
162 if (AsWebContents())
163 AsWebContents()->process()->UpdateMaxPageID(page_id);
164 else
165 max_page_id_ = std::max(max_page_id_, page_id);
166}
167
168const std::wstring TabContents::GetDefaultTitle() const {
169 return l10n_util::GetString(IDS_DEFAULT_TAB_TITLE);
170}
171
172SkBitmap TabContents::GetFavIcon() const {
173 // Like GetTitle(), we also want to use the favicon for the last committed
174 // entry rather than a pending navigation entry.
[email protected]cbab76d2008-10-13 22:42:47175 NavigationEntry* entry = controller_->GetTransientEntry();
176 if (entry)
177 return entry->favicon().bitmap();
178
179 entry = controller_->GetLastCommittedEntry();
[email protected]d5f942ba2008-09-26 19:30:34180 if (entry)
181 return entry->favicon().bitmap();
182 else if (controller_->LoadingURLLazily())
183 return controller_->GetLazyFavIcon();
184 return SkBitmap();
185}
186
[email protected]3e45ba92009-02-20 21:09:00187#if defined(OS_WIN)
[email protected]d5f942ba2008-09-26 19:30:34188SecurityStyle TabContents::GetSecurityStyle() const {
189 // We may not have a navigation entry yet.
190 NavigationEntry* entry = controller_->GetActiveEntry();
191 return entry ? entry->ssl().security_style() : SECURITY_STYLE_UNKNOWN;
192}
193
194bool TabContents::GetSSLEVText(std::wstring* ev_text,
195 std::wstring* ev_tooltip_text) const {
196 DCHECK(ev_text && ev_tooltip_text);
197 ev_text->clear();
198 ev_tooltip_text->clear();
199
200 NavigationEntry* entry = controller_->GetActiveEntry();
201 if (!entry ||
202 net::IsCertStatusError(entry->ssl().cert_status()) ||
203 ((entry->ssl().cert_status() & net::CERT_STATUS_IS_EV) == 0))
204 return false;
205
206 scoped_refptr<net::X509Certificate> cert;
207 CertStore::GetSharedInstance()->RetrieveCert(entry->ssl().cert_id(), &cert);
208 if (!cert.get()) {
209 NOTREACHED();
210 return false;
211 }
212
213 return SSLManager::GetEVCertNames(*cert, ev_text, ev_tooltip_text);
214}
[email protected]76f68dc2009-03-10 20:31:32215#endif
[email protected]d5f942ba2008-09-26 19:30:34216
217void TabContents::SetIsCrashed(bool state) {
218 if (state == is_crashed_)
219 return;
220
221 is_crashed_ = state;
222 if (delegate_)
223 delegate_->ContentsStateChanged(this);
224}
225
226void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) {
227 if (delegate_)
228 delegate_->NavigationStateChanged(this, changed_flags);
229}
230
231void TabContents::DidBecomeSelected() {
232 if (controller_)
233 controller_->SetActive(true);
234
[email protected]76f68dc2009-03-10 20:31:32235#if defined(OS_WIN)
[email protected]d5f942ba2008-09-26 19:30:34236 // Invalidate all descendants. (take care to exclude invalidating ourselves!)
[email protected]92edc472009-02-10 20:32:06237 EnumChildWindows(GetNativeView(), InvalidateWindow, 0);
[email protected]76f68dc2009-03-10 20:31:32238#endif
[email protected]d5f942ba2008-09-26 19:30:34239}
240
241void TabContents::WasHidden() {
[email protected]bfd04a62009-02-01 18:16:56242 NotificationService::current()->Notify(
243 NotificationType::TAB_CONTENTS_HIDDEN,
244 Source<TabContents>(this),
245 NotificationService::NoDetails());
[email protected]d5f942ba2008-09-26 19:30:34246}
247
248void TabContents::Activate() {
249 if (delegate_)
250 delegate_->ActivateContents(this);
251}
252
[email protected]c0588052008-10-27 23:01:50253void TabContents::OpenURL(const GURL& url, const GURL& referrer,
[email protected]d5f942ba2008-09-26 19:30:34254 WindowOpenDisposition disposition,
255 PageTransition::Type transition) {
256 if (delegate_)
[email protected]c0588052008-10-27 23:01:50257 delegate_->OpenURLFromTab(this, url, referrer, disposition, transition);
[email protected]d5f942ba2008-09-26 19:30:34258}
259
260bool TabContents::NavigateToPendingEntry(bool reload) {
261 // Our benavior is just to report that the entry was committed.
[email protected]76f68dc2009-03-10 20:31:32262 string16 default_title = WideToUTF16Hack(GetDefaultTitle());
[email protected]7f0005a2009-04-15 03:25:11263 controller()->pending_entry()->set_title(default_title);
[email protected]d5f942ba2008-09-26 19:30:34264 controller()->CommitPendingEntry();
265 return true;
266}
267
[email protected]76f68dc2009-03-10 20:31:32268#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29269ConstrainedWindow* TabContents::CreateConstrainedDialog(
[email protected]c2dacc92008-10-16 23:51:38270 views::WindowDelegate* window_delegate,
271 views::View* contents_view) {
initial.commit09911bf2008-07-26 23:55:29272 ConstrainedWindow* window =
273 ConstrainedWindow::CreateConstrainedDialog(
274 this, gfx::Rect(), contents_view, window_delegate);
275 child_windows_.push_back(window);
276 return window;
277}
[email protected]f3332e12009-03-23 15:28:57278#endif
initial.commit09911bf2008-07-26 23:55:29279
280void TabContents::AddNewContents(TabContents* new_contents,
281 WindowOpenDisposition disposition,
282 const gfx::Rect& initial_pos,
283 bool user_gesture) {
284 if (!delegate_)
285 return;
286
[email protected]f3332e12009-03-23 15:28:57287#if defined(OS_WIN)
[email protected]3b0a45e82008-10-13 21:01:03288 if ((disposition == NEW_POPUP) && !user_gesture) {
289 // Unrequested popups from normal pages are constrained.
290 TabContents* popup_owner = this;
291 TabContents* our_owner = delegate_->GetConstrainingContents(this);
292 if (our_owner)
293 popup_owner = our_owner;
294 popup_owner->AddConstrainedPopup(new_contents, initial_pos);
initial.commit09911bf2008-07-26 23:55:29295 } else {
[email protected]0aa55312008-10-17 21:53:08296 new_contents->DisassociateFromPopupCount();
297
initial.commit09911bf2008-07-26 23:55:29298 delegate_->AddNewContents(this, new_contents, disposition, initial_pos,
299 user_gesture);
[email protected]634a6f92008-12-01 21:39:31300
301 PopupNotificationVisibilityChanged(ShowingBlockedPopupNotification());
initial.commit09911bf2008-07-26 23:55:29302 }
[email protected]f3332e12009-03-23 15:28:57303#else
304 // TODO(port): implement the popup blocker stuff
305 delegate_->AddNewContents(this, new_contents, disposition, initial_pos,
306 user_gesture);
307#endif
initial.commit09911bf2008-07-26 23:55:29308}
309
[email protected]f3332e12009-03-23 15:28:57310#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29311void TabContents::AddConstrainedPopup(TabContents* new_contents,
312 const gfx::Rect& initial_pos) {
[email protected]d6598c052008-11-05 19:03:25313 if (!blocked_popups_) {
314 CRect client_rect;
[email protected]92edc472009-02-10 20:32:06315 GetClientRect(GetNativeView(), &client_rect);
[email protected]d6598c052008-11-05 19:03:25316 gfx::Point anchor_position(
317 client_rect.Width() -
318 views::NativeScrollBar::GetVerticalScrollBarWidth(),
319 client_rect.Height());
initial.commit09911bf2008-07-26 23:55:29320
[email protected]d6598c052008-11-05 19:03:25321 blocked_popups_ = BlockedPopupContainer::Create(
322 this, profile(), anchor_position);
323 child_windows_.push_back(blocked_popups_);
324 }
325
326 blocked_popups_->AddTabContents(new_contents, initial_pos);
[email protected]634a6f92008-12-01 21:39:31327 PopupNotificationVisibilityChanged(ShowingBlockedPopupNotification());
initial.commit09911bf2008-07-26 23:55:29328}
329
initial.commit09911bf2008-07-26 23:55:29330void TabContents::CloseAllSuppressedPopups() {
[email protected]d6598c052008-11-05 19:03:25331 if (blocked_popups_)
332 blocked_popups_->CloseAllPopups();
initial.commit09911bf2008-07-26 23:55:29333}
[email protected]332af7732009-03-11 13:21:35334#endif
initial.commit09911bf2008-07-26 23:55:29335
[email protected]616ed5a2008-11-21 22:27:24336void TabContents::AddInfoBar(InfoBarDelegate* delegate) {
337 // Look through the existing InfoBarDelegates we have for a match. If we've
338 // already got one that matches, then we don't add the new one.
[email protected]f86a07022008-11-25 01:06:05339 for (int i = 0; i < infobar_delegate_count(); ++i) {
[email protected]616ed5a2008-11-21 22:27:24340 if (GetInfoBarDelegateAt(i)->EqualsDelegate(delegate))
341 return;
342 }
343
344 infobar_delegates_.push_back(delegate);
[email protected]bfd04a62009-02-01 18:16:56345 NotificationService::current()->Notify(
346 NotificationType::TAB_CONTENTS_INFOBAR_ADDED,
347 Source<TabContents>(this),
348 Details<InfoBarDelegate>(delegate));
[email protected]616ed5a2008-11-21 22:27:24349
350 // Add ourselves as an observer for navigations the first time a delegate is
351 // added. We use this notification to expire InfoBars that need to expire on
352 // page transitions.
353 if (infobar_delegates_.size() == 1) {
[email protected]6a02963e2009-01-06 16:58:03354 DCHECK(controller());
[email protected]bfd04a62009-02-01 18:16:56355 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]6a02963e2009-01-06 16:58:03356 Source<NavigationController>(controller()));
[email protected]616ed5a2008-11-21 22:27:24357 }
358}
359
360void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) {
361 std::vector<InfoBarDelegate*>::iterator it =
362 find(infobar_delegates_.begin(), infobar_delegates_.end(), delegate);
363 if (it != infobar_delegates_.end()) {
364 InfoBarDelegate* delegate = *it;
[email protected]bfd04a62009-02-01 18:16:56365 NotificationService::current()->Notify(
366 NotificationType::TAB_CONTENTS_INFOBAR_REMOVED,
367 Source<TabContents>(this),
368 Details<InfoBarDelegate>(delegate));
[email protected]f86a07022008-11-25 01:06:05369 infobar_delegates_.erase(it);
[email protected]616ed5a2008-11-21 22:27:24370
[email protected]6a02963e2009-01-06 16:58:03371 // Remove ourselves as an observer if we are tracking no more InfoBars.
372 if (infobar_delegates_.empty()) {
[email protected]bfd04a62009-02-01 18:16:56373 registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]6a02963e2009-01-06 16:58:03374 Source<NavigationController>(controller()));
375 }
[email protected]616ed5a2008-11-21 22:27:24376 }
377}
[email protected]3edd9522009-03-04 22:19:41378
379void TabContents::ToolbarSizeChanged(bool is_animating) {
380 TabContentsDelegate* d = delegate();
381 if (d)
382 d->ToolbarSizeChanged(this, is_animating);
383}
[email protected]616ed5a2008-11-21 22:27:24384
initial.commit09911bf2008-07-26 23:55:29385void TabContents::SetDownloadShelfVisible(bool visible) {
386 if (shelf_visible_ != visible) {
387 if (visible) {
[email protected]bcef0dc02009-02-28 00:35:02388 // Invoke GetDownloadShelf to force the shelf to be created.
389 GetDownloadShelf();
initial.commit09911bf2008-07-26 23:55:29390 }
391 shelf_visible_ = visible;
392
[email protected]019d83502008-07-30 22:44:50393 if (delegate_)
394 delegate_->ContentsStateChanged(this);
initial.commit09911bf2008-07-26 23:55:29395 }
[email protected]ce2390b682008-08-08 22:24:51396
397 // SetShelfVisible can force-close the shelf, so make sure we lay out
398 // everything correctly, as if the animation had finished. This doesn't
399 // matter for showing the shelf, as the show animation will do it.
400 ToolbarSizeChanged(false);
initial.commit09911bf2008-07-26 23:55:29401}
402
[email protected]d5f942ba2008-09-26 19:30:34403void TabContents::OnStartDownload(DownloadItem* download) {
404 DCHECK(download);
405 TabContents* tab_contents = this;
406
[email protected]3edd9522009-03-04 22:19:41407// TODO(port): port contraining contents.
408#if defined(OS_WIN)
[email protected]d5f942ba2008-09-26 19:30:34409 // Download in a constrained popup is shown in the tab that opened it.
410 TabContents* constraining_tab = delegate()->GetConstrainingContents(this);
411 if (constraining_tab)
412 tab_contents = constraining_tab;
[email protected]3edd9522009-03-04 22:19:41413#endif
[email protected]d5f942ba2008-09-26 19:30:34414
[email protected]bcef0dc02009-02-28 00:35:02415 // GetDownloadShelf creates the download shelf if it was not yet created.
416 tab_contents->GetDownloadShelf()->AddDownload(
417 new DownloadItemModel(download));
[email protected]d5f942ba2008-09-26 19:30:34418 tab_contents->SetDownloadShelfVisible(true);
419
[email protected]3edd9522009-03-04 22:19:41420// TODO(port): port animatinos.
421#if defined(OS_WIN)
[email protected]d5f942ba2008-09-26 19:30:34422 // This animation will delete itself when it finishes, or if we become hidden
423 // or destroyed.
[email protected]92edc472009-02-10 20:32:06424 if (IsWindowVisible(GetNativeView())) { // For minimized windows, unit
425 // tests, etc.
[email protected]d5f942ba2008-09-26 19:30:34426 new DownloadStartedAnimation(tab_contents);
427 }
[email protected]3edd9522009-03-04 22:19:41428#endif
[email protected]d5f942ba2008-09-26 19:30:34429}
430
[email protected]bcef0dc02009-02-28 00:35:02431DownloadShelf* TabContents::GetDownloadShelf() {
432 if (!download_shelf_.get())
433 download_shelf_.reset(DownloadShelf::Create(this));
434 return download_shelf_.get();
initial.commit09911bf2008-07-26 23:55:29435}
436
[email protected]bcef0dc02009-02-28 00:35:02437void TabContents::MigrateShelfFrom(TabContents* tab_contents) {
438 download_shelf_.reset(tab_contents->GetDownloadShelf());
439 download_shelf_->ChangeTabContents(tab_contents, this);
440 tab_contents->ReleaseDownloadShelf();
initial.commit09911bf2008-07-26 23:55:29441}
442
[email protected]3edd9522009-03-04 22:19:41443void TabContents::ReleaseDownloadShelf() {
444 download_shelf_.release();
445}
446
447// static
448void TabContents::MigrateShelf(TabContents* from, TabContents* to) {
449 bool was_shelf_visible = from->IsDownloadShelfVisible();
450 if (was_shelf_visible)
451 to->MigrateShelfFrom(from);
452 to->SetDownloadShelfVisible(was_shelf_visible);
453}
[email protected]3edd9522009-03-04 22:19:41454
[email protected]d5f942ba2008-09-26 19:30:34455void TabContents::WillClose(ConstrainedWindow* window) {
456 ConstrainedWindowList::iterator it =
457 find(child_windows_.begin(), child_windows_.end(), window);
458 if (it != child_windows_.end())
459 child_windows_.erase(it);
460
[email protected]332af7732009-03-11 13:21:35461#if defined(OS_WIN)
[email protected]d6598c052008-11-05 19:03:25462 if (window == blocked_popups_)
463 blocked_popups_ = NULL;
464
[email protected]92edc472009-02-10 20:32:06465 if (::IsWindow(GetNativeView())) {
[email protected]d5f942ba2008-09-26 19:30:34466 CRect client_rect;
[email protected]92edc472009-02-10 20:32:06467 GetClientRect(GetNativeView(), &client_rect);
[email protected]d5f942ba2008-09-26 19:30:34468 RepositionSupressedPopupsToFit(
469 gfx::Size(client_rect.Width(), client_rect.Height()));
470 }
[email protected]332af7732009-03-11 13:21:35471#endif
[email protected]d5f942ba2008-09-26 19:30:34472}
473
[email protected]d5f942ba2008-09-26 19:30:34474void TabContents::DidMoveOrResize(ConstrainedWindow* window) {
[email protected]332af7732009-03-11 13:21:35475#if defined(OS_WIN)
[email protected]92edc472009-02-10 20:32:06476 UpdateWindow(GetNativeView());
[email protected]332af7732009-03-11 13:21:35477#endif
[email protected]d5f942ba2008-09-26 19:30:34478}
479
[email protected]616ed5a2008-11-21 22:27:24480void TabContents::Observe(NotificationType type,
481 const NotificationSource& source,
482 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56483 DCHECK(type == NotificationType::NAV_ENTRY_COMMITTED);
[email protected]616ed5a2008-11-21 22:27:24484 DCHECK(controller() == Source<NavigationController>(source).ptr());
485
486 NavigationController::LoadCommittedDetails& committed_details =
487 *(Details<NavigationController::LoadCommittedDetails>(details).ptr());
488 ExpireInfoBars(committed_details);
489}
490
[email protected]d5f942ba2008-09-26 19:30:34491void TabContents::SetIsLoading(bool is_loading,
492 LoadNotificationDetails* details) {
493 if (is_loading == is_loading_)
494 return;
495
496 is_loading_ = is_loading;
497 waiting_for_response_ = is_loading;
498
[email protected]d5f942ba2008-09-26 19:30:34499 if (delegate_)
500 delegate_->LoadingStateChanged(this);
501
[email protected]bfd04a62009-02-01 18:16:56502 NotificationType type = is_loading ? NotificationType::LOAD_START :
503 NotificationType::LOAD_STOP;
[email protected]76f68dc2009-03-10 20:31:32504 NotificationDetails det = NotificationService::NoDetails();;
505 if (details)
506 det = Details<LoadNotificationDetails>(details);
[email protected]f0a51fb52009-03-05 12:46:38507 NotificationService::current()->Notify(type,
[email protected]bfd04a62009-02-01 18:16:56508 Source<NavigationController>(this->controller()),
509 det);
initial.commit09911bf2008-07-26 23:55:29510}
license.botbf09a502008-08-24 00:55:55511
[email protected]76f68dc2009-03-10 20:31:32512#if defined(OS_WIN)
[email protected]9e0534b2008-10-21 15:03:01513// TODO(brettw) This should be on the WebContentsView.
[email protected]d5f942ba2008-09-26 19:30:34514void TabContents::RepositionSupressedPopupsToFit(const gfx::Size& new_size) {
515 // TODO(erg): There's no way to detect whether scroll bars are
516 // visible, so for beta, we're just going to assume that the
517 // vertical scroll bar is visible, and not care about covering up
518 // the horizontal scroll bar. Fixing this is half of
519 // http://b/1118139.
520 gfx::Point anchor_position(
521 new_size.width() -
[email protected]c2dacc92008-10-16 23:51:38522 views::NativeScrollBar::GetVerticalScrollBarWidth(),
[email protected]d5f942ba2008-09-26 19:30:34523 new_size.height());
[email protected]d6598c052008-11-05 19:03:25524
525 if (blocked_popups_)
526 blocked_popups_->RepositionConstrainedWindowTo(anchor_position);
[email protected]d5f942ba2008-09-26 19:30:34527}
528
[email protected]b9681312008-11-07 00:08:26529bool TabContents::ShowingBlockedPopupNotification() const {
530 return blocked_popups_ != NULL &&
531 blocked_popups_->GetTabContentsCount() != 0;
532}
[email protected]332af7732009-03-11 13:21:35533#endif // defined(OS_WIN)
[email protected]616ed5a2008-11-21 22:27:24534
535namespace {
536bool TransitionIsReload(PageTransition::Type transition) {
537 return PageTransition::StripQualifier(transition) == PageTransition::RELOAD;
538}
539}
540
541void TabContents::ExpireInfoBars(
542 const NavigationController::LoadCommittedDetails& details) {
543 // Only hide InfoBars when the user has done something that makes the main
544 // frame load. We don't want various automatic or subframe navigations making
545 // it disappear.
546 if (!details.is_user_initiated_main_frame_load())
547 return;
548
[email protected]f86a07022008-11-25 01:06:05549 for (int i = infobar_delegate_count() - 1; i >= 0; --i) {
[email protected]616ed5a2008-11-21 22:27:24550 InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
[email protected]f86a07022008-11-25 01:06:05551 if (delegate->ShouldExpire(details))
[email protected]616ed5a2008-11-21 22:27:24552 RemoveInfoBar(delegate);
[email protected]616ed5a2008-11-21 22:27:24553 }
554}