| 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 if (ordered_nodes.size() > 1) { |
| 689 *(reinterpret_cast<const std::vector<BookmarkNode*>*>(&ordered_nodes))); | 693 std::map<const BookmarkNode*, int> order; |
| 694 for (size_t i = 0; i < ordered_nodes.size(); ++i) |
| 695 order[ordered_nodes[i]] = i; |
| 690 | 696 |
| 691 if (store_.get()) | 697 std::vector<std::unique_ptr<BookmarkNode>> new_children( |
| 692 store_->ScheduleSave(); | 698 ordered_nodes.size()); |
| 699 BookmarkNode* mutable_parent = AsMutable(parent); |
| 700 for (auto& child : mutable_parent->children()) { |
| 701 size_t new_location = order[child.get()]; |
| 702 new_children[new_location] = std::move(child); |
| 703 } |
| 704 mutable_parent->children().swap(new_children); |
| 705 |
| 706 if (store_.get()) |
| 707 store_->ScheduleSave(); |
| 708 } |
| 693 | 709 |
| 694 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 710 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 695 BookmarkNodeChildrenReordered(this, parent)); | 711 BookmarkNodeChildrenReordered(this, parent)); |
| 696 } | 712 } |
| 697 | 713 |
| 698 void BookmarkModel::SetDateFolderModified(const BookmarkNode* parent, | 714 void BookmarkModel::SetDateFolderModified(const BookmarkNode* parent, |
| 699 const Time time) { | 715 const Time time) { |
| 700 DCHECK(parent); | 716 DCHECK(parent); |
| 701 AsMutable(parent)->set_date_folder_modified(time); | 717 AsMutable(parent)->set_date_folder_modified(time); |
| 702 | 718 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 case BookmarkNode::OTHER_NODE: | 761 case BookmarkNode::OTHER_NODE: |
| 746 return other_node_; | 762 return other_node_; |
| 747 case BookmarkNode::MOBILE: | 763 case BookmarkNode::MOBILE: |
| 748 return mobile_node_; | 764 return mobile_node_; |
| 749 default: | 765 default: |
| 750 NOTREACHED(); | 766 NOTREACHED(); |
| 751 return NULL; | 767 return NULL; |
| 752 } | 768 } |
| 753 } | 769 } |
| 754 | 770 |
| 755 void BookmarkModel::RestoreRemovedNode( | 771 void BookmarkModel::RestoreRemovedNode(const BookmarkNode* parent, |
| 756 const BookmarkNode* parent, | 772 int index, |
| 757 int index, | 773 std::unique_ptr<BookmarkNode> node) { |
| 758 std::unique_ptr<BookmarkNode> scoped_node) { | 774 BookmarkNode* node_ptr = node.get(); |
| 759 BookmarkNode* node = scoped_node.release(); | 775 AddNode(AsMutable(parent), index, std::move(node)); |
| 760 AddNode(AsMutable(parent), index, node); | |
| 761 | 776 |
| 762 // We might be restoring a folder node that have already contained a set of | 777 // We might be restoring a folder node that have already contained a set of |
| 763 // child nodes. We need to notify all of them. | 778 // child nodes. We need to notify all of them. |
| 764 NotifyNodeAddedForAllDescendents(node); | 779 NotifyNodeAddedForAllDescendents(node_ptr); |
| 765 } | 780 } |
| 766 | 781 |
| 767 void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) { | 782 void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) { |
| 768 for (int i = 0; i < node->child_count(); ++i) { | 783 for (int i = 0; i < node->child_count(); ++i) { |
| 769 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 784 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 770 BookmarkNodeAdded(this, node, i)); | 785 BookmarkNodeAdded(this, node, i)); |
| 771 NotifyNodeAddedForAllDescendents(node->GetChild(i)); | 786 NotifyNodeAddedForAllDescendents(node->GetChild(i)); |
| 772 } | 787 } |
| 773 } | 788 } |
| 774 | 789 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 tracked_objects::ScopedTracker tracking_profile2( | 834 tracked_objects::ScopedTracker tracking_profile2( |
| 820 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading2")); | 835 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading2")); |
| 821 | 836 |
| 822 // If bookmarks file changed externally, the IDs may have changed | 837 // If bookmarks file changed externally, the IDs may have changed |
| 823 // externally. In that case, the decoder may have reassigned IDs to make | 838 // 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 | 839 // them unique. So when the file has changed externally, we should save the |
| 825 // bookmarks file to persist new IDs. | 840 // bookmarks file to persist new IDs. |
| 826 if (store_.get()) | 841 if (store_.get()) |
| 827 store_->ScheduleSave(); | 842 store_->ScheduleSave(); |
| 828 } | 843 } |
| 829 bookmark_bar_node_ = details->release_bb_node(); | 844 std::unique_ptr<BookmarkPermanentNode> owned_bb_node = |
| 830 other_node_ = details->release_other_folder_node(); | 845 details->owned_bb_node(); |
| 831 mobile_node_ = details->release_mobile_folder_node(); | 846 std::unique_ptr<BookmarkPermanentNode> owned_other_folder_node = |
| 832 index_.reset(details->release_index()); | 847 details->owned_other_folder_node(); |
| 848 std::unique_ptr<BookmarkPermanentNode> owned_mobile_folder_node = |
| 849 details->owned_mobile_folder_node(); |
| 850 index_ = details->owned_index(); |
| 851 |
| 852 bookmark_bar_node_ = owned_bb_node.get(); |
| 853 other_node_ = owned_other_folder_node.get(); |
| 854 mobile_node_ = owned_mobile_folder_node.get(); |
| 833 | 855 |
| 834 // Get any extra nodes and take ownership of them at the |root_|. | 856 // Get any extra nodes and take ownership of them at the |root_|. |
| 835 std::vector<BookmarkPermanentNode*> extra_nodes; | 857 std::vector<std::unique_ptr<BookmarkPermanentNode>> extra_nodes = |
| 836 details->release_extra_nodes(&extra_nodes); | 858 details->owned_extra_nodes(); |
| 837 | 859 |
| 838 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 860 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 839 // is fixed. | 861 // is fixed. |
| 840 tracked_objects::ScopedTracker tracking_profile3( | 862 tracked_objects::ScopedTracker tracking_profile3( |
| 841 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading3")); | 863 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading3")); |
| 842 | 864 |
| 843 // WARNING: order is important here, various places assume the order is | 865 // WARNING: order is important here, various places assume the order is |
| 844 // constant (but can vary between embedders with the initial visibility | 866 // constant (but can vary between embedders with the initial visibility |
| 845 // of permanent nodes). | 867 // of permanent nodes). |
| 846 std::vector<BookmarkPermanentNode*> root_children; | 868 std::vector<std::unique_ptr<BookmarkPermanentNode>> root_children; |
| 847 root_children.push_back(bookmark_bar_node_); | 869 root_children.push_back(std::move(owned_bb_node)); |
| 848 root_children.push_back(other_node_); | 870 root_children.push_back(std::move(owned_other_folder_node)); |
| 849 root_children.push_back(mobile_node_); | 871 root_children.push_back(std::move(owned_mobile_folder_node)); |
| 850 for (size_t i = 0; i < extra_nodes.size(); ++i) | 872 std::move(extra_nodes.begin(), extra_nodes.end(), |
| 851 root_children.push_back(extra_nodes[i]); | 873 std::back_inserter(root_children)); |
| 852 | 874 |
| 853 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 875 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 854 // is fixed. | 876 // is fixed. |
| 855 tracked_objects::ScopedTracker tracking_profile4( | 877 tracked_objects::ScopedTracker tracking_profile4( |
| 856 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading4")); | 878 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading4")); |
| 857 | 879 |
| 858 std::stable_sort(root_children.begin(), | 880 std::stable_sort(root_children.begin(), |
| 859 root_children.end(), | 881 root_children.end(), |
| 860 VisibilityComparator(client_.get())); | 882 VisibilityComparator(client_.get())); |
| 861 for (size_t i = 0; i < root_children.size(); ++i) | 883 for (size_t i = 0; i < root_children.size(); ++i) |
| 862 root_.Add(root_children[i], static_cast<int>(i)); | 884 root_.Add(std::move(root_children[i]), static_cast<int>(i)); |
| 863 | 885 |
| 864 root_.SetMetaInfoMap(details->model_meta_info_map()); | 886 root_.SetMetaInfoMap(details->model_meta_info_map()); |
| 865 root_.set_sync_transaction_version(details->model_sync_transaction_version()); | 887 root_.set_sync_transaction_version(details->model_sync_transaction_version()); |
| 866 | 888 |
| 867 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 889 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 868 // is fixed. | 890 // is fixed. |
| 869 tracked_objects::ScopedTracker tracking_profile5( | 891 tracked_objects::ScopedTracker tracking_profile5( |
| 870 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading5")); | 892 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading5")); |
| 871 | 893 |
| 872 { | 894 { |
| 873 base::AutoLock url_lock(url_lock_); | 895 base::AutoLock url_lock(url_lock_); |
| 874 // Update nodes_ordered_by_url_set_ from the nodes. | 896 // Update nodes_ordered_by_url_set_ from the nodes. |
| 875 PopulateNodesByURL(&root_); | 897 PopulateNodesByURL(&root_); |
| 876 } | 898 } |
| 877 | 899 |
| 878 loaded_ = true; | 900 loaded_ = true; |
| 879 | 901 |
| 880 loaded_signal_.Signal(); | 902 loaded_signal_.Signal(); |
| 881 | 903 |
| 882 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 | 904 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 |
| 883 // is fixed. | 905 // is fixed. |
| 884 tracked_objects::ScopedTracker tracking_profile6( | 906 tracked_objects::ScopedTracker tracking_profile6( |
| 885 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading6")); | 907 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading6")); |
| 886 | 908 |
| 887 // Notify our direct observers. | 909 // Notify our direct observers. |
| 888 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 910 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 889 BookmarkModelLoaded(this, details->ids_reassigned())); | 911 BookmarkModelLoaded(this, details->ids_reassigned())); |
| 890 } | 912 } |
| 891 | 913 |
| 892 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { | 914 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* node_ptr) { |
| 893 std::unique_ptr<BookmarkNode> node(delete_me); | 915 std::unique_ptr<BookmarkNode> node; |
| 894 | 916 |
| 895 const BookmarkNode* parent = node->parent(); | 917 const BookmarkNode* parent = node_ptr->parent(); |
| 896 DCHECK(parent); | 918 DCHECK(parent); |
| 897 int index = parent->GetIndexOf(node.get()); | 919 int index = parent->GetIndexOf(node_ptr); |
| 898 DCHECK_NE(-1, index); | 920 DCHECK_NE(-1, index); |
| 899 | 921 |
| 900 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 922 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 901 OnWillRemoveBookmarks(this, parent, index, node.get())); | 923 OnWillRemoveBookmarks(this, parent, index, node_ptr)); |
| 902 | 924 |
| 903 std::set<GURL> removed_urls; | 925 std::set<GURL> removed_urls; |
| 904 { | 926 { |
| 905 base::AutoLock url_lock(url_lock_); | 927 base::AutoLock url_lock(url_lock_); |
| 906 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); | 928 node = RemoveNodeAndGetRemovedUrls(node_ptr, &removed_urls); |
| 907 } | 929 } |
| 908 | 930 |
| 909 if (store_.get()) | 931 if (store_.get()) |
| 910 store_->ScheduleSave(); | 932 store_->ScheduleSave(); |
| 911 | 933 |
| 912 FOR_EACH_OBSERVER( | 934 FOR_EACH_OBSERVER( |
| 913 BookmarkModelObserver, | 935 BookmarkModelObserver, |
| 914 observers_, | 936 observers_, |
| 915 BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls)); | 937 BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls)); |
| 916 | 938 |
| 917 undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, std::move(node)); | 939 undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, std::move(node)); |
| 918 } | 940 } |
| 919 | 941 |
| 920 void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) { | 942 void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) { |
| 921 index_->Remove(node); | 943 index_->Remove(node); |
| 922 // NOTE: this is called in such a way that url_lock_ is already held. As | 944 // NOTE: this is called in such a way that url_lock_ is already held. As |
| 923 // such, this doesn't explicitly grab the lock. | 945 // such, this doesn't explicitly grab the lock. |
| 924 url_lock_.AssertAcquired(); | 946 url_lock_.AssertAcquired(); |
| 925 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); | 947 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); |
| 926 DCHECK(i != nodes_ordered_by_url_set_.end()); | 948 DCHECK(i != nodes_ordered_by_url_set_.end()); |
| 927 // i points to the first node with the URL, advance until we find the | 949 // i points to the first node with the URL, advance until we find the |
| 928 // node we're removing. | 950 // node we're removing. |
| 929 while (*i != node) | 951 while (*i != node) |
| 930 ++i; | 952 ++i; |
| 931 nodes_ordered_by_url_set_.erase(i); | 953 nodes_ordered_by_url_set_.erase(i); |
| 932 } | 954 } |
| 933 | 955 |
| 934 void BookmarkModel::RemoveNodeAndGetRemovedUrls(BookmarkNode* node, | 956 std::unique_ptr<BookmarkNode> BookmarkModel::RemoveNodeAndGetRemovedUrls( |
| 935 std::set<GURL>* removed_urls) { | 957 BookmarkNode* node_ptr, |
| 958 std::set<GURL>* removed_urls) { |
| 936 // NOTE: this method should be always called with |url_lock_| held. | 959 // NOTE: this method should be always called with |url_lock_| held. |
| 937 // This method does not explicitly acquires a lock. | 960 // This method does not explicitly acquires a lock. |
| 938 url_lock_.AssertAcquired(); | 961 url_lock_.AssertAcquired(); |
| 939 DCHECK(removed_urls); | 962 DCHECK(removed_urls); |
| 940 BookmarkNode* parent = node->parent(); | 963 BookmarkNode* parent = node_ptr->parent(); |
| 941 DCHECK(parent); | 964 DCHECK(parent); |
| 942 parent->Remove(node); | 965 std::unique_ptr<BookmarkNode> node = parent->Remove(node_ptr); |
| 943 RemoveNode(node, removed_urls); | 966 RemoveNode(node_ptr, removed_urls); |
| 944 // RemoveNode adds an entry to removed_urls for each node of type URL. As we | 967 // 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. | 968 // allow duplicates we need to remove any entries that are still bookmarked. |
| 946 for (std::set<GURL>::iterator i = removed_urls->begin(); | 969 for (std::set<GURL>::iterator i = removed_urls->begin(); |
| 947 i != removed_urls->end();) { | 970 i != removed_urls->end();) { |
| 948 if (IsBookmarkedNoLock(*i)) { | 971 if (IsBookmarkedNoLock(*i)) { |
| 949 // When we erase the iterator pointing at the erasee is | 972 // When we erase the iterator pointing at the erasee is |
| 950 // invalidated, so using i++ here within the "erase" call is | 973 // invalidated, so using i++ here within the "erase" call is |
| 951 // important as it advances the iterator before passing the | 974 // important as it advances the iterator before passing the |
| 952 // old value through to erase. | 975 // old value through to erase. |
| 953 removed_urls->erase(i++); | 976 removed_urls->erase(i++); |
| 954 } else { | 977 } else { |
| 955 ++i; | 978 ++i; |
| 956 } | 979 } |
| 957 } | 980 } |
| 981 |
| 982 return node; |
| 958 } | 983 } |
| 959 | 984 |
| 960 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, | 985 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
| 961 int index, | 986 int index, |
| 962 BookmarkNode* node) { | 987 std::unique_ptr<BookmarkNode> node) { |
| 963 parent->Add(node, index); | 988 BookmarkNode* node_ptr = node.get(); |
| 989 parent->Add(std::move(node), index); |
| 964 | 990 |
| 965 if (store_.get()) | 991 if (store_.get()) |
| 966 store_->ScheduleSave(); | 992 store_->ScheduleSave(); |
| 967 | 993 |
| 968 { | 994 { |
| 969 base::AutoLock url_lock(url_lock_); | 995 base::AutoLock url_lock(url_lock_); |
| 970 AddNodeToInternalMaps(node); | 996 AddNodeToInternalMaps(node_ptr); |
| 971 } | 997 } |
| 972 | 998 |
| 973 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 999 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 974 BookmarkNodeAdded(this, parent, index)); | 1000 BookmarkNodeAdded(this, parent, index)); |
| 975 | 1001 |
| 976 return node; | 1002 return node_ptr; |
| 977 } | 1003 } |
| 978 | 1004 |
| 979 void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) { | 1005 void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) { |
| 980 url_lock_.AssertAcquired(); | 1006 url_lock_.AssertAcquired(); |
| 981 if (node->is_url()) { | 1007 if (node->is_url()) { |
| 982 index_->Add(node); | 1008 index_->Add(node); |
| 983 nodes_ordered_by_url_set_.insert(node); | 1009 nodes_ordered_by_url_set_.insert(node); |
| 984 } | 1010 } |
| 985 for (int i = 0; i < node->child_count(); ++i) | 1011 for (int i = 0; i < node->child_count(); ++i) |
| 986 AddNodeToInternalMaps(node->GetChild(i)); | 1012 AddNodeToInternalMaps(node->GetChild(i)); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 undo_delegate_ = undo_delegate; | 1131 undo_delegate_ = undo_delegate; |
| 1106 if (undo_delegate_) | 1132 if (undo_delegate_) |
| 1107 undo_delegate_->SetUndoProvider(this); | 1133 undo_delegate_->SetUndoProvider(this); |
| 1108 } | 1134 } |
| 1109 | 1135 |
| 1110 BookmarkUndoDelegate* BookmarkModel::undo_delegate() const { | 1136 BookmarkUndoDelegate* BookmarkModel::undo_delegate() const { |
| 1111 return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get(); | 1137 return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get(); |
| 1112 } | 1138 } |
| 1113 | 1139 |
| 1114 } // namespace bookmarks | 1140 } // namespace bookmarks |
| OLD | NEW |