Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/bookmarks/browser/bookmark_model.h" | 5 #include "components/bookmarks/browser/bookmark_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/i18n/string_compare.h" | 13 #include "base/i18n/string_compare.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | |
| 16 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/profiler/scoped_tracker.h" | 18 #include "base/profiler/scoped_tracker.h" |
| 18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 19 #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h" | 20 #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h" |
| 20 #include "components/bookmarks/browser/bookmark_index.h" | 21 #include "components/bookmarks/browser/bookmark_index.h" |
| 21 #include "components/bookmarks/browser/bookmark_match.h" | 22 #include "components/bookmarks/browser/bookmark_match.h" |
| 22 #include "components/bookmarks/browser/bookmark_model_observer.h" | 23 #include "components/bookmarks/browser/bookmark_model_observer.h" |
| 23 #include "components/bookmarks/browser/bookmark_node_data.h" | 24 #include "components/bookmarks/browser/bookmark_node_data.h" |
| 24 #include "components/bookmarks/browser/bookmark_storage.h" | 25 #include "components/bookmarks/browser/bookmark_storage.h" |
| 25 #include "components/bookmarks/browser/bookmark_undo_delegate.h" | 26 #include "components/bookmarks/browser/bookmark_undo_delegate.h" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 44 BookmarkPermanentNode* AsMutable(const BookmarkPermanentNode* node) { | 45 BookmarkPermanentNode* AsMutable(const BookmarkPermanentNode* node) { |
| 45 return const_cast<BookmarkPermanentNode*>(node); | 46 return const_cast<BookmarkPermanentNode*>(node); |
| 46 } | 47 } |
| 47 | 48 |
| 48 // Comparator used when sorting permanent nodes. Nodes that are initially | 49 // Comparator used when sorting permanent nodes. Nodes that are initially |
| 49 // visible are sorted before nodes that are initially hidden. | 50 // visible are sorted before nodes that are initially hidden. |
| 50 class VisibilityComparator { | 51 class VisibilityComparator { |
| 51 public: | 52 public: |
| 52 explicit VisibilityComparator(BookmarkClient* client) : client_(client) {} | 53 explicit VisibilityComparator(BookmarkClient* client) : client_(client) {} |
| 53 | 54 |
| 54 // Returns true if |n1| preceeds |n2|. | 55 // Returns true if |n1| precedes |n2|. |
| 55 bool operator()(const BookmarkPermanentNode* n1, | 56 bool operator()(const std::unique_ptr<BookmarkPermanentNode>& n1, |
| 56 const BookmarkPermanentNode* n2) { | 57 const std::unique_ptr<BookmarkPermanentNode>& n2) { |
| 57 bool n1_visible = client_->IsPermanentNodeVisible(n1); | 58 bool n1_visible = client_->IsPermanentNodeVisible(n1.get()); |
| 58 bool n2_visible = client_->IsPermanentNodeVisible(n2); | 59 bool n2_visible = client_->IsPermanentNodeVisible(n2.get()); |
| 59 return n1_visible != n2_visible && n1_visible; | 60 return n1_visible != n2_visible && n1_visible; |
| 60 } | 61 } |
| 61 | 62 |
| 62 private: | 63 private: |
| 63 BookmarkClient* client_; | 64 BookmarkClient* client_; |
| 64 }; | 65 }; |
| 65 | 66 |
| 66 // Comparator used when sorting bookmarks. Folders are sorted first, then | 67 // Comparator used when sorting bookmarks. Folders are sorted first, then |
| 67 // bookmarks. | 68 // bookmarks. |
| 68 class SortComparator { | 69 class SortComparator { |
| 69 public: | 70 public: |
| 70 explicit SortComparator(icu::Collator* collator) : collator_(collator) {} | 71 explicit SortComparator(icu::Collator* collator) : collator_(collator) {} |
| 71 | 72 |
| 72 // Returns true if |n1| preceeds |n2|. | 73 // Returns true if |n1| precedes |n2|. |
| 73 bool operator()(const BookmarkNode* n1, const BookmarkNode* n2) { | 74 bool operator()(const std::unique_ptr<BookmarkNode>& n1, |
| 75 const std::unique_ptr<BookmarkNode>& n2) { | |
| 74 if (n1->type() == n2->type()) { | 76 if (n1->type() == n2->type()) { |
| 75 // Types are the same, compare the names. | 77 // Types are the same, compare the names. |
| 76 if (!collator_) | 78 if (!collator_) |
| 77 return n1->GetTitle() < n2->GetTitle(); | 79 return n1->GetTitle() < n2->GetTitle(); |
| 78 return base::i18n::CompareString16WithCollator( | 80 return base::i18n::CompareString16WithCollator( |
| 79 *collator_, n1->GetTitle(), n2->GetTitle()) == UCOL_LESS; | 81 *collator_, n1->GetTitle(), n2->GetTitle()) == UCOL_LESS; |
| 80 } | 82 } |
| 81 // Types differ, sort such that folders come first. | 83 // Types differ, sort such that folders come first. |
| 82 return n1->is_folder(); | 84 return n1->is_folder(); |
| 83 } | 85 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 void BookmarkModel::Remove(const BookmarkNode* node) { | 212 void BookmarkModel::Remove(const BookmarkNode* node) { |
| 211 DCHECK(loaded_); | 213 DCHECK(loaded_); |
| 212 DCHECK(node); | 214 DCHECK(node); |
| 213 DCHECK(!is_root_node(node)); | 215 DCHECK(!is_root_node(node)); |
| 214 RemoveAndDeleteNode(AsMutable(node)); | 216 RemoveAndDeleteNode(AsMutable(node)); |
| 215 } | 217 } |
| 216 | 218 |
| 217 void BookmarkModel::RemoveAllUserBookmarks() { | 219 void BookmarkModel::RemoveAllUserBookmarks() { |
| 218 std::set<GURL> removed_urls; | 220 std::set<GURL> removed_urls; |
| 219 struct RemoveNodeData { | 221 struct RemoveNodeData { |
| 220 RemoveNodeData(const BookmarkNode* parent, int index, BookmarkNode* node) | |
| 221 : parent(parent), index(index), node(node) {} | |
| 222 | |
| 223 const BookmarkNode* parent; | 222 const BookmarkNode* parent; |
| 224 int index; | 223 int index; |
| 225 BookmarkNode* node; | 224 std::unique_ptr<BookmarkNode> node; |
| 226 }; | 225 }; |
| 227 std::vector<RemoveNodeData> removed_node_data_list; | 226 std::vector<RemoveNodeData> removed_node_data_list; |
| 228 | 227 |
| 229 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 228 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 230 OnWillRemoveAllUserBookmarks(this)); | 229 OnWillRemoveAllUserBookmarks(this)); |
| 231 | 230 |
| 232 BeginExtensiveChanges(); | 231 BeginExtensiveChanges(); |
| 233 // Skip deleting permanent nodes. Permanent bookmark nodes are the root and | 232 // Skip deleting permanent nodes. Permanent bookmark nodes are the root and |
| 234 // its immediate children. For removing all non permanent nodes just remove | 233 // its immediate children. For removing all non permanent nodes just remove |
| 235 // all children of non-root permanent nodes. | 234 // all children of non-root permanent nodes. |
| 236 { | 235 { |
| 237 base::AutoLock url_lock(url_lock_); | 236 base::AutoLock url_lock(url_lock_); |
| 238 for (int i = 0; i < root_.child_count(); ++i) { | 237 for (int i = 0; i < root_.child_count(); ++i) { |
| 239 const BookmarkNode* permanent_node = root_.GetChild(i); | 238 const BookmarkNode* permanent_node = root_.GetChild(i); |
| 240 | 239 |
| 241 if (!client_->CanBeEditedByUser(permanent_node)) | 240 if (!client_->CanBeEditedByUser(permanent_node)) |
| 242 continue; | 241 continue; |
| 243 | 242 |
| 244 for (int j = permanent_node->child_count() - 1; j >= 0; --j) { | 243 for (int j = permanent_node->child_count() - 1; j >= 0; --j) { |
| 245 BookmarkNode* child_node = AsMutable(permanent_node->GetChild(j)); | 244 std::unique_ptr<BookmarkNode> node = RemoveNodeAndGetRemovedUrls( |
| 246 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); | 245 AsMutable(permanent_node->GetChild(j)), &removed_urls); |
| 247 removed_node_data_list.push_back( | 246 removed_node_data_list.push_back({permanent_node, j, std::move(node)}); |
| 248 RemoveNodeData(permanent_node, j, child_node)); | |
| 249 } | 247 } |
| 250 } | 248 } |
| 251 } | 249 } |
| 252 EndExtensiveChanges(); | 250 EndExtensiveChanges(); |
| 253 if (store_.get()) | 251 if (store_.get()) |
| 254 store_->ScheduleSave(); | 252 store_->ScheduleSave(); |
| 255 | 253 |
| 256 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 254 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 257 BookmarkAllUserNodesRemoved(this, removed_urls)); | 255 BookmarkAllUserNodesRemoved(this, removed_urls)); |
| 258 | 256 |
| 259 BeginGroupedChanges(); | 257 BeginGroupedChanges(); |
| 260 for (const auto& removed_node_data : removed_node_data_list) { | 258 for (auto& removed_node_data : removed_node_data_list) { |
| 261 undo_delegate()->OnBookmarkNodeRemoved( | 259 undo_delegate()->OnBookmarkNodeRemoved(this, removed_node_data.parent, |
| 262 this, removed_node_data.parent, removed_node_data.index, | 260 removed_node_data.index, |
| 263 std::unique_ptr<BookmarkNode>(removed_node_data.node)); | 261 std::move(removed_node_data.node)); |
| 264 } | 262 } |
| 265 EndGroupedChanges(); | 263 EndGroupedChanges(); |
| 266 } | 264 } |
| 267 | 265 |
| 268 void BookmarkModel::Move(const BookmarkNode* node, | 266 void BookmarkModel::Move(const BookmarkNode* node, |
| 269 const BookmarkNode* new_parent, | 267 const BookmarkNode* new_parent, |
| 270 int index) { | 268 int index) { |
| 271 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || | 269 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || |
| 272 is_root_node(new_parent) || is_permanent_node(node)) { | 270 is_root_node(new_parent) || is_permanent_node(node)) { |
| 273 NOTREACHED(); | 271 NOTREACHED(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 286 if (old_parent == new_parent && | 284 if (old_parent == new_parent && |
| 287 (index == old_index || index == old_index + 1)) { | 285 (index == old_index || index == old_index + 1)) { |
| 288 // Node is already in this position, nothing to do. | 286 // Node is already in this position, nothing to do. |
| 289 return; | 287 return; |
| 290 } | 288 } |
| 291 | 289 |
| 292 SetDateFolderModified(new_parent, Time::Now()); | 290 SetDateFolderModified(new_parent, Time::Now()); |
| 293 | 291 |
| 294 if (old_parent == new_parent && index > old_index) | 292 if (old_parent == new_parent && index > old_index) |
| 295 index--; | 293 index--; |
| 294 | |
| 295 BookmarkNode* mutable_old_parent = AsMutable(old_parent); | |
| 296 std::unique_ptr<BookmarkNode> owned_node = | |
| 297 mutable_old_parent->Remove(AsMutable(node)); | |
| 296 BookmarkNode* mutable_new_parent = AsMutable(new_parent); | 298 BookmarkNode* mutable_new_parent = AsMutable(new_parent); |
| 297 mutable_new_parent->Add(AsMutable(node), index); | 299 mutable_new_parent->Add(std::move(owned_node), index); |
| 298 | 300 |
| 299 if (store_.get()) | 301 if (store_.get()) |
| 300 store_->ScheduleSave(); | 302 store_->ScheduleSave(); |
| 301 | 303 |
| 302 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 304 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 303 BookmarkNodeMoved(this, old_parent, old_index, | 305 BookmarkNodeMoved(this, old_parent, old_index, |
| 304 new_parent, index)); | 306 new_parent, index)); |
| 305 } | 307 } |
| 306 | 308 |
| 307 void BookmarkModel::Copy(const BookmarkNode* node, | 309 void BookmarkModel::Copy(const BookmarkNode* node, |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 const BookmarkNode* parent, | 589 const BookmarkNode* parent, |
| 588 int index, | 590 int index, |
| 589 const base::string16& title, | 591 const base::string16& title, |
| 590 const BookmarkNode::MetaInfoMap* meta_info) { | 592 const BookmarkNode::MetaInfoMap* meta_info) { |
| 591 if (!loaded_ || is_root_node(parent) || !IsValidIndex(parent, index, true)) { | 593 if (!loaded_ || is_root_node(parent) || !IsValidIndex(parent, index, true)) { |
| 592 // Can't add to the root. | 594 // Can't add to the root. |
| 593 NOTREACHED(); | 595 NOTREACHED(); |
| 594 return NULL; | 596 return NULL; |
| 595 } | 597 } |
| 596 | 598 |
| 597 BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), GURL()); | 599 std::unique_ptr<BookmarkNode> new_node = |
| 600 base::MakeUnique<BookmarkNode>(generate_next_node_id(), GURL()); | |
| 598 new_node->set_date_folder_modified(Time::Now()); | 601 new_node->set_date_folder_modified(Time::Now()); |
| 599 // Folders shouldn't have line breaks in their titles. | 602 // Folders shouldn't have line breaks in their titles. |
| 600 new_node->SetTitle(title); | 603 new_node->SetTitle(title); |
| 601 new_node->set_type(BookmarkNode::FOLDER); | 604 new_node->set_type(BookmarkNode::FOLDER); |
| 602 if (meta_info) | 605 if (meta_info) |
| 603 new_node->SetMetaInfoMap(*meta_info); | 606 new_node->SetMetaInfoMap(*meta_info); |
| 604 | 607 |
| 605 return AddNode(AsMutable(parent), index, new_node); | 608 return AddNode(AsMutable(parent), index, std::move(new_node)); |
| 606 } | 609 } |
| 607 | 610 |
| 608 const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent, | 611 const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent, |
| 609 int index, | 612 int index, |
| 610 const base::string16& title, | 613 const base::string16& title, |
| 611 const GURL& url) { | 614 const GURL& url) { |
| 612 return AddURLWithCreationTimeAndMetaInfo( | 615 return AddURLWithCreationTimeAndMetaInfo( |
| 613 parent, | 616 parent, |
| 614 index, | 617 index, |
| 615 title, | 618 title, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 628 if (!loaded_ || !url.is_valid() || is_root_node(parent) || | 631 if (!loaded_ || !url.is_valid() || is_root_node(parent) || |
| 629 !IsValidIndex(parent, index, true)) { | 632 !IsValidIndex(parent, index, true)) { |
| 630 NOTREACHED(); | 633 NOTREACHED(); |
| 631 return NULL; | 634 return NULL; |
| 632 } | 635 } |
| 633 | 636 |
| 634 // Syncing may result in dates newer than the last modified date. | 637 // Syncing may result in dates newer than the last modified date. |
| 635 if (creation_time > parent->date_folder_modified()) | 638 if (creation_time > parent->date_folder_modified()) |
| 636 SetDateFolderModified(parent, creation_time); | 639 SetDateFolderModified(parent, creation_time); |
| 637 | 640 |
| 638 BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), url); | 641 std::unique_ptr<BookmarkNode> new_node = |
| 642 base::MakeUnique<BookmarkNode>(generate_next_node_id(), url); | |
| 639 new_node->SetTitle(title); | 643 new_node->SetTitle(title); |
| 640 new_node->set_date_added(creation_time); | 644 new_node->set_date_added(creation_time); |
| 641 new_node->set_type(BookmarkNode::URL); | 645 new_node->set_type(BookmarkNode::URL); |
| 642 if (meta_info) | 646 if (meta_info) |
| 643 new_node->SetMetaInfoMap(*meta_info); | 647 new_node->SetMetaInfoMap(*meta_info); |
| 644 | 648 |
| 645 return AddNode(AsMutable(parent), index, new_node); | 649 return AddNode(AsMutable(parent), index, std::move(new_node)); |
| 646 } | 650 } |
| 647 | 651 |
| 648 void BookmarkModel::SortChildren(const BookmarkNode* parent) { | 652 void BookmarkModel::SortChildren(const BookmarkNode* parent) { |
| 649 DCHECK(client_->CanBeEditedByUser(parent)); | 653 DCHECK(client_->CanBeEditedByUser(parent)); |
| 650 | 654 |
| 651 if (!parent || !parent->is_folder() || is_root_node(parent) || | 655 if (!parent || !parent->is_folder() || is_root_node(parent) || |
| 652 parent->child_count() <= 1) { | 656 parent->child_count() <= 1) { |
| 653 return; | 657 return; |
| 654 } | 658 } |
| 655 | 659 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 672 BookmarkNodeChildrenReordered(this, parent)); | 676 BookmarkNodeChildrenReordered(this, parent)); |
| 673 } | 677 } |
| 674 | 678 |
| 675 void BookmarkModel::ReorderChildren( | 679 void BookmarkModel::ReorderChildren( |
| 676 const BookmarkNode* parent, | 680 const BookmarkNode* parent, |
| 677 const std::vector<const BookmarkNode*>& ordered_nodes) { | 681 const std::vector<const BookmarkNode*>& ordered_nodes) { |
| 678 DCHECK(client_->CanBeEditedByUser(parent)); | 682 DCHECK(client_->CanBeEditedByUser(parent)); |
| 679 | 683 |
| 680 // Ensure that all children in |parent| are in |ordered_nodes|. | 684 // Ensure that all children in |parent| are in |ordered_nodes|. |
| 681 DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); | 685 DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); |
| 682 for (size_t i = 0; i < ordered_nodes.size(); ++i) | 686 for (const BookmarkNode* node : ordered_nodes) |
| 683 DCHECK_EQ(parent, ordered_nodes[i]->parent()); | 687 DCHECK_EQ(parent, node->parent()); |
| 684 | 688 |
| 685 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 689 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 686 OnWillReorderBookmarkNode(this, parent)); | 690 OnWillReorderBookmarkNode(this, parent)); |
| 687 | 691 |
| 688 AsMutable(parent)->SetChildren( | 692 BookmarkNode* mutable_parent = AsMutable(parent); |
| 689 *(reinterpret_cast<const std::vector<BookmarkNode*>*>(&ordered_nodes))); | 693 for (size_t i = 0; i < ordered_nodes.size() - 1; ++i) { |
|
sky
2016/09/29 22:06:48
if ordered_nodes is empty this code is problematic
Avi (use Gerrit)
2016/09/29 22:59:58
Done.
| |
| 694 std::unique_ptr<BookmarkNode> node = | |
| 695 mutable_parent->Remove(AsMutable(ordered_nodes[i])); | |
|
sky
2016/09/29 22:06:48
This implementation is way more expensive than the
Avi (use Gerrit)
2016/09/29 22:59:58
Yes. The only thought I have on how to do better i
Avi (use Gerrit)
2016/09/30 00:16:48
Actually I have an idea.
| |
| 696 mutable_parent->Add(std::move(node), i); | |
| 697 } | |
| 690 | 698 |
| 691 if (store_.get()) | 699 if (store_.get()) |
| 692 store_->ScheduleSave(); | 700 store_->ScheduleSave(); |
| 693 | 701 |
| 694 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 702 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 695 BookmarkNodeChildrenReordered(this, parent)); | 703 BookmarkNodeChildrenReordered(this, parent)); |
| 696 } | 704 } |
| 697 | 705 |
| 698 void BookmarkModel::SetDateFolderModified(const BookmarkNode* parent, | 706 void BookmarkModel::SetDateFolderModified(const BookmarkNode* parent, |
| 699 const Time time) { | 707 const Time time) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 case BookmarkNode::OTHER_NODE: | 753 case BookmarkNode::OTHER_NODE: |
| 746 return other_node_; | 754 return other_node_; |
| 747 case BookmarkNode::MOBILE: | 755 case BookmarkNode::MOBILE: |
| 748 return mobile_node_; | 756 return mobile_node_; |
| 749 default: | 757 default: |
| 750 NOTREACHED(); | 758 NOTREACHED(); |
| 751 return NULL; | 759 return NULL; |
| 752 } | 760 } |
| 753 } | 761 } |
| 754 | 762 |
| 755 void BookmarkModel::RestoreRemovedNode( | 763 void BookmarkModel::RestoreRemovedNode(const BookmarkNode* parent, |
| 756 const BookmarkNode* parent, | 764 int index, |
| 757 int index, | 765 std::unique_ptr<BookmarkNode> node) { |
| 758 std::unique_ptr<BookmarkNode> scoped_node) { | 766 BookmarkNode* node_ptr = node.get(); |
| 759 BookmarkNode* node = scoped_node.release(); | 767 AddNode(AsMutable(parent), index, std::move(node)); |
| 760 AddNode(AsMutable(parent), index, node); | |
| 761 | 768 |
| 762 // We might be restoring a folder node that have already contained a set of | 769 // We might be restoring a folder node that have already contained a set of |
| 763 // child nodes. We need to notify all of them. | 770 // child nodes. We need to notify all of them. |
| 764 NotifyNodeAddedForAllDescendents(node); | 771 NotifyNodeAddedForAllDescendents(node_ptr); |
| 765 } | 772 } |
| 766 | 773 |
| 767 void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) { | 774 void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) { |
| 768 for (int i = 0; i < node->child_count(); ++i) { | 775 for (int i = 0; i < node->child_count(); ++i) { |
| 769 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 776 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 770 BookmarkNodeAdded(this, node, i)); | 777 BookmarkNodeAdded(this, node, i)); |
| 771 NotifyNodeAddedForAllDescendents(node->GetChild(i)); | 778 NotifyNodeAddedForAllDescendents(node->GetChild(i)); |
| 772 } | 779 } |
| 773 } | 780 } |
| 774 | 781 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 tracked_objects::ScopedTracker tracking_profile2( | 826 tracked_objects::ScopedTracker tracking_profile2( |
| 820 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading2")); | 827 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading2")); |
| 821 | 828 |
| 822 // If bookmarks file changed externally, the IDs may have changed | 829 // If bookmarks file changed externally, the IDs may have changed |
| 823 // externally. In that case, the decoder may have reassigned IDs to make | 830 // externally. In that case, the decoder may have reassigned IDs to make |
| 824 // them unique. So when the file has changed externally, we should save the | 831 // them unique. So when the file has changed externally, we should save the |
| 825 // bookmarks file to persist new IDs. | 832 // bookmarks file to persist new IDs. |
| 826 if (store_.get()) | 833 if (store_.get()) |
| 827 store_->ScheduleSave(); | 834 store_->ScheduleSave(); |
| 828 } | 835 } |
| 829 bookmark_bar_node_ = details->release_bb_node(); | 836 std::unique_ptr<BookmarkPermanentNode> owned_bb_node = |
| 830 other_node_ = details->release_other_folder_node(); | 837 details->owned_bb_node(); |
| 831 mobile_node_ = details->release_mobile_folder_node(); | 838 std::unique_ptr<BookmarkPermanentNode> owned_other_folder_node = |
| 832 index_.reset(details->release_index()); | 839 details->owned_other_folder_node(); |
| 840 std::unique_ptr<BookmarkPermanentNode> owned_mobile_folder_node = | |
| 841 details->owned_mobile_folder_node(); | |
| 842 index_ = details->owned_index(); | |
| 843 | |
| 844 bookmark_bar_node_ = owned_bb_node.get(); | |
|
sky
2016/09/29 22:06:48
Can you set these members when you add them below?
Avi (use Gerrit)
2016/09/29 22:59:58
Not sure what you mean. Have something like
roo
sky
2016/09/30 03:07:05
My mistake. What you have is fine.
| |
| 845 other_node_ = owned_other_folder_node.get(); | |
| 846 mobile_node_ = owned_mobile_folder_node.get(); | |
| 833 | 847 |
| 834 // Get any extra nodes and take ownership of them at the |root_|. | 848 // Get any extra nodes and take ownership of them at the |root_|. |
| 835 std::vector<BookmarkPermanentNode*> extra_nodes; | 849 std::vector<std::unique_ptr<BookmarkPermanentNode>> extra_nodes = |
| 836 details->release_extra_nodes(&extra_nodes); | 850 details->owned_extra_nodes(); |
| 837 | 851 |
| 838 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 852 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 839 // is fixed. | 853 // is fixed. |
| 840 tracked_objects::ScopedTracker tracking_profile3( | 854 tracked_objects::ScopedTracker tracking_profile3( |
| 841 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading3")); | 855 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading3")); |
| 842 | 856 |
| 843 // WARNING: order is important here, various places assume the order is | 857 // WARNING: order is important here, various places assume the order is |
| 844 // constant (but can vary between embedders with the initial visibility | 858 // constant (but can vary between embedders with the initial visibility |
| 845 // of permanent nodes). | 859 // of permanent nodes). |
| 846 std::vector<BookmarkPermanentNode*> root_children; | 860 std::vector<std::unique_ptr<BookmarkPermanentNode>> root_children; |
| 847 root_children.push_back(bookmark_bar_node_); | 861 root_children.push_back(std::move(owned_bb_node)); |
| 848 root_children.push_back(other_node_); | 862 root_children.push_back(std::move(owned_other_folder_node)); |
| 849 root_children.push_back(mobile_node_); | 863 root_children.push_back(std::move(owned_mobile_folder_node)); |
| 850 for (size_t i = 0; i < extra_nodes.size(); ++i) | 864 std::move(extra_nodes.begin(), extra_nodes.end(), |
| 851 root_children.push_back(extra_nodes[i]); | 865 std::back_inserter(root_children)); |
| 852 | 866 |
| 853 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 867 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 854 // is fixed. | 868 // is fixed. |
| 855 tracked_objects::ScopedTracker tracking_profile4( | 869 tracked_objects::ScopedTracker tracking_profile4( |
| 856 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading4")); | 870 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading4")); |
| 857 | 871 |
| 858 std::stable_sort(root_children.begin(), | 872 std::stable_sort(root_children.begin(), |
| 859 root_children.end(), | 873 root_children.end(), |
| 860 VisibilityComparator(client_.get())); | 874 VisibilityComparator(client_.get())); |
| 861 for (size_t i = 0; i < root_children.size(); ++i) | 875 for (size_t i = 0; i < root_children.size(); ++i) |
| 862 root_.Add(root_children[i], static_cast<int>(i)); | 876 root_.Add(std::move(root_children[i]), static_cast<int>(i)); |
| 863 | 877 |
| 864 root_.SetMetaInfoMap(details->model_meta_info_map()); | 878 root_.SetMetaInfoMap(details->model_meta_info_map()); |
| 865 root_.set_sync_transaction_version(details->model_sync_transaction_version()); | 879 root_.set_sync_transaction_version(details->model_sync_transaction_version()); |
| 866 | 880 |
| 867 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 881 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 868 // is fixed. | 882 // is fixed. |
| 869 tracked_objects::ScopedTracker tracking_profile5( | 883 tracked_objects::ScopedTracker tracking_profile5( |
| 870 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading5")); | 884 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading5")); |
| 871 | 885 |
| 872 { | 886 { |
| 873 base::AutoLock url_lock(url_lock_); | 887 base::AutoLock url_lock(url_lock_); |
| 874 // Update nodes_ordered_by_url_set_ from the nodes. | 888 // Update nodes_ordered_by_url_set_ from the nodes. |
| 875 PopulateNodesByURL(&root_); | 889 PopulateNodesByURL(&root_); |
| 876 } | 890 } |
| 877 | 891 |
| 878 loaded_ = true; | 892 loaded_ = true; |
| 879 | 893 |
| 880 loaded_signal_.Signal(); | 894 loaded_signal_.Signal(); |
| 881 | 895 |
| 882 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 896 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 883 // is fixed. | 897 // is fixed. |
| 884 tracked_objects::ScopedTracker tracking_profile6( | 898 tracked_objects::ScopedTracker tracking_profile6( |
| 885 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading6")); | 899 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading6")); |
| 886 | 900 |
| 887 // Notify our direct observers. | 901 // Notify our direct observers. |
| 888 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 902 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 889 BookmarkModelLoaded(this, details->ids_reassigned())); | 903 BookmarkModelLoaded(this, details->ids_reassigned())); |
| 890 } | 904 } |
| 891 | 905 |
| 892 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { | 906 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* node_ptr) { |
| 893 std::unique_ptr<BookmarkNode> node(delete_me); | 907 std::unique_ptr<BookmarkNode> node; |
| 894 | 908 |
| 895 const BookmarkNode* parent = node->parent(); | 909 const BookmarkNode* parent = node_ptr->parent(); |
| 896 DCHECK(parent); | 910 DCHECK(parent); |
| 897 int index = parent->GetIndexOf(node.get()); | 911 int index = parent->GetIndexOf(node_ptr); |
| 898 DCHECK_NE(-1, index); | 912 DCHECK_NE(-1, index); |
| 899 | 913 |
| 900 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 914 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 901 OnWillRemoveBookmarks(this, parent, index, node.get())); | 915 OnWillRemoveBookmarks(this, parent, index, node_ptr)); |
| 902 | 916 |
| 903 std::set<GURL> removed_urls; | 917 std::set<GURL> removed_urls; |
| 904 { | 918 { |
| 905 base::AutoLock url_lock(url_lock_); | 919 base::AutoLock url_lock(url_lock_); |
| 906 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); | 920 node = RemoveNodeAndGetRemovedUrls(node_ptr, &removed_urls); |
| 907 } | 921 } |
| 908 | 922 |
| 909 if (store_.get()) | 923 if (store_.get()) |
| 910 store_->ScheduleSave(); | 924 store_->ScheduleSave(); |
| 911 | 925 |
| 912 FOR_EACH_OBSERVER( | 926 FOR_EACH_OBSERVER( |
| 913 BookmarkModelObserver, | 927 BookmarkModelObserver, |
| 914 observers_, | 928 observers_, |
| 915 BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls)); | 929 BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls)); |
| 916 | 930 |
| 917 undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, std::move(node)); | 931 undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, std::move(node)); |
| 918 } | 932 } |
| 919 | 933 |
| 920 void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) { | 934 void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) { |
| 921 index_->Remove(node); | 935 index_->Remove(node); |
| 922 // NOTE: this is called in such a way that url_lock_ is already held. As | 936 // NOTE: this is called in such a way that url_lock_ is already held. As |
| 923 // such, this doesn't explicitly grab the lock. | 937 // such, this doesn't explicitly grab the lock. |
| 924 url_lock_.AssertAcquired(); | 938 url_lock_.AssertAcquired(); |
| 925 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); | 939 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); |
| 926 DCHECK(i != nodes_ordered_by_url_set_.end()); | 940 DCHECK(i != nodes_ordered_by_url_set_.end()); |
| 927 // i points to the first node with the URL, advance until we find the | 941 // i points to the first node with the URL, advance until we find the |
| 928 // node we're removing. | 942 // node we're removing. |
| 929 while (*i != node) | 943 while (*i != node) |
| 930 ++i; | 944 ++i; |
| 931 nodes_ordered_by_url_set_.erase(i); | 945 nodes_ordered_by_url_set_.erase(i); |
| 932 } | 946 } |
| 933 | 947 |
| 934 void BookmarkModel::RemoveNodeAndGetRemovedUrls(BookmarkNode* node, | 948 std::unique_ptr<BookmarkNode> BookmarkModel::RemoveNodeAndGetRemovedUrls( |
| 935 std::set<GURL>* removed_urls) { | 949 BookmarkNode* node_ptr, |
| 950 std::set<GURL>* removed_urls) { | |
| 936 // NOTE: this method should be always called with |url_lock_| held. | 951 // NOTE: this method should be always called with |url_lock_| held. |
| 937 // This method does not explicitly acquires a lock. | 952 // This method does not explicitly acquires a lock. |
| 938 url_lock_.AssertAcquired(); | 953 url_lock_.AssertAcquired(); |
| 939 DCHECK(removed_urls); | 954 DCHECK(removed_urls); |
| 940 BookmarkNode* parent = node->parent(); | 955 BookmarkNode* parent = node_ptr->parent(); |
| 941 DCHECK(parent); | 956 DCHECK(parent); |
| 942 parent->Remove(node); | 957 std::unique_ptr<BookmarkNode> node = parent->Remove(node_ptr); |
| 943 RemoveNode(node, removed_urls); | 958 RemoveNode(node_ptr, removed_urls); |
| 944 // RemoveNode adds an entry to removed_urls for each node of type URL. As we | 959 // RemoveNode adds an entry to removed_urls for each node of type URL. As we |
| 945 // allow duplicates we need to remove any entries that are still bookmarked. | 960 // allow duplicates we need to remove any entries that are still bookmarked. |
| 946 for (std::set<GURL>::iterator i = removed_urls->begin(); | 961 for (std::set<GURL>::iterator i = removed_urls->begin(); |
| 947 i != removed_urls->end();) { | 962 i != removed_urls->end();) { |
| 948 if (IsBookmarkedNoLock(*i)) { | 963 if (IsBookmarkedNoLock(*i)) { |
| 949 // When we erase the iterator pointing at the erasee is | 964 // When we erase the iterator pointing at the erasee is |
| 950 // invalidated, so using i++ here within the "erase" call is | 965 // invalidated, so using i++ here within the "erase" call is |
| 951 // important as it advances the iterator before passing the | 966 // important as it advances the iterator before passing the |
| 952 // old value through to erase. | 967 // old value through to erase. |
| 953 removed_urls->erase(i++); | 968 removed_urls->erase(i++); |
| 954 } else { | 969 } else { |
| 955 ++i; | 970 ++i; |
| 956 } | 971 } |
| 957 } | 972 } |
| 973 | |
| 974 return node; | |
| 958 } | 975 } |
| 959 | 976 |
| 960 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, | 977 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
| 961 int index, | 978 int index, |
| 962 BookmarkNode* node) { | 979 std::unique_ptr<BookmarkNode> node) { |
| 963 parent->Add(node, index); | 980 BookmarkNode* node_ptr = node.get(); |
| 981 parent->Add(std::move(node), index); | |
| 964 | 982 |
| 965 if (store_.get()) | 983 if (store_.get()) |
| 966 store_->ScheduleSave(); | 984 store_->ScheduleSave(); |
| 967 | 985 |
| 968 { | 986 { |
| 969 base::AutoLock url_lock(url_lock_); | 987 base::AutoLock url_lock(url_lock_); |
| 970 AddNodeToInternalMaps(node); | 988 AddNodeToInternalMaps(node_ptr); |
| 971 } | 989 } |
| 972 | 990 |
| 973 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 991 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 974 BookmarkNodeAdded(this, parent, index)); | 992 BookmarkNodeAdded(this, parent, index)); |
| 975 | 993 |
| 976 return node; | 994 return node_ptr; |
| 977 } | 995 } |
| 978 | 996 |
| 979 void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) { | 997 void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) { |
| 980 url_lock_.AssertAcquired(); | 998 url_lock_.AssertAcquired(); |
| 981 if (node->is_url()) { | 999 if (node->is_url()) { |
| 982 index_->Add(node); | 1000 index_->Add(node); |
| 983 nodes_ordered_by_url_set_.insert(node); | 1001 nodes_ordered_by_url_set_.insert(node); |
| 984 } | 1002 } |
| 985 for (int i = 0; i < node->child_count(); ++i) | 1003 for (int i = 0; i < node->child_count(); ++i) |
| 986 AddNodeToInternalMaps(node->GetChild(i)); | 1004 AddNodeToInternalMaps(node->GetChild(i)); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1105 undo_delegate_ = undo_delegate; | 1123 undo_delegate_ = undo_delegate; |
| 1106 if (undo_delegate_) | 1124 if (undo_delegate_) |
| 1107 undo_delegate_->SetUndoProvider(this); | 1125 undo_delegate_->SetUndoProvider(this); |
| 1108 } | 1126 } |
| 1109 | 1127 |
| 1110 BookmarkUndoDelegate* BookmarkModel::undo_delegate() const { | 1128 BookmarkUndoDelegate* BookmarkModel::undo_delegate() const { |
| 1111 return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get(); | 1129 return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get(); |
| 1112 } | 1130 } |
| 1113 | 1131 |
| 1114 } // namespace bookmarks | 1132 } // namespace bookmarks |
| OLD | NEW |