OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/frame_host/navigation_entry_impl.h" | 5 #include "content/browser/frame_host/navigation_entry_impl.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 | 8 |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 | 26 |
27 int NavigationEntryImpl::kInvalidBindings = -1; | 27 int NavigationEntryImpl::kInvalidBindings = -1; |
28 | 28 |
29 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) | 29 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) |
30 : frame_entry(frame_entry) { | 30 : frame_entry(frame_entry) { |
31 } | 31 } |
32 | 32 |
33 NavigationEntryImpl::TreeNode::~TreeNode() { | 33 NavigationEntryImpl::TreeNode::~TreeNode() { |
34 } | 34 } |
35 | 35 |
36 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const { | 36 bool NavigationEntryImpl::TreeNode::MatchesFrame( |
37 FrameTreeNode* frame_tree_node) const { | |
38 if (frame_tree_node->frame_tree_node_id() == | |
39 frame_entry->frame_tree_node_id()) | |
40 return true; | |
41 | |
42 // For now, we set the root FNE's FrameTreeNode ID to -1. | |
43 return frame_tree_node->IsMainFrame() && | |
44 frame_entry->frame_tree_node_id() == -1; | |
45 } | |
46 | |
47 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::CloneAndReplace( | |
Avi (use Gerrit)
2015/05/19 19:36:05
Oh! If we're returning a new object, make the retu
Charlie Reis
2015/05/21 20:09:33
Done.
| |
48 FrameTreeNode* frame_tree_node, | |
49 FrameNavigationEntry* frame_navigation_entry) const { | |
50 if (frame_tree_node && MatchesFrame(frame_tree_node)) { | |
51 // Replace this node in the cloned tree and prune its children. | |
52 return new NavigationEntryImpl::TreeNode(frame_navigation_entry); | |
53 } | |
54 | |
37 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. | 55 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. |
56 // TODO(creis): Share FNEs unless it's for another tab. | |
38 NavigationEntryImpl::TreeNode* copy = | 57 NavigationEntryImpl::TreeNode* copy = |
39 new NavigationEntryImpl::TreeNode(frame_entry->Clone()); | 58 new NavigationEntryImpl::TreeNode(frame_entry->Clone()); |
40 | 59 |
41 // TODO(creis): Clone children once we add them. | 60 // Recursively clone the children. |
61 for (auto& child : children) { | |
62 copy->children.push_back( | |
Avi (use Gerrit)
2015/05/19 19:36:05
... and you can push_back a scoped_ptr onto a Scop
Charlie Reis
2015/05/21 20:09:33
Done.
| |
63 child->CloneAndReplace(frame_tree_node, frame_navigation_entry)); | |
64 } | |
65 | |
42 return copy; | 66 return copy; |
43 } | 67 } |
44 | 68 |
45 NavigationEntry* NavigationEntry::Create() { | 69 NavigationEntry* NavigationEntry::Create() { |
46 return new NavigationEntryImpl(); | 70 return new NavigationEntryImpl(); |
47 } | 71 } |
48 | 72 |
49 NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry( | 73 NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry( |
50 NavigationEntry* entry) { | 74 NavigationEntry* entry) { |
51 return static_cast<NavigationEntryImpl*>(entry); | 75 return static_cast<NavigationEntryImpl*>(entry); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 return false; | 352 return false; |
329 *data = iter->second; | 353 *data = iter->second; |
330 return true; | 354 return true; |
331 } | 355 } |
332 | 356 |
333 void NavigationEntryImpl::ClearExtraData(const std::string& key) { | 357 void NavigationEntryImpl::ClearExtraData(const std::string& key) { |
334 extra_data_.erase(key); | 358 extra_data_.erase(key); |
335 } | 359 } |
336 | 360 |
337 NavigationEntryImpl* NavigationEntryImpl::Clone() const { | 361 NavigationEntryImpl* NavigationEntryImpl::Clone() const { |
362 return NavigationEntryImpl::CloneAndReplace(nullptr, nullptr); | |
363 } | |
364 | |
365 NavigationEntryImpl* NavigationEntryImpl::CloneAndReplace( | |
366 FrameTreeNode* frame_tree_node, | |
367 FrameNavigationEntry* frame_navigation_entry) const { | |
338 NavigationEntryImpl* copy = new NavigationEntryImpl(); | 368 NavigationEntryImpl* copy = new NavigationEntryImpl(); |
339 | 369 |
340 // TODO(creis): Only share the same FrameNavigationEntries if cloning within | 370 // TODO(creis): Only share the same FrameNavigationEntries if cloning within |
341 // the same tab. | 371 // the same tab. |
342 copy->frame_tree_.reset(frame_tree_->Clone()); | 372 copy->frame_tree_.reset( |
373 frame_tree_->CloneAndReplace(frame_tree_node, frame_navigation_entry)); | |
343 | 374 |
344 // Copy all state over, unless cleared in ResetForCommit. | 375 // Copy all state over, unless cleared in ResetForCommit. |
345 copy->unique_id_ = unique_id_; | 376 copy->unique_id_ = unique_id_; |
346 copy->bindings_ = bindings_; | 377 copy->bindings_ = bindings_; |
347 copy->page_type_ = page_type_; | 378 copy->page_type_ = page_type_; |
348 copy->virtual_url_ = virtual_url_; | 379 copy->virtual_url_ = virtual_url_; |
349 copy->update_virtual_url_with_url_ = update_virtual_url_with_url_; | 380 copy->update_virtual_url_with_url_ = update_virtual_url_with_url_; |
350 copy->title_ = title_; | 381 copy->title_ = title_; |
351 copy->favicon_ = favicon_; | 382 copy->favicon_ = favicon_; |
352 copy->page_state_ = page_state_; | 383 copy->page_state_ = page_state_; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 #endif | 496 #endif |
466 } | 497 } |
467 | 498 |
468 void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node, | 499 void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node, |
469 SiteInstanceImpl* site_instance, | 500 SiteInstanceImpl* site_instance, |
470 const GURL& url, | 501 const GURL& url, |
471 const Referrer& referrer) { | 502 const Referrer& referrer) { |
472 // We should already have a TreeNode for the parent node by the time this node | 503 // We should already have a TreeNode for the parent node by the time this node |
473 // commits. Find it first. | 504 // commits. Find it first. |
474 DCHECK(frame_tree_node->parent()); | 505 DCHECK(frame_tree_node->parent()); |
475 int parent_ftn_id = frame_tree_node->parent()->frame_tree_node_id(); | |
476 bool found = false; | 506 bool found = false; |
477 NavigationEntryImpl::TreeNode* parent_node = nullptr; | 507 NavigationEntryImpl::TreeNode* parent_node = nullptr; |
478 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | 508 std::queue<NavigationEntryImpl::TreeNode*> work_queue; |
479 work_queue.push(root_node()); | 509 work_queue.push(root_node()); |
480 while (!found && !work_queue.empty()) { | 510 while (!found && !work_queue.empty()) { |
481 parent_node = work_queue.front(); | 511 parent_node = work_queue.front(); |
482 work_queue.pop(); | 512 work_queue.pop(); |
483 // The root FNE will have an ID of -1, so check for that as well. | 513 if (parent_node->MatchesFrame(frame_tree_node->parent())) { |
484 if (parent_node->frame_entry->frame_tree_node_id() == parent_ftn_id || | 514 // Only the root TreeNode should have a FTN ID of -1. |
485 (parent_node->frame_entry->frame_tree_node_id() == -1 && | 515 DCHECK_IMPLIES(parent_node->frame_entry->frame_tree_node_id() == -1, |
486 parent_node == root_node() && | 516 parent_node == root_node()); |
487 frame_tree_node->parent()->IsMainFrame())) { | |
488 found = true; | 517 found = true; |
489 break; | 518 break; |
490 } | 519 } |
491 // Enqueue any children and keep looking. | 520 // Enqueue any children and keep looking. |
492 for (auto& child : parent_node->children) | 521 for (auto& child : parent_node->children) |
493 work_queue.push(child); | 522 work_queue.push(child); |
494 } | 523 } |
495 if (!found) { | 524 if (!found) { |
496 // The renderer should not send a commit for a subframe before its parent. | 525 // The renderer should not send a commit for a subframe before its parent. |
497 // TODO(creis): This can currently happen because we don't yet clone the | 526 // TODO(creis): Kill the renderer if we get here. |
498 // FrameNavigationEntry tree on manual subframe navigations. Once that's | 527 NOTREACHED() << "Shouldn't see a commit for a subframe before parent."; |
499 // added, we should kill the renderer if we get here. | |
500 return; | 528 return; |
501 } | 529 } |
502 | 530 |
503 // Now check whether we have a TreeNode for the node itself. | 531 // Now check whether we have a TreeNode for the node itself. |
504 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | 532 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
505 for (TreeNode* child : parent_node->children) { | 533 for (TreeNode* child : parent_node->children) { |
506 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { | 534 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { |
507 // Update the existing FrameNavigationEntry. | 535 // Update the existing FrameNavigationEntry (e.g., for replaceState). |
508 child->frame_entry->UpdateEntry(site_instance, url, referrer); | 536 child->frame_entry->UpdateEntry(site_instance, url, referrer); |
509 return; | 537 return; |
510 } | 538 } |
511 } | 539 } |
512 | 540 |
513 // No entry exists yet, so create a new one. Unordered list, since we expect | 541 // No entry exists yet, so create a new one. Unordered list, since we expect |
514 // to look up entries by frame sequence number or unique name. | 542 // to look up entries by frame sequence number or unique name. |
515 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( | 543 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( |
516 frame_tree_node_id, site_instance, url, referrer); | 544 frame_tree_node_id, site_instance, url, referrer); |
517 parent_node->children.push_back( | 545 parent_node->children.push_back( |
518 new NavigationEntryImpl::TreeNode(frame_entry)); | 546 new NavigationEntryImpl::TreeNode(frame_entry)); |
519 } | 547 } |
520 | 548 |
521 void NavigationEntryImpl::SetScreenshotPNGData( | 549 void NavigationEntryImpl::SetScreenshotPNGData( |
522 scoped_refptr<base::RefCountedBytes> png_data) { | 550 scoped_refptr<base::RefCountedBytes> png_data) { |
523 screenshot_ = png_data; | 551 screenshot_ = png_data; |
524 if (screenshot_.get()) | 552 if (screenshot_.get()) |
525 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); | 553 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); |
526 } | 554 } |
527 | 555 |
528 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { | 556 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { |
529 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); | 557 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); |
530 } | 558 } |
531 | 559 |
532 } // namespace content | 560 } // namespace content |
OLD | NEW |