Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Side by Side Diff: content/browser/web_contents/navigation_controller_impl.cc

Issue 11231077: Move a bunch more code into the content namespace. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/web_contents/navigation_controller_impl.h" 5 #include "content/browser/web_contents/navigation_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_number_conversions.h" // Temporary 10 #include "base/string_number_conversions.h" // Temporary
(...skipping 21 matching lines...) Expand all
32 #include "content/public/browser/user_metrics.h" 32 #include "content/public/browser/user_metrics.h"
33 #include "content/public/browser/web_contents_delegate.h" 33 #include "content/public/browser/web_contents_delegate.h"
34 #include "content/public/common/content_client.h" 34 #include "content/public/common/content_client.h"
35 #include "content/public/common/content_constants.h" 35 #include "content/public/common/content_constants.h"
36 #include "content/public/common/url_constants.h" 36 #include "content/public/common/url_constants.h"
37 #include "net/base/escape.h" 37 #include "net/base/escape.h"
38 #include "net/base/mime_util.h" 38 #include "net/base/mime_util.h"
39 #include "net/base/net_util.h" 39 #include "net/base/net_util.h"
40 #include "webkit/glue/glue_serialize.h" 40 #include "webkit/glue/glue_serialize.h"
41 41
42 using content::BrowserContext; 42 namespace content {
43 using content::DOMStorageContext;
44 using content::GetContentClient;
45 using content::GlobalRequestID;
46 using content::NavigationController;
47 using content::NavigationEntry;
48 using content::NavigationEntryImpl;
49 using content::RenderViewHostImpl;
50 using content::SessionStorageNamespace;
51 using content::SessionStorageNamespaceMap;
52 using content::SiteInstance;
53 using content::UserMetricsAction;
54 using content::WebContents;
55
56 namespace { 43 namespace {
57 44
58 const int kInvalidateAll = 0xFFFFFFFF; 45 const int kInvalidateAll = 0xFFFFFFFF;
59 46
60 // Invoked when entries have been pruned, or removed. For example, if the 47 // Invoked when entries have been pruned, or removed. For example, if the
61 // current entries are [google, digg, yahoo], with the current entry google, 48 // current entries are [google, digg, yahoo], with the current entry google,
62 // and the user types in cnet, then digg and yahoo are pruned. 49 // and the user types in cnet, then digg and yahoo are pruned.
63 void NotifyPrunedEntries(NavigationControllerImpl* nav_controller, 50 void NotifyPrunedEntries(NavigationControllerImpl* nav_controller,
64 bool from_front, 51 bool from_front,
65 int count) { 52 int count) {
66 content::PrunedDetails details; 53 PrunedDetails details;
67 details.from_front = from_front; 54 details.from_front = from_front;
68 details.count = count; 55 details.count = count;
69 content::NotificationService::current()->Notify( 56 NotificationService::current()->Notify(
70 content::NOTIFICATION_NAV_LIST_PRUNED, 57 NOTIFICATION_NAV_LIST_PRUNED,
71 content::Source<NavigationController>(nav_controller), 58 Source<NavigationController>(nav_controller),
72 content::Details<content::PrunedDetails>(&details)); 59 Details<PrunedDetails>(&details));
73 } 60 }
74 61
75 // Ensure the given NavigationEntry has a valid state, so that WebKit does not 62 // Ensure the given NavigationEntry has a valid state, so that WebKit does not
76 // get confused if we navigate back to it. 63 // get confused if we navigate back to it.
77 // 64 //
78 // An empty state is treated as a new navigation by WebKit, which would mean 65 // An empty state is treated as a new navigation by WebKit, which would mean
79 // losing the navigation entries and generating a new navigation entry after 66 // losing the navigation entries and generating a new navigation entry after
80 // this one. We don't want that. To avoid this we create a valid state which 67 // this one. We don't want that. To avoid this we create a valid state which
81 // WebKit will not treat as a new navigation. 68 // WebKit will not treat as a new navigation.
82 void SetContentStateIfEmpty(NavigationEntryImpl* entry) { 69 void SetContentStateIfEmpty(NavigationEntryImpl* entry) {
(...skipping 18 matching lines...) Expand all
101 } 88 }
102 89
103 // Configure all the NavigationEntries in entries for restore. This resets 90 // Configure all the NavigationEntries in entries for restore. This resets
104 // the transition type to reload and makes sure the content state isn't empty. 91 // the transition type to reload and makes sure the content state isn't empty.
105 void ConfigureEntriesForRestore( 92 void ConfigureEntriesForRestore(
106 std::vector<linked_ptr<NavigationEntryImpl> >* entries, 93 std::vector<linked_ptr<NavigationEntryImpl> >* entries,
107 NavigationController::RestoreType type) { 94 NavigationController::RestoreType type) {
108 for (size_t i = 0; i < entries->size(); ++i) { 95 for (size_t i = 0; i < entries->size(); ++i) {
109 // Use a transition type of reload so that we don't incorrectly increase 96 // Use a transition type of reload so that we don't incorrectly increase
110 // the typed count. 97 // the typed count.
111 (*entries)[i]->SetTransitionType(content::PAGE_TRANSITION_RELOAD); 98 (*entries)[i]->SetTransitionType(PAGE_TRANSITION_RELOAD);
112 (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type)); 99 (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type));
113 // NOTE(darin): This code is only needed for backwards compat. 100 // NOTE(darin): This code is only needed for backwards compat.
114 SetContentStateIfEmpty((*entries)[i].get()); 101 SetContentStateIfEmpty((*entries)[i].get());
115 } 102 }
116 } 103 }
117 104
118 // See NavigationController::IsURLInPageNavigation for how this works and why. 105 // See NavigationController::IsURLInPageNavigation for how this works and why.
119 bool AreURLsInPageNavigation(const GURL& existing_url, 106 bool AreURLsInPageNavigation(const GURL& existing_url,
120 const GURL& new_url, 107 const GURL& new_url,
121 bool renderer_says_in_page) { 108 bool renderer_says_in_page) {
(...skipping 11 matching lines...) Expand all
133 } 120 }
134 121
135 url_canon::Replacements<char> replacements; 122 url_canon::Replacements<char> replacements;
136 replacements.ClearRef(); 123 replacements.ClearRef();
137 return existing_url.ReplaceComponents(replacements) == 124 return existing_url.ReplaceComponents(replacements) ==
138 new_url.ReplaceComponents(replacements); 125 new_url.ReplaceComponents(replacements);
139 } 126 }
140 127
141 // Determines whether or not we should be carrying over a user agent override 128 // Determines whether or not we should be carrying over a user agent override
142 // between two NavigationEntries. 129 // between two NavigationEntries.
143 bool ShouldKeepOverride(const content::NavigationEntry* last_entry) { 130 bool ShouldKeepOverride(const NavigationEntry* last_entry) {
144 return last_entry && last_entry->GetIsOverridingUserAgent(); 131 return last_entry && last_entry->GetIsOverridingUserAgent();
145 } 132 }
146 133
147 } // namespace 134 } // namespace
148 135
149 // NavigationControllerImpl ---------------------------------------------------- 136 // NavigationControllerImpl ----------------------------------------------------
150 137
151 const size_t kMaxEntryCountForTestingNotSet = -1; 138 const size_t kMaxEntryCountForTestingNotSet = -1;
152 139
153 // static 140 // static
154 size_t NavigationControllerImpl::max_entry_count_for_testing_ = 141 size_t NavigationControllerImpl::max_entry_count_for_testing_ =
155 kMaxEntryCountForTestingNotSet; 142 kMaxEntryCountForTestingNotSet;
156 143
157 // Should Reload check for post data? The default is true, but is set to false 144 // Should Reload check for post data? The default is true, but is set to false
158 // when testing. 145 // when testing.
159 static bool g_check_for_repost = true; 146 static bool g_check_for_repost = true;
160 147
161 namespace content {
162 // static 148 // static
163 NavigationEntry* NavigationController::CreateNavigationEntry( 149 NavigationEntry* NavigationController::CreateNavigationEntry(
164 const GURL& url, 150 const GURL& url,
165 const Referrer& referrer, 151 const Referrer& referrer,
166 PageTransition transition, 152 PageTransition transition,
167 bool is_renderer_initiated, 153 bool is_renderer_initiated,
168 const std::string& extra_headers, 154 const std::string& extra_headers,
169 BrowserContext* browser_context) { 155 BrowserContext* browser_context) {
170 // Allow the browser URL handler to rewrite the URL. This will, for example, 156 // Allow the browser URL handler to rewrite the URL. This will, for example,
171 // remove "view-source:" from the beginning of the URL to get the URL that 157 // remove "view-source:" from the beginning of the URL to get the URL that
(...skipping 18 matching lines...) Expand all
190 entry->set_update_virtual_url_with_url(reverse_on_redirect); 176 entry->set_update_virtual_url_with_url(reverse_on_redirect);
191 entry->set_extra_headers(extra_headers); 177 entry->set_extra_headers(extra_headers);
192 return entry; 178 return entry;
193 } 179 }
194 180
195 // static 181 // static
196 void NavigationController::DisablePromptOnRepost() { 182 void NavigationController::DisablePromptOnRepost() {
197 g_check_for_repost = false; 183 g_check_for_repost = false;
198 } 184 }
199 185
200 } // namespace content
201
202 base::Time NavigationControllerImpl::TimeSmoother::GetSmoothedTime( 186 base::Time NavigationControllerImpl::TimeSmoother::GetSmoothedTime(
203 base::Time t) { 187 base::Time t) {
204 // If |t| is between the water marks, we're in a run of duplicates 188 // If |t| is between the water marks, we're in a run of duplicates
205 // or just getting out of it, so increase the high-water mark to get 189 // or just getting out of it, so increase the high-water mark to get
206 // a time that probably hasn't been used before and return it. 190 // a time that probably hasn't been used before and return it.
207 if (low_water_mark_ <= t && t <= high_water_mark_) { 191 if (low_water_mark_ <= t && t <= high_water_mark_) {
208 high_water_mark_ += base::TimeDelta::FromMicroseconds(1); 192 high_water_mark_ += base::TimeDelta::FromMicroseconds(1);
209 return high_water_mark_; 193 return high_water_mark_;
210 } 194 }
211 195
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 263 }
280 void NavigationControllerImpl::ReloadOriginalRequestURL(bool check_for_repost) { 264 void NavigationControllerImpl::ReloadOriginalRequestURL(bool check_for_repost) {
281 ReloadInternal(check_for_repost, RELOAD_ORIGINAL_REQUEST_URL); 265 ReloadInternal(check_for_repost, RELOAD_ORIGINAL_REQUEST_URL);
282 } 266 }
283 267
284 void NavigationControllerImpl::ReloadInternal(bool check_for_repost, 268 void NavigationControllerImpl::ReloadInternal(bool check_for_repost,
285 ReloadType reload_type) { 269 ReloadType reload_type) {
286 if (transient_entry_index_ != -1) { 270 if (transient_entry_index_ != -1) {
287 // If an interstitial is showing, treat a reload as a navigation to the 271 // If an interstitial is showing, treat a reload as a navigation to the
288 // transient entry's URL. 272 // transient entry's URL.
289 content::NavigationEntryImpl* active_entry = 273 NavigationEntryImpl* active_entry =
290 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry()); 274 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry());
291 if (!active_entry) 275 if (!active_entry)
292 return; 276 return;
293 LoadURL(active_entry->GetURL(), 277 LoadURL(active_entry->GetURL(),
294 content::Referrer(), 278 Referrer(),
295 content::PAGE_TRANSITION_RELOAD, 279 PAGE_TRANSITION_RELOAD,
296 active_entry->extra_headers()); 280 active_entry->extra_headers());
297 return; 281 return;
298 } 282 }
299 283
300 DiscardNonCommittedEntriesInternal(); 284 DiscardNonCommittedEntriesInternal();
301 int current_index = GetCurrentEntryIndex(); 285 int current_index = GetCurrentEntryIndex();
302 // If we are no where, then we can't reload. TODO(darin): We should add a 286 // If we are no where, then we can't reload. TODO(darin): We should add a
303 // CanReload method. 287 // CanReload method.
304 if (current_index == -1) { 288 if (current_index == -1) {
305 return; 289 return;
306 } 290 }
307 291
308 if (g_check_for_repost && check_for_repost && 292 if (g_check_for_repost && check_for_repost &&
309 GetEntryAtIndex(current_index)->GetHasPostData()) { 293 GetEntryAtIndex(current_index)->GetHasPostData()) {
310 // The user is asking to reload a page with POST data. Prompt to make sure 294 // The user is asking to reload a page with POST data. Prompt to make sure
311 // they really want to do this. If they do, the dialog will call us back 295 // they really want to do this. If they do, the dialog will call us back
312 // with check_for_repost = false. 296 // with check_for_repost = false.
313 content::NotificationService::current()->Notify( 297 NotificationService::current()->Notify(
314 content::NOTIFICATION_REPOST_WARNING_SHOWN, 298 NOTIFICATION_REPOST_WARNING_SHOWN,
315 content::Source<NavigationController>(this), 299 Source<NavigationController>(this),
316 content::NotificationService::NoDetails()); 300 NotificationService::NoDetails());
317 301
318 pending_reload_ = reload_type; 302 pending_reload_ = reload_type;
319 web_contents_->Activate(); 303 web_contents_->Activate();
320 web_contents_->GetDelegate()->ShowRepostFormWarningDialog(web_contents_); 304 web_contents_->GetDelegate()->ShowRepostFormWarningDialog(web_contents_);
321 } else { 305 } else {
322 DiscardNonCommittedEntriesInternal(); 306 DiscardNonCommittedEntriesInternal();
323 307
324 NavigationEntryImpl* entry = entries_[current_index].get(); 308 NavigationEntryImpl* entry = entries_[current_index].get();
325 SiteInstanceImpl* site_instance = entry->site_instance(); 309 SiteInstanceImpl* site_instance = entry->site_instance();
326 DCHECK(site_instance); 310 DCHECK(site_instance);
(...skipping 22 matching lines...) Expand all
349 pending_entry_ = nav_entry; 333 pending_entry_ = nav_entry;
350 } else { 334 } else {
351 pending_entry_index_ = current_index; 335 pending_entry_index_ = current_index;
352 336
353 // The title of the page being reloaded might have been removed in the 337 // The title of the page being reloaded might have been removed in the
354 // meanwhile, so we need to revert to the default title upon reload and 338 // meanwhile, so we need to revert to the default title upon reload and
355 // invalidate the previously cached title (SetTitle will do both). 339 // invalidate the previously cached title (SetTitle will do both).
356 // See Chromium issue 96041. 340 // See Chromium issue 96041.
357 entries_[pending_entry_index_]->SetTitle(string16()); 341 entries_[pending_entry_index_]->SetTitle(string16());
358 342
359 entries_[pending_entry_index_]->SetTransitionType( 343 entries_[pending_entry_index_]->SetTransitionType(PAGE_TRANSITION_RELOAD);
360 content::PAGE_TRANSITION_RELOAD);
361 } 344 }
362 345
363 NavigateToPendingEntry(reload_type); 346 NavigateToPendingEntry(reload_type);
364 } 347 }
365 } 348 }
366 349
367 void NavigationControllerImpl::CancelPendingReload() { 350 void NavigationControllerImpl::CancelPendingReload() {
368 DCHECK(pending_reload_ != NO_RELOAD); 351 DCHECK(pending_reload_ != NO_RELOAD);
369 pending_reload_ = NO_RELOAD; 352 pending_reload_ = NO_RELOAD;
370 } 353 }
(...skipping 29 matching lines...) Expand all
400 << entry->GetURL(); 383 << entry->GetURL();
401 delete entry; 384 delete entry;
402 return; 385 return;
403 } 386 }
404 387
405 // When navigating to a new page, we don't know for sure if we will actually 388 // When navigating to a new page, we don't know for sure if we will actually
406 // end up leaving the current page. The new page load could for example 389 // end up leaving the current page. The new page load could for example
407 // result in a download or a 'no content' response (e.g., a mailto: URL). 390 // result in a download or a 'no content' response (e.g., a mailto: URL).
408 DiscardNonCommittedEntriesInternal(); 391 DiscardNonCommittedEntriesInternal();
409 pending_entry_ = entry; 392 pending_entry_ = entry;
410 content::NotificationService::current()->Notify( 393 NotificationService::current()->Notify(
411 content::NOTIFICATION_NAV_ENTRY_PENDING, 394 NOTIFICATION_NAV_ENTRY_PENDING,
412 content::Source<NavigationController>(this), 395 Source<NavigationController>(this),
413 content::Details<NavigationEntry>(entry)); 396 Details<NavigationEntry>(entry));
414 NavigateToPendingEntry(NO_RELOAD); 397 NavigateToPendingEntry(NO_RELOAD);
415 } 398 }
416 399
417 NavigationEntry* NavigationControllerImpl::GetActiveEntry() const { 400 NavigationEntry* NavigationControllerImpl::GetActiveEntry() const {
418 if (transient_entry_index_ != -1) 401 if (transient_entry_index_ != -1)
419 return entries_[transient_entry_index_].get(); 402 return entries_[transient_entry_index_].get();
420 if (pending_entry_) 403 if (pending_entry_)
421 return pending_entry_; 404 return pending_entry_;
422 return GetLastCommittedEntry(); 405 return GetLastCommittedEntry();
423 } 406 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 return; 492 return;
510 } 493 }
511 494
512 // Base the navigation on where we are now... 495 // Base the navigation on where we are now...
513 int current_index = GetCurrentEntryIndex(); 496 int current_index = GetCurrentEntryIndex();
514 497
515 DiscardNonCommittedEntries(); 498 DiscardNonCommittedEntries();
516 499
517 pending_entry_index_ = current_index - 1; 500 pending_entry_index_ = current_index - 1;
518 entries_[pending_entry_index_]->SetTransitionType( 501 entries_[pending_entry_index_]->SetTransitionType(
519 content::PageTransitionFromInt( 502 PageTransitionFromInt(
520 entries_[pending_entry_index_]->GetTransitionType() | 503 entries_[pending_entry_index_]->GetTransitionType() |
521 content::PAGE_TRANSITION_FORWARD_BACK)); 504 PAGE_TRANSITION_FORWARD_BACK));
522 NavigateToPendingEntry(NO_RELOAD); 505 NavigateToPendingEntry(NO_RELOAD);
523 } 506 }
524 507
525 void NavigationControllerImpl::GoForward() { 508 void NavigationControllerImpl::GoForward() {
526 if (!CanGoForward()) { 509 if (!CanGoForward()) {
527 NOTREACHED(); 510 NOTREACHED();
528 return; 511 return;
529 } 512 }
530 513
531 bool transient = (transient_entry_index_ != -1); 514 bool transient = (transient_entry_index_ != -1);
532 515
533 // Base the navigation on where we are now... 516 // Base the navigation on where we are now...
534 int current_index = GetCurrentEntryIndex(); 517 int current_index = GetCurrentEntryIndex();
535 518
536 DiscardNonCommittedEntries(); 519 DiscardNonCommittedEntries();
537 520
538 pending_entry_index_ = current_index; 521 pending_entry_index_ = current_index;
539 // If there was a transient entry, we removed it making the current index 522 // If there was a transient entry, we removed it making the current index
540 // the next page. 523 // the next page.
541 if (!transient) 524 if (!transient)
542 pending_entry_index_++; 525 pending_entry_index_++;
543 526
544 entries_[pending_entry_index_]->SetTransitionType( 527 entries_[pending_entry_index_]->SetTransitionType(
545 content::PageTransitionFromInt( 528 PageTransitionFromInt(
546 entries_[pending_entry_index_]->GetTransitionType() | 529 entries_[pending_entry_index_]->GetTransitionType() |
547 content::PAGE_TRANSITION_FORWARD_BACK)); 530 PAGE_TRANSITION_FORWARD_BACK));
548 NavigateToPendingEntry(NO_RELOAD); 531 NavigateToPendingEntry(NO_RELOAD);
549 } 532 }
550 533
551 void NavigationControllerImpl::GoToIndex(int index) { 534 void NavigationControllerImpl::GoToIndex(int index) {
552 if (index < 0 || index >= static_cast<int>(entries_.size())) { 535 if (index < 0 || index >= static_cast<int>(entries_.size())) {
553 NOTREACHED(); 536 NOTREACHED();
554 return; 537 return;
555 } 538 }
556 539
557 if (transient_entry_index_ != -1) { 540 if (transient_entry_index_ != -1) {
558 if (index == transient_entry_index_) { 541 if (index == transient_entry_index_) {
559 // Nothing to do when navigating to the transient. 542 // Nothing to do when navigating to the transient.
560 return; 543 return;
561 } 544 }
562 if (index > transient_entry_index_) { 545 if (index > transient_entry_index_) {
563 // Removing the transient is goint to shift all entries by 1. 546 // Removing the transient is goint to shift all entries by 1.
564 index--; 547 index--;
565 } 548 }
566 } 549 }
567 550
568 DiscardNonCommittedEntries(); 551 DiscardNonCommittedEntries();
569 552
570 pending_entry_index_ = index; 553 pending_entry_index_ = index;
571 entries_[pending_entry_index_]->SetTransitionType( 554 entries_[pending_entry_index_]->SetTransitionType(
572 content::PageTransitionFromInt( 555 PageTransitionFromInt(
573 entries_[pending_entry_index_]->GetTransitionType() | 556 entries_[pending_entry_index_]->GetTransitionType() |
574 content::PAGE_TRANSITION_FORWARD_BACK)); 557 PAGE_TRANSITION_FORWARD_BACK));
575 NavigateToPendingEntry(NO_RELOAD); 558 NavigateToPendingEntry(NO_RELOAD);
576 } 559 }
577 560
578 void NavigationControllerImpl::GoToOffset(int offset) { 561 void NavigationControllerImpl::GoToOffset(int offset) {
579 if (!CanGoToOffset(offset)) 562 if (!CanGoToOffset(offset))
580 return; 563 return;
581 564
582 GoToIndex(GetIndexForOffset(offset)); 565 GoToIndex(GetIndexForOffset(offset));
583 } 566 }
584 567
(...skipping 20 matching lines...) Expand all
605 index = last_committed_entry_index_ + 1; 588 index = last_committed_entry_index_ + 1;
606 DiscardTransientEntry(); 589 DiscardTransientEntry();
607 entries_.insert( 590 entries_.insert(
608 entries_.begin() + index, linked_ptr<NavigationEntryImpl>(entry)); 591 entries_.begin() + index, linked_ptr<NavigationEntryImpl>(entry));
609 transient_entry_index_ = index; 592 transient_entry_index_ = index;
610 web_contents_->NotifyNavigationStateChanged(kInvalidateAll); 593 web_contents_->NotifyNavigationStateChanged(kInvalidateAll);
611 } 594 }
612 595
613 void NavigationControllerImpl::LoadURL( 596 void NavigationControllerImpl::LoadURL(
614 const GURL& url, 597 const GURL& url,
615 const content::Referrer& referrer, 598 const Referrer& referrer,
616 content::PageTransition transition, 599 PageTransition transition,
617 const std::string& extra_headers) { 600 const std::string& extra_headers) {
618 LoadURLParams params(url); 601 LoadURLParams params(url);
619 params.referrer = referrer; 602 params.referrer = referrer;
620 params.transition_type = transition; 603 params.transition_type = transition;
621 params.extra_headers = extra_headers; 604 params.extra_headers = extra_headers;
622 LoadURLWithParams(params); 605 LoadURLWithParams(params);
623 } 606 }
624 607
625 void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) { 608 void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) {
626 if (content::HandleDebugURL(params.url, params.transition_type)) 609 if (HandleDebugURL(params.url, params.transition_type))
627 return; 610 return;
628 611
629 // Checks based on params.load_type. 612 // Checks based on params.load_type.
630 switch (params.load_type) { 613 switch (params.load_type) {
631 case LOAD_TYPE_DEFAULT: 614 case LOAD_TYPE_DEFAULT:
632 break; 615 break;
633 case LOAD_TYPE_BROWSER_INITIATED_HTTP_POST: 616 case LOAD_TYPE_BROWSER_INITIATED_HTTP_POST:
634 if (!params.url.SchemeIs(chrome::kHttpScheme) && 617 if (!params.url.SchemeIs(chrome::kHttpScheme) &&
635 !params.url.SchemeIs(chrome::kHttpsScheme)) { 618 !params.url.SchemeIs(chrome::kHttpsScheme)) {
636 NOTREACHED() << "Http post load must use http(s) scheme."; 619 NOTREACHED() << "Http post load must use http(s) scheme.";
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 682
700 LoadEntry(entry); 683 LoadEntry(entry);
701 } 684 }
702 685
703 void NavigationControllerImpl::DocumentLoadedInFrame() { 686 void NavigationControllerImpl::DocumentLoadedInFrame() {
704 is_initial_navigation_ = false; 687 is_initial_navigation_ = false;
705 } 688 }
706 689
707 bool NavigationControllerImpl::RendererDidNavigate( 690 bool NavigationControllerImpl::RendererDidNavigate(
708 const ViewHostMsg_FrameNavigate_Params& params, 691 const ViewHostMsg_FrameNavigate_Params& params,
709 content::LoadCommittedDetails* details) { 692 LoadCommittedDetails* details) {
710 693
711 // Save the previous state before we clobber it. 694 // Save the previous state before we clobber it.
712 if (GetLastCommittedEntry()) { 695 if (GetLastCommittedEntry()) {
713 details->previous_url = GetLastCommittedEntry()->GetURL(); 696 details->previous_url = GetLastCommittedEntry()->GetURL();
714 details->previous_entry_index = GetLastCommittedEntryIndex(); 697 details->previous_entry_index = GetLastCommittedEntryIndex();
715 } else { 698 } else {
716 details->previous_url = GURL(); 699 details->previous_url = GURL();
717 details->previous_entry_index = -1; 700 details->previous_entry_index = -1;
718 } 701 }
719 702
720 // If we have a pending entry at this point, it should have a SiteInstance. 703 // If we have a pending entry at this point, it should have a SiteInstance.
721 // Restored entries start out with a null SiteInstance, but we should have 704 // Restored entries start out with a null SiteInstance, but we should have
722 // assigned one in NavigateToPendingEntry. 705 // assigned one in NavigateToPendingEntry.
723 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); 706 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance());
724 707
725 // If we are doing a cross-site reload, we need to replace the existing 708 // If we are doing a cross-site reload, we need to replace the existing
726 // navigation entry, not add another entry to the history. This has the side 709 // navigation entry, not add another entry to the history. This has the side
727 // effect of removing forward browsing history, if such existed. 710 // effect of removing forward browsing history, if such existed.
728 details->did_replace_entry = 711 details->did_replace_entry =
729 pending_entry_ && pending_entry_->is_cross_site_reload(); 712 pending_entry_ && pending_entry_->is_cross_site_reload();
730 713
731 // is_in_page must be computed before the entry gets committed. 714 // is_in_page must be computed before the entry gets committed.
732 details->is_in_page = IsURLInPageNavigation( 715 details->is_in_page = IsURLInPageNavigation(
733 params.url, params.was_within_same_page); 716 params.url, params.was_within_same_page);
734 717
735 // Do navigation-type specific actions. These will make and commit an entry. 718 // Do navigation-type specific actions. These will make and commit an entry.
736 details->type = ClassifyNavigation(params); 719 details->type = ClassifyNavigation(params);
737 720
738 switch (details->type) { 721 switch (details->type) {
739 case content::NAVIGATION_TYPE_NEW_PAGE: 722 case NAVIGATION_TYPE_NEW_PAGE:
740 RendererDidNavigateToNewPage(params, details->did_replace_entry); 723 RendererDidNavigateToNewPage(params, details->did_replace_entry);
741 break; 724 break;
742 case content::NAVIGATION_TYPE_EXISTING_PAGE: 725 case NAVIGATION_TYPE_EXISTING_PAGE:
743 RendererDidNavigateToExistingPage(params); 726 RendererDidNavigateToExistingPage(params);
744 break; 727 break;
745 case content::NAVIGATION_TYPE_SAME_PAGE: 728 case NAVIGATION_TYPE_SAME_PAGE:
746 RendererDidNavigateToSamePage(params); 729 RendererDidNavigateToSamePage(params);
747 break; 730 break;
748 case content::NAVIGATION_TYPE_IN_PAGE: 731 case NAVIGATION_TYPE_IN_PAGE:
749 RendererDidNavigateInPage(params, &details->did_replace_entry); 732 RendererDidNavigateInPage(params, &details->did_replace_entry);
750 break; 733 break;
751 case content::NAVIGATION_TYPE_NEW_SUBFRAME: 734 case NAVIGATION_TYPE_NEW_SUBFRAME:
752 RendererDidNavigateNewSubframe(params); 735 RendererDidNavigateNewSubframe(params);
753 break; 736 break;
754 case content::NAVIGATION_TYPE_AUTO_SUBFRAME: 737 case NAVIGATION_TYPE_AUTO_SUBFRAME:
755 if (!RendererDidNavigateAutoSubframe(params)) 738 if (!RendererDidNavigateAutoSubframe(params))
756 return false; 739 return false;
757 break; 740 break;
758 case content::NAVIGATION_TYPE_NAV_IGNORE: 741 case NAVIGATION_TYPE_NAV_IGNORE:
759 // If a pending navigation was in progress, this canceled it. We should 742 // If a pending navigation was in progress, this canceled it. We should
760 // discard it and make sure it is removed from the URL bar. After that, 743 // discard it and make sure it is removed from the URL bar. After that,
761 // there is nothing we can do with this navigation, so we just return to 744 // there is nothing we can do with this navigation, so we just return to
762 // the caller that nothing has happened. 745 // the caller that nothing has happened.
763 if (pending_entry_) { 746 if (pending_entry_) {
764 DiscardNonCommittedEntries(); 747 DiscardNonCommittedEntries();
765 web_contents_->NotifyNavigationStateChanged( 748 web_contents_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
766 content::INVALIDATE_TYPE_URL);
767 } 749 }
768 return false; 750 return false;
769 default: 751 default:
770 NOTREACHED(); 752 NOTREACHED();
771 } 753 }
772 754
773 // At this point, we know that the navigation has just completed, so 755 // At this point, we know that the navigation has just completed, so
774 // record the time. 756 // record the time.
775 // 757 //
776 // TODO(akalin): Use "sane time" as described in 758 // TODO(akalin): Use "sane time" as described in
(...skipping 16 matching lines...) Expand all
793 // Once committed, we do not need to track if the entry was initiated by 775 // Once committed, we do not need to track if the entry was initiated by
794 // the renderer. 776 // the renderer.
795 active_entry->set_is_renderer_initiated(false); 777 active_entry->set_is_renderer_initiated(false);
796 778
797 // The active entry's SiteInstance should match our SiteInstance. 779 // The active entry's SiteInstance should match our SiteInstance.
798 DCHECK(active_entry->site_instance() == web_contents_->GetSiteInstance()); 780 DCHECK(active_entry->site_instance() == web_contents_->GetSiteInstance());
799 781
800 // Now prep the rest of the details for the notification and broadcast. 782 // Now prep the rest of the details for the notification and broadcast.
801 details->entry = active_entry; 783 details->entry = active_entry;
802 details->is_main_frame = 784 details->is_main_frame =
803 content::PageTransitionIsMainFrame(params.transition); 785 PageTransitionIsMainFrame(params.transition);
804 details->serialized_security_info = params.security_info; 786 details->serialized_security_info = params.security_info;
805 details->http_status_code = params.http_status_code; 787 details->http_status_code = params.http_status_code;
806 NotifyNavigationEntryCommitted(details); 788 NotifyNavigationEntryCommitted(details);
807 789
808 return true; 790 return true;
809 } 791 }
810 792
811 content::NavigationType NavigationControllerImpl::ClassifyNavigation( 793 NavigationType NavigationControllerImpl::ClassifyNavigation(
812 const ViewHostMsg_FrameNavigate_Params& params) const { 794 const ViewHostMsg_FrameNavigate_Params& params) const {
813 if (params.page_id == -1) { 795 if (params.page_id == -1) {
814 // The renderer generates the page IDs, and so if it gives us the invalid 796 // The renderer generates the page IDs, and so if it gives us the invalid
815 // page ID (-1) we know it didn't actually navigate. This happens in a few 797 // page ID (-1) we know it didn't actually navigate. This happens in a few
816 // cases: 798 // cases:
817 // 799 //
818 // - If a page makes a popup navigated to about blank, and then writes 800 // - If a page makes a popup navigated to about blank, and then writes
819 // stuff like a subframe navigated to a real page. We'll get the commit 801 // stuff like a subframe navigated to a real page. We'll get the commit
820 // for the subframe, but there won't be any commit for the outer page. 802 // for the subframe, but there won't be any commit for the outer page.
821 // 803 //
822 // - We were also getting these for failed loads (for example, bug 21849). 804 // - We were also getting these for failed loads (for example, bug 21849).
823 // The guess is that we get a "load commit" for the alternate error page, 805 // The guess is that we get a "load commit" for the alternate error page,
824 // but that doesn't affect the page ID, so we get the "old" one, which 806 // but that doesn't affect the page ID, so we get the "old" one, which
825 // could be invalid. This can also happen for a cross-site transition 807 // could be invalid. This can also happen for a cross-site transition
826 // that causes us to swap processes. Then the error page load will be in 808 // that causes us to swap processes. Then the error page load will be in
827 // a new process with no page IDs ever assigned (and hence a -1 value), 809 // a new process with no page IDs ever assigned (and hence a -1 value),
828 // yet the navigation controller still might have previous pages in its 810 // yet the navigation controller still might have previous pages in its
829 // list. 811 // list.
830 // 812 //
831 // In these cases, there's nothing we can do with them, so ignore. 813 // In these cases, there's nothing we can do with them, so ignore.
832 return content::NAVIGATION_TYPE_NAV_IGNORE; 814 return NAVIGATION_TYPE_NAV_IGNORE;
833 } 815 }
834 816
835 if (params.page_id > web_contents_->GetMaxPageID()) { 817 if (params.page_id > web_contents_->GetMaxPageID()) {
836 // Greater page IDs than we've ever seen before are new pages. We may or may 818 // Greater page IDs than we've ever seen before are new pages. We may or may
837 // not have a pending entry for the page, and this may or may not be the 819 // not have a pending entry for the page, and this may or may not be the
838 // main frame. 820 // main frame.
839 if (content::PageTransitionIsMainFrame(params.transition)) 821 if (PageTransitionIsMainFrame(params.transition))
840 return content::NAVIGATION_TYPE_NEW_PAGE; 822 return NAVIGATION_TYPE_NEW_PAGE;
841 823
842 // When this is a new subframe navigation, we should have a committed page 824 // When this is a new subframe navigation, we should have a committed page
843 // for which it's a suframe in. This may not be the case when an iframe is 825 // for which it's a suframe in. This may not be the case when an iframe is
844 // navigated on a popup navigated to about:blank (the iframe would be 826 // navigated on a popup navigated to about:blank (the iframe would be
845 // written into the popup by script on the main page). For these cases, 827 // written into the popup by script on the main page). For these cases,
846 // there isn't any navigation stuff we can do, so just ignore it. 828 // there isn't any navigation stuff we can do, so just ignore it.
847 if (!GetLastCommittedEntry()) 829 if (!GetLastCommittedEntry())
848 return content::NAVIGATION_TYPE_NAV_IGNORE; 830 return NAVIGATION_TYPE_NAV_IGNORE;
849 831
850 // Valid subframe navigation. 832 // Valid subframe navigation.
851 return content::NAVIGATION_TYPE_NEW_SUBFRAME; 833 return NAVIGATION_TYPE_NEW_SUBFRAME;
852 } 834 }
853 835
854 // Now we know that the notification is for an existing page. Find that entry. 836 // Now we know that the notification is for an existing page. Find that entry.
855 int existing_entry_index = GetEntryIndexWithPageID( 837 int existing_entry_index = GetEntryIndexWithPageID(
856 web_contents_->GetSiteInstance(), 838 web_contents_->GetSiteInstance(),
857 params.page_id); 839 params.page_id);
858 if (existing_entry_index == -1) { 840 if (existing_entry_index == -1) {
859 // The page was not found. It could have been pruned because of the limit on 841 // The page was not found. It could have been pruned because of the limit on
860 // back/forward entries (not likely since we'll usually tell it to navigate 842 // back/forward entries (not likely since we'll usually tell it to navigate
861 // to such entries). It could also mean that the renderer is smoking crack. 843 // to such entries). It could also mean that the renderer is smoking crack.
862 NOTREACHED(); 844 NOTREACHED();
863 845
864 // Because the unknown entry has committed, we risk showing the wrong URL in 846 // Because the unknown entry has committed, we risk showing the wrong URL in
865 // release builds. Instead, we'll kill the renderer process to be safe. 847 // release builds. Instead, we'll kill the renderer process to be safe.
866 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url; 848 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url;
867 content::RecordAction(UserMetricsAction("BadMessageTerminate_NC")); 849 RecordAction(UserMetricsAction("BadMessageTerminate_NC"));
868 850
869 // Temporary code so we can get more information. Format: 851 // Temporary code so we can get more information. Format:
870 // http://url/foo.html#page1#max3#frame1#ids:2_Nx,1_1x,3_2 852 // http://url/foo.html#page1#max3#frame1#ids:2_Nx,1_1x,3_2
871 std::string temp = params.url.spec(); 853 std::string temp = params.url.spec();
872 temp.append("#page"); 854 temp.append("#page");
873 temp.append(base::IntToString(params.page_id)); 855 temp.append(base::IntToString(params.page_id));
874 temp.append("#max"); 856 temp.append("#max");
875 temp.append(base::IntToString(web_contents_->GetMaxPageID())); 857 temp.append(base::IntToString(web_contents_->GetMaxPageID()));
876 temp.append("#frame"); 858 temp.append("#frame");
877 temp.append(base::IntToString(params.frame_id)); 859 temp.append(base::IntToString(params.frame_id));
(...skipping 10 matching lines...) Expand all
888 else 870 else
889 temp.append("N"); 871 temp.append("N");
890 if (entries_[i]->site_instance() != web_contents_->GetSiteInstance()) 872 if (entries_[i]->site_instance() != web_contents_->GetSiteInstance())
891 temp.append("x"); 873 temp.append("x");
892 temp.append(","); 874 temp.append(",");
893 } 875 }
894 GURL url(temp); 876 GURL url(temp);
895 static_cast<RenderViewHostImpl*>( 877 static_cast<RenderViewHostImpl*>(
896 web_contents_->GetRenderViewHost())->Send( 878 web_contents_->GetRenderViewHost())->Send(
897 new ViewMsg_TempCrashWithData(url)); 879 new ViewMsg_TempCrashWithData(url));
898 return content::NAVIGATION_TYPE_NAV_IGNORE; 880 return NAVIGATION_TYPE_NAV_IGNORE;
899 } 881 }
900 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); 882 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get();
901 883
902 if (!content::PageTransitionIsMainFrame(params.transition)) { 884 if (!PageTransitionIsMainFrame(params.transition)) {
903 // All manual subframes would get new IDs and were handled above, so we 885 // All manual subframes would get new IDs and were handled above, so we
904 // know this is auto. Since the current page was found in the navigation 886 // know this is auto. Since the current page was found in the navigation
905 // entry list, we're guaranteed to have a last committed entry. 887 // entry list, we're guaranteed to have a last committed entry.
906 DCHECK(GetLastCommittedEntry()); 888 DCHECK(GetLastCommittedEntry());
907 return content::NAVIGATION_TYPE_AUTO_SUBFRAME; 889 return NAVIGATION_TYPE_AUTO_SUBFRAME;
908 } 890 }
909 891
910 // Anything below here we know is a main frame navigation. 892 // Anything below here we know is a main frame navigation.
911 if (pending_entry_ && 893 if (pending_entry_ &&
912 existing_entry != pending_entry_ && 894 existing_entry != pending_entry_ &&
913 pending_entry_->GetPageID() == -1 && 895 pending_entry_->GetPageID() == -1 &&
914 existing_entry == GetLastCommittedEntry()) { 896 existing_entry == GetLastCommittedEntry()) {
915 // In this case, we have a pending entry for a URL but WebCore didn't do a 897 // In this case, we have a pending entry for a URL but WebCore didn't do a
916 // new navigation. This happens when you press enter in the URL bar to 898 // new navigation. This happens when you press enter in the URL bar to
917 // reload. We will create a pending entry, but WebKit will convert it to 899 // reload. We will create a pending entry, but WebKit will convert it to
918 // a reload since it's the same page and not create a new entry for it 900 // a reload since it's the same page and not create a new entry for it
919 // (the user doesn't want to have a new back/forward entry when they do 901 // (the user doesn't want to have a new back/forward entry when they do
920 // this). If this matches the last committed entry, we want to just ignore 902 // this). If this matches the last committed entry, we want to just ignore
921 // the pending entry and go back to where we were (the "existing entry"). 903 // the pending entry and go back to where we were (the "existing entry").
922 return content::NAVIGATION_TYPE_SAME_PAGE; 904 return NAVIGATION_TYPE_SAME_PAGE;
923 } 905 }
924 906
925 // Any toplevel navigations with the same base (minus the reference fragment) 907 // Any toplevel navigations with the same base (minus the reference fragment)
926 // are in-page navigations. We weeded out subframe navigations above. Most of 908 // are in-page navigations. We weeded out subframe navigations above. Most of
927 // the time this doesn't matter since WebKit doesn't tell us about subframe 909 // the time this doesn't matter since WebKit doesn't tell us about subframe
928 // navigations that don't actually navigate, but it can happen when there is 910 // navigations that don't actually navigate, but it can happen when there is
929 // an encoding override (it always sends a navigation request). 911 // an encoding override (it always sends a navigation request).
930 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url, 912 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
931 params.was_within_same_page)) { 913 params.was_within_same_page)) {
932 return content::NAVIGATION_TYPE_IN_PAGE; 914 return NAVIGATION_TYPE_IN_PAGE;
933 } 915 }
934 916
935 // Since we weeded out "new" navigations above, we know this is an existing 917 // Since we weeded out "new" navigations above, we know this is an existing
936 // (back/forward) navigation. 918 // (back/forward) navigation.
937 return content::NAVIGATION_TYPE_EXISTING_PAGE; 919 return NAVIGATION_TYPE_EXISTING_PAGE;
938 } 920 }
939 921
940 bool NavigationControllerImpl::IsRedirect( 922 bool NavigationControllerImpl::IsRedirect(
941 const ViewHostMsg_FrameNavigate_Params& params) { 923 const ViewHostMsg_FrameNavigate_Params& params) {
942 // For main frame transition, we judge by params.transition. 924 // For main frame transition, we judge by params.transition.
943 // Otherwise, by params.redirects. 925 // Otherwise, by params.redirects.
944 if (content::PageTransitionIsMainFrame(params.transition)) { 926 if (PageTransitionIsMainFrame(params.transition)) {
945 return content::PageTransitionIsRedirect(params.transition); 927 return PageTransitionIsRedirect(params.transition);
946 } 928 }
947 return params.redirects.size() > 1; 929 return params.redirects.size() > 1;
948 } 930 }
949 931
950 void NavigationControllerImpl::RendererDidNavigateToNewPage( 932 void NavigationControllerImpl::RendererDidNavigateToNewPage(
951 const ViewHostMsg_FrameNavigate_Params& params, bool replace_entry) { 933 const ViewHostMsg_FrameNavigate_Params& params, bool replace_entry) {
952 NavigationEntryImpl* new_entry; 934 NavigationEntryImpl* new_entry;
953 bool update_virtual_url; 935 bool update_virtual_url;
954 if (pending_entry_) { 936 if (pending_entry_) {
955 // TODO(brettw) this assumes that the pending entry is appropriate for the 937 // TODO(brettw) this assumes that the pending entry is appropriate for the
956 // new page that was just loaded. I don't think this is necessarily the 938 // new page that was just loaded. I don't think this is necessarily the
957 // case! We should have some more tracking to know for sure. 939 // case! We should have some more tracking to know for sure.
958 new_entry = new NavigationEntryImpl(*pending_entry_); 940 new_entry = new NavigationEntryImpl(*pending_entry_);
959 941
960 // Don't use the page type from the pending entry. Some interstitial page 942 // Don't use the page type from the pending entry. Some interstitial page
961 // may have set the type to interstitial. Once we commit, however, the page 943 // may have set the type to interstitial. Once we commit, however, the page
962 // type must always be normal. 944 // type must always be normal.
963 new_entry->set_page_type(content::PAGE_TYPE_NORMAL); 945 new_entry->set_page_type(PAGE_TYPE_NORMAL);
964 update_virtual_url = new_entry->update_virtual_url_with_url(); 946 update_virtual_url = new_entry->update_virtual_url_with_url();
965 } else { 947 } else {
966 new_entry = new NavigationEntryImpl; 948 new_entry = new NavigationEntryImpl;
967 949
968 // Find out whether the new entry needs to update its virtual URL on URL 950 // Find out whether the new entry needs to update its virtual URL on URL
969 // change and set up the entry accordingly. This is needed to correctly 951 // change and set up the entry accordingly. This is needed to correctly
970 // update the virtual URL when replaceState is called after a pushState. 952 // update the virtual URL when replaceState is called after a pushState.
971 GURL url = params.url; 953 GURL url = params.url;
972 bool needs_update = false; 954 bool needs_update = false;
973 BrowserURLHandlerImpl::GetInstance()->RewriteURLIfNecessary( 955 BrowserURLHandlerImpl::GetInstance()->RewriteURLIfNecessary(
(...skipping 19 matching lines...) Expand all
993 new_entry->SetPostID(params.post_id); 975 new_entry->SetPostID(params.post_id);
994 new_entry->SetOriginalRequestURL(params.original_request_url); 976 new_entry->SetOriginalRequestURL(params.original_request_url);
995 new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); 977 new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent);
996 978
997 InsertOrReplaceEntry(new_entry, replace_entry); 979 InsertOrReplaceEntry(new_entry, replace_entry);
998 } 980 }
999 981
1000 void NavigationControllerImpl::RendererDidNavigateToExistingPage( 982 void NavigationControllerImpl::RendererDidNavigateToExistingPage(
1001 const ViewHostMsg_FrameNavigate_Params& params) { 983 const ViewHostMsg_FrameNavigate_Params& params) {
1002 // We should only get here for main frame navigations. 984 // We should only get here for main frame navigations.
1003 DCHECK(content::PageTransitionIsMainFrame(params.transition)); 985 DCHECK(PageTransitionIsMainFrame(params.transition));
1004 986
1005 // This is a back/forward navigation. The existing page for the ID is 987 // This is a back/forward navigation. The existing page for the ID is
1006 // guaranteed to exist by ClassifyNavigation, and we just need to update it 988 // guaranteed to exist by ClassifyNavigation, and we just need to update it
1007 // with new information from the renderer. 989 // with new information from the renderer.
1008 int entry_index = GetEntryIndexWithPageID(web_contents_->GetSiteInstance(), 990 int entry_index = GetEntryIndexWithPageID(web_contents_->GetSiteInstance(),
1009 params.page_id); 991 params.page_id);
1010 DCHECK(entry_index >= 0 && 992 DCHECK(entry_index >= 0 &&
1011 entry_index < static_cast<int>(entries_.size())); 993 entry_index < static_cast<int>(entries_.size()));
1012 NavigationEntryImpl* entry = entries_[entry_index].get(); 994 NavigationEntryImpl* entry = entries_[entry_index].get();
1013 995
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 // The URL may have changed due to redirects. 1041 // The URL may have changed due to redirects.
1060 if (existing_entry->update_virtual_url_with_url()) 1042 if (existing_entry->update_virtual_url_with_url())
1061 UpdateVirtualURLToURL(existing_entry, params.url); 1043 UpdateVirtualURLToURL(existing_entry, params.url);
1062 existing_entry->SetURL(params.url); 1044 existing_entry->SetURL(params.url);
1063 1045
1064 DiscardNonCommittedEntries(); 1046 DiscardNonCommittedEntries();
1065 } 1047 }
1066 1048
1067 void NavigationControllerImpl::RendererDidNavigateInPage( 1049 void NavigationControllerImpl::RendererDidNavigateInPage(
1068 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { 1050 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) {
1069 DCHECK(content::PageTransitionIsMainFrame(params.transition)) << 1051 DCHECK(PageTransitionIsMainFrame(params.transition)) <<
1070 "WebKit should only tell us about in-page navs for the main frame."; 1052 "WebKit should only tell us about in-page navs for the main frame.";
1071 // We're guaranteed to have an entry for this one. 1053 // We're guaranteed to have an entry for this one.
1072 NavigationEntryImpl* existing_entry = GetEntryWithPageID( 1054 NavigationEntryImpl* existing_entry = GetEntryWithPageID(
1073 web_contents_->GetSiteInstance(), params.page_id); 1055 web_contents_->GetSiteInstance(), params.page_id);
1074 1056
1075 // Reference fragment navigation. We're guaranteed to have the last_committed 1057 // Reference fragment navigation. We're guaranteed to have the last_committed
1076 // entry and it will be the same page as the new navigation (minus the 1058 // entry and it will be the same page as the new navigation (minus the
1077 // reference fragments, of course). We'll update the URL of the existing 1059 // reference fragments, of course). We'll update the URL of the existing
1078 // entry without pruning the forward history. 1060 // entry without pruning the forward history.
1079 existing_entry->SetURL(params.url); 1061 existing_entry->SetURL(params.url);
1080 if (existing_entry->update_virtual_url_with_url()) 1062 if (existing_entry->update_virtual_url_with_url())
1081 UpdateVirtualURLToURL(existing_entry, params.url); 1063 UpdateVirtualURLToURL(existing_entry, params.url);
1082 1064
1083 // This replaces the existing entry since the page ID didn't change. 1065 // This replaces the existing entry since the page ID didn't change.
1084 *did_replace_entry = true; 1066 *did_replace_entry = true;
1085 1067
1086 if (pending_entry_) 1068 if (pending_entry_)
1087 DiscardNonCommittedEntriesInternal(); 1069 DiscardNonCommittedEntriesInternal();
1088 1070
1089 // If a transient entry was removed, the indices might have changed, so we 1071 // If a transient entry was removed, the indices might have changed, so we
1090 // have to query the entry index again. 1072 // have to query the entry index again.
1091 last_committed_entry_index_ = 1073 last_committed_entry_index_ =
1092 GetEntryIndexWithPageID(web_contents_->GetSiteInstance(), params.page_id); 1074 GetEntryIndexWithPageID(web_contents_->GetSiteInstance(), params.page_id);
1093 } 1075 }
1094 1076
1095 void NavigationControllerImpl::RendererDidNavigateNewSubframe( 1077 void NavigationControllerImpl::RendererDidNavigateNewSubframe(
1096 const ViewHostMsg_FrameNavigate_Params& params) { 1078 const ViewHostMsg_FrameNavigate_Params& params) {
1097 if (content::PageTransitionStripQualifier(params.transition) == 1079 if (PageTransitionStripQualifier(params.transition) ==
1098 content::PAGE_TRANSITION_AUTO_SUBFRAME) { 1080 PAGE_TRANSITION_AUTO_SUBFRAME) {
1099 // This is not user-initiated. Ignore. 1081 // This is not user-initiated. Ignore.
1100 return; 1082 return;
1101 } 1083 }
1102 1084
1103 // Manual subframe navigations just get the current entry cloned so the user 1085 // Manual subframe navigations just get the current entry cloned so the user
1104 // can go back or forward to it. The actual subframe information will be 1086 // can go back or forward to it. The actual subframe information will be
1105 // stored in the page state for each of those entries. This happens out of 1087 // stored in the page state for each of those entries. This happens out of
1106 // band with the actual navigations. 1088 // band with the actual navigations.
1107 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " 1089 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee "
1108 << "that a last committed entry exists."; 1090 << "that a last committed entry exists.";
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 // Normally the interstitial page hides itself if the user doesn't proceeed. 1273 // Normally the interstitial page hides itself if the user doesn't proceeed.
1292 // This would result in showing a NavigationEntry we just removed. Set this 1274 // This would result in showing a NavigationEntry we just removed. Set this
1293 // so the interstitial triggers a reload if the user doesn't proceed. 1275 // so the interstitial triggers a reload if the user doesn't proceed.
1294 static_cast<InterstitialPageImpl*>(web_contents_->GetInterstitialPage())-> 1276 static_cast<InterstitialPageImpl*>(web_contents_->GetInterstitialPage())->
1295 set_reload_on_dont_proceed(true); 1277 set_reload_on_dont_proceed(true);
1296 } 1278 }
1297 } 1279 }
1298 1280
1299 void NavigationControllerImpl::SetSessionStorageNamespace( 1281 void NavigationControllerImpl::SetSessionStorageNamespace(
1300 const std::string& partition_id, 1282 const std::string& partition_id,
1301 content::SessionStorageNamespace* session_storage_namespace) { 1283 SessionStorageNamespace* session_storage_namespace) {
1302 if (!session_storage_namespace) 1284 if (!session_storage_namespace)
1303 return; 1285 return;
1304 1286
1305 // We can't overwrite an existing SessionStorage without violating spec. 1287 // We can't overwrite an existing SessionStorage without violating spec.
1306 // Attempts to do so may give a tab access to another tab's session storage 1288 // Attempts to do so may give a tab access to another tab's session storage
1307 // so die hard on an error. 1289 // so die hard on an error.
1308 bool successful_insert = session_storage_namespace_map_.insert( 1290 bool successful_insert = session_storage_namespace_map_.insert(
1309 make_pair(partition_id, 1291 make_pair(partition_id,
1310 static_cast<SessionStorageNamespaceImpl*>( 1292 static_cast<SessionStorageNamespaceImpl*>(
1311 session_storage_namespace))) 1293 session_storage_namespace)))
1312 .second; 1294 .second;
1313 CHECK(successful_insert) << "Cannot replace existing SessionStorageNamespace"; 1295 CHECK(successful_insert) << "Cannot replace existing SessionStorageNamespace";
1314 } 1296 }
1315 1297
1316 void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) { 1298 void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) {
1317 max_restored_page_id_ = max_id; 1299 max_restored_page_id_ = max_id;
1318 } 1300 }
1319 1301
1320 int32 NavigationControllerImpl::GetMaxRestoredPageID() const { 1302 int32 NavigationControllerImpl::GetMaxRestoredPageID() const {
1321 return max_restored_page_id_; 1303 return max_restored_page_id_;
1322 } 1304 }
1323 1305
1324 SessionStorageNamespace* 1306 SessionStorageNamespace*
1325 NavigationControllerImpl::GetSessionStorageNamespace( 1307 NavigationControllerImpl::GetSessionStorageNamespace(SiteInstance* instance) {
1326 content::SiteInstance* instance) {
1327 std::string partition_id; 1308 std::string partition_id;
1328 if (instance) { 1309 if (instance) {
1329 // TODO(ajwong): When GetDefaultSessionStorageNamespace() goes away, remove 1310 // TODO(ajwong): When GetDefaultSessionStorageNamespace() goes away, remove
1330 // this if statement so |instance| must not be NULL. 1311 // this if statement so |instance| must not be NULL.
1331 partition_id = 1312 partition_id =
1332 GetContentClient()->browser()->GetStoragePartitionIdForSite( 1313 GetContentClient()->browser()->GetStoragePartitionIdForSite(
1333 browser_context_, instance->GetSiteURL()); 1314 browser_context_, instance->GetSiteURL());
1334 } 1315 }
1335 1316
1336 SessionStorageNamespaceMap::const_iterator it = 1317 SessionStorageNamespaceMap::const_iterator it =
1337 session_storage_namespace_map_.find(partition_id); 1318 session_storage_namespace_map_.find(partition_id);
1338 if (it != session_storage_namespace_map_.end()) 1319 if (it != session_storage_namespace_map_.end())
1339 return it->second.get(); 1320 return it->second.get();
1340 1321
1341 // Create one if no one has accessed session storage for this partition yet. 1322 // Create one if no one has accessed session storage for this partition yet.
1342 // 1323 //
1343 // TODO(ajwong): Should this use the |partition_id| directly rather than 1324 // TODO(ajwong): Should this use the |partition_id| directly rather than
1344 // re-lookup via |instance|? http://crbug.com/142685 1325 // re-lookup via |instance|? http://crbug.com/142685
1345 content::StoragePartition* partition = 1326 StoragePartition* partition =
1346 BrowserContext::GetStoragePartition(browser_context_, instance); 1327 BrowserContext::GetStoragePartition(browser_context_, instance);
1347 SessionStorageNamespaceImpl* session_storage_namespace = 1328 SessionStorageNamespaceImpl* session_storage_namespace =
1348 new SessionStorageNamespaceImpl( 1329 new SessionStorageNamespaceImpl(
1349 static_cast<DOMStorageContextImpl*>( 1330 static_cast<DOMStorageContextImpl*>(
1350 partition->GetDOMStorageContext())); 1331 partition->GetDOMStorageContext()));
1351 session_storage_namespace_map_[partition_id] = session_storage_namespace; 1332 session_storage_namespace_map_[partition_id] = session_storage_namespace;
1352 1333
1353 return session_storage_namespace; 1334 return session_storage_namespace;
1354 } 1335 }
1355 1336
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 NavigationEntry* NavigationControllerImpl::GetPendingEntry() const { 1374 NavigationEntry* NavigationControllerImpl::GetPendingEntry() const {
1394 return pending_entry_; 1375 return pending_entry_;
1395 } 1376 }
1396 1377
1397 int NavigationControllerImpl::GetPendingEntryIndex() const { 1378 int NavigationControllerImpl::GetPendingEntryIndex() const {
1398 return pending_entry_index_; 1379 return pending_entry_index_;
1399 } 1380 }
1400 1381
1401 void NavigationControllerImpl::InsertOrReplaceEntry(NavigationEntryImpl* entry, 1382 void NavigationControllerImpl::InsertOrReplaceEntry(NavigationEntryImpl* entry,
1402 bool replace) { 1383 bool replace) {
1403 DCHECK(entry->GetTransitionType() != content::PAGE_TRANSITION_AUTO_SUBFRAME); 1384 DCHECK(entry->GetTransitionType() != PAGE_TRANSITION_AUTO_SUBFRAME);
1404 1385
1405 // Copy the pending entry's unique ID to the committed entry. 1386 // Copy the pending entry's unique ID to the committed entry.
1406 // I don't know if pending_entry_index_ can be other than -1 here. 1387 // I don't know if pending_entry_index_ can be other than -1 here.
1407 const NavigationEntryImpl* const pending_entry = 1388 const NavigationEntryImpl* const pending_entry =
1408 (pending_entry_index_ == -1) ? 1389 (pending_entry_index_ == -1) ?
1409 pending_entry_ : entries_[pending_entry_index_].get(); 1390 pending_entry_ : entries_[pending_entry_index_].get();
1410 if (pending_entry) 1391 if (pending_entry)
1411 entry->set_unique_id(pending_entry->GetUniqueID()); 1392 entry->set_unique_id(pending_entry->GetUniqueID());
1412 1393
1413 DiscardNonCommittedEntriesInternal(); 1394 DiscardNonCommittedEntriesInternal();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 // a session history navigation to the last committed page, RenderViewHost 1439 // a session history navigation to the last committed page, RenderViewHost
1459 // will force the throbber to start, but WebKit will essentially ignore the 1440 // will force the throbber to start, but WebKit will essentially ignore the
1460 // navigation, and won't send a message to stop the throbber. To prevent this 1441 // navigation, and won't send a message to stop the throbber. To prevent this
1461 // from happening, we drop the navigation here and stop the slow-to-commit 1442 // from happening, we drop the navigation here and stop the slow-to-commit
1462 // page from loading (which would normally happen during the navigation). 1443 // page from loading (which would normally happen during the navigation).
1463 if (pending_entry_index_ != -1 && 1444 if (pending_entry_index_ != -1 &&
1464 pending_entry_index_ == last_committed_entry_index_ && 1445 pending_entry_index_ == last_committed_entry_index_ &&
1465 (entries_[pending_entry_index_]->restore_type() == 1446 (entries_[pending_entry_index_]->restore_type() ==
1466 NavigationEntryImpl::RESTORE_NONE) && 1447 NavigationEntryImpl::RESTORE_NONE) &&
1467 (entries_[pending_entry_index_]->GetTransitionType() & 1448 (entries_[pending_entry_index_]->GetTransitionType() &
1468 content::PAGE_TRANSITION_FORWARD_BACK)) { 1449 PAGE_TRANSITION_FORWARD_BACK)) {
1469 web_contents_->Stop(); 1450 web_contents_->Stop();
1470 1451
1471 // If an interstitial page is showing, we want to close it to get back 1452 // If an interstitial page is showing, we want to close it to get back
1472 // to what was showing before. 1453 // to what was showing before.
1473 if (web_contents_->GetInterstitialPage()) 1454 if (web_contents_->GetInterstitialPage())
1474 web_contents_->GetInterstitialPage()->DontProceed(); 1455 web_contents_->GetInterstitialPage()->DontProceed();
1475 1456
1476 DiscardNonCommittedEntries(); 1457 DiscardNonCommittedEntries();
1477 return; 1458 return;
1478 } 1459 }
(...skipping 22 matching lines...) Expand all
1501 // navigations to restored entries in WebContentsImpl::OnGoToEntryAtOffset. 1482 // navigations to restored entries in WebContentsImpl::OnGoToEntryAtOffset.
1502 if (pending_entry_ && !pending_entry_->site_instance() && 1483 if (pending_entry_ && !pending_entry_->site_instance() &&
1503 pending_entry_->restore_type() != NavigationEntryImpl::RESTORE_NONE) { 1484 pending_entry_->restore_type() != NavigationEntryImpl::RESTORE_NONE) {
1504 pending_entry_->set_site_instance(static_cast<SiteInstanceImpl*>( 1485 pending_entry_->set_site_instance(static_cast<SiteInstanceImpl*>(
1505 web_contents_->GetPendingSiteInstance())); 1486 web_contents_->GetPendingSiteInstance()));
1506 pending_entry_->set_restore_type(NavigationEntryImpl::RESTORE_NONE); 1487 pending_entry_->set_restore_type(NavigationEntryImpl::RESTORE_NONE);
1507 } 1488 }
1508 } 1489 }
1509 1490
1510 void NavigationControllerImpl::NotifyNavigationEntryCommitted( 1491 void NavigationControllerImpl::NotifyNavigationEntryCommitted(
1511 content::LoadCommittedDetails* details) { 1492 LoadCommittedDetails* details) {
1512 details->entry = GetActiveEntry(); 1493 details->entry = GetActiveEntry();
1513 content::NotificationDetails notification_details = 1494 NotificationDetails notification_details =
1514 content::Details<content::LoadCommittedDetails>(details); 1495 Details<LoadCommittedDetails>(details);
1515 1496
1516 // We need to notify the ssl_manager_ before the web_contents_ so the 1497 // We need to notify the ssl_manager_ before the web_contents_ so the
1517 // location bar will have up-to-date information about the security style 1498 // location bar will have up-to-date information about the security style
1518 // when it wants to draw. See http://crbug.com/11157 1499 // when it wants to draw. See http://crbug.com/11157
1519 ssl_manager_.DidCommitProvisionalLoad(notification_details); 1500 ssl_manager_.DidCommitProvisionalLoad(notification_details);
1520 1501
1521 // TODO(pkasting): http://b/1113079 Probably these explicit notification paths 1502 // TODO(pkasting): http://b/1113079 Probably these explicit notification paths
1522 // should be removed, and interested parties should just listen for the 1503 // should be removed, and interested parties should just listen for the
1523 // notification below instead. 1504 // notification below instead.
1524 web_contents_->NotifyNavigationStateChanged(kInvalidateAll); 1505 web_contents_->NotifyNavigationStateChanged(kInvalidateAll);
1525 1506
1526 content::NotificationService::current()->Notify( 1507 NotificationService::current()->Notify(
1527 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 1508 NOTIFICATION_NAV_ENTRY_COMMITTED,
1528 content::Source<NavigationController>(this), 1509 Source<NavigationController>(this),
1529 notification_details); 1510 notification_details);
1530 } 1511 }
1531 1512
1532 // static 1513 // static
1533 size_t NavigationControllerImpl::max_entry_count() { 1514 size_t NavigationControllerImpl::max_entry_count() {
1534 if (max_entry_count_for_testing_ != kMaxEntryCountForTestingNotSet) 1515 if (max_entry_count_for_testing_ != kMaxEntryCountForTestingNotSet)
1535 return max_entry_count_for_testing_; 1516 return max_entry_count_for_testing_;
1536 return content::kMaxSessionHistoryEntries; 1517 return kMaxSessionHistoryEntries;
1537 } 1518 }
1538 1519
1539 void NavigationControllerImpl::SetActive(bool is_active) { 1520 void NavigationControllerImpl::SetActive(bool is_active) {
1540 if (is_active && needs_reload_) 1521 if (is_active && needs_reload_)
1541 LoadIfNecessary(); 1522 LoadIfNecessary();
1542 } 1523 }
1543 1524
1544 void NavigationControllerImpl::LoadIfNecessary() { 1525 void NavigationControllerImpl::LoadIfNecessary() {
1545 if (!needs_reload_) 1526 if (!needs_reload_)
1546 return; 1527 return;
1547 1528
1548 // Calling Reload() results in ignoring state, and not loading. 1529 // Calling Reload() results in ignoring state, and not loading.
1549 // Explicitly use NavigateToPendingEntry so that the renderer uses the 1530 // Explicitly use NavigateToPendingEntry so that the renderer uses the
1550 // cached state. 1531 // cached state.
1551 pending_entry_index_ = last_committed_entry_index_; 1532 pending_entry_index_ = last_committed_entry_index_;
1552 NavigateToPendingEntry(NO_RELOAD); 1533 NavigateToPendingEntry(NO_RELOAD);
1553 } 1534 }
1554 1535
1555 void NavigationControllerImpl::NotifyEntryChanged(const NavigationEntry* entry, 1536 void NavigationControllerImpl::NotifyEntryChanged(const NavigationEntry* entry,
1556 int index) { 1537 int index) {
1557 content::EntryChangedDetails det; 1538 EntryChangedDetails det;
1558 det.changed_entry = entry; 1539 det.changed_entry = entry;
1559 det.index = index; 1540 det.index = index;
1560 content::NotificationService::current()->Notify( 1541 NotificationService::current()->Notify(
1561 content::NOTIFICATION_NAV_ENTRY_CHANGED, 1542 NOTIFICATION_NAV_ENTRY_CHANGED,
1562 content::Source<NavigationController>(this), 1543 Source<NavigationController>(this),
1563 content::Details<content::EntryChangedDetails>(&det)); 1544 Details<EntryChangedDetails>(&det));
1564 } 1545 }
1565 1546
1566 void NavigationControllerImpl::FinishRestore(int selected_index, 1547 void NavigationControllerImpl::FinishRestore(int selected_index,
1567 RestoreType type) { 1548 RestoreType type) {
1568 DCHECK(selected_index >= 0 && selected_index < GetEntryCount()); 1549 DCHECK(selected_index >= 0 && selected_index < GetEntryCount());
1569 ConfigureEntriesForRestore(&entries_, type); 1550 ConfigureEntriesForRestore(&entries_, type);
1570 1551
1571 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount())); 1552 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount()));
1572 1553
1573 last_committed_entry_index_ = selected_index; 1554 last_committed_entry_index_ = selected_index;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 } 1589 }
1609 1590
1610 void NavigationControllerImpl::InsertEntriesFrom( 1591 void NavigationControllerImpl::InsertEntriesFrom(
1611 const NavigationControllerImpl& source, 1592 const NavigationControllerImpl& source,
1612 int max_index) { 1593 int max_index) {
1613 DCHECK_LE(max_index, source.GetEntryCount()); 1594 DCHECK_LE(max_index, source.GetEntryCount());
1614 size_t insert_index = 0; 1595 size_t insert_index = 0;
1615 for (int i = 0; i < max_index; i++) { 1596 for (int i = 0; i < max_index; i++) {
1616 // When cloning a tab, copy all entries except interstitial pages 1597 // When cloning a tab, copy all entries except interstitial pages
1617 if (source.entries_[i].get()->GetPageType() != 1598 if (source.entries_[i].get()->GetPageType() !=
1618 content::PAGE_TYPE_INTERSTITIAL) { 1599 PAGE_TYPE_INTERSTITIAL) {
1619 entries_.insert(entries_.begin() + insert_index++, 1600 entries_.insert(entries_.begin() + insert_index++,
1620 linked_ptr<NavigationEntryImpl>( 1601 linked_ptr<NavigationEntryImpl>(
1621 new NavigationEntryImpl(*source.entries_[i]))); 1602 new NavigationEntryImpl(*source.entries_[i])));
1622 } 1603 }
1623 } 1604 }
1624 } 1605 }
1625 1606
1626 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1607 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1627 const base::Callback<base::Time()>& get_timestamp_callback) { 1608 const base::Callback<base::Time()>& get_timestamp_callback) {
1628 get_timestamp_callback_ = get_timestamp_callback; 1609 get_timestamp_callback_ = get_timestamp_callback;
1629 } 1610 }
1611
1612 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698