Index: components/bookmarks/browser/bookmark_model.cc |
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc |
index cf969748c6fb5b5751c50bfade02a6d224f790d7..9a5daf6fad87bd72214ee0e2c17a03e729eceb56 100644 |
--- a/components/bookmarks/browser/bookmark_model.cc |
+++ b/components/bookmarks/browser/bookmark_model.cc |
@@ -49,18 +49,18 @@ class VisibilityComparator |
const BookmarkPermanentNode*, |
bool> { |
public: |
- explicit VisibilityComparator(BookmarkClient* client) : client_(client) {} |
+ explicit VisibilityComparator(BookmarkModel* model) : model_(model) {} |
// Returns true if |n1| preceeds |n2|. |
bool operator()(const BookmarkPermanentNode* n1, |
const BookmarkPermanentNode* n2) { |
- bool n1_visible = client_->IsPermanentNodeVisible(n1); |
- bool n2_visible = client_->IsPermanentNodeVisible(n2); |
+ bool n1_visible = model_->IsPermanentNodeVisible(n1); |
+ bool n2_visible = model_->IsPermanentNodeVisible(n2); |
return n1_visible != n2_visible && n1_visible; |
} |
private: |
- BookmarkClient* client_; |
+ BookmarkModel* model_; |
}; |
// Comparator used when sorting bookmarks. Folders are sorted first, then |
@@ -96,9 +96,11 @@ BookmarkModel::BookmarkModel(BookmarkClient* client) |
: client_(client), |
loaded_(false), |
root_(GURL()), |
- bookmark_bar_node_(NULL), |
- other_node_(NULL), |
- mobile_node_(NULL), |
+ bookmark_bar_node_(nullptr), |
+ other_node_(nullptr), |
+ mobile_node_(nullptr), |
+ managed_node_(nullptr), |
+ supervised_node_(nullptr), |
next_node_id_(1), |
observers_( |
base::ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), |
@@ -212,7 +214,7 @@ void BookmarkModel::RemoveAllUserBookmarks() { |
for (int i = 0; i < root_.child_count(); ++i) { |
BookmarkNode* permanent_node = root_.GetChild(i); |
- if (!client_->CanBeEditedByUser(permanent_node)) |
+ if (!CanBeEditedByUser(permanent_node)) |
continue; |
for (int j = permanent_node->child_count() - 1; j >= 0; --j) { |
@@ -299,8 +301,8 @@ const gfx::Image& BookmarkModel::GetFavicon(const BookmarkNode* node) { |
if (node->favicon_state() == BookmarkNode::INVALID_FAVICON) { |
BookmarkNode* mutable_node = AsMutable(node); |
LoadFavicon(mutable_node, |
- client_->PreferTouchIcon() ? favicon_base::TOUCH_ICON |
- : favicon_base::FAVICON); |
+ PreferTouchIcon() ? favicon_base::TOUCH_ICON |
+ : favicon_base::FAVICON); |
} |
return node->favicon(); |
} |
@@ -317,7 +319,7 @@ void BookmarkModel::SetTitle(const BookmarkNode* node, |
if (node->GetTitle() == title) |
return; |
- if (is_permanent_node(node) && !client_->CanSetPermanentNodeTitle(node)) { |
+ if (is_permanent_node(node) && !CanSetPermanentNodeTitle(node)) { |
NOTREACHED(); |
return; |
} |
@@ -424,7 +426,7 @@ void BookmarkModel::AddNonClonedKey(const std::string& key) { |
void BookmarkModel::SetNodeSyncTransactionVersion( |
const BookmarkNode* node, |
int64 sync_transaction_version) { |
- DCHECK(client_->CanSyncNode(node)); |
+ DCHECK(CanSyncNode(node)); |
if (sync_transaction_version == node->sync_transaction_version()) |
return; |
@@ -455,6 +457,31 @@ void BookmarkModel::OnFaviconChanged(const std::set<GURL>& urls) { |
} |
} |
+bool BookmarkModel::CanSyncNode(const BookmarkNode* node) { |
+ return !bookmarks::IsDescendantOf(node, managed_node_) && |
+ !bookmarks::IsDescendantOf(node, supervised_node_); |
+} |
+ |
+bool BookmarkModel::CanBeEditedByUser(const BookmarkNode* node) { |
+ return !bookmarks::IsDescendantOf(node, managed_node_) && |
+ !bookmarks::IsDescendantOf(node, supervised_node_); |
+} |
+ |
+bool BookmarkModel::IsPermanentNodeVisible(const BookmarkPermanentNode* node) { |
+ DCHECK(IsTopLevelPermanentNode(node)); |
+ if (node == supervised_node_ || node == managed_node_) |
+ return false; |
+#if !defined(OS_IOS) |
+ return node->type() != BookmarkNode::MOBILE; |
+#else |
+ return node->type() == BookmarkNode::MOBILE; |
+#endif |
+} |
+ |
+void BookmarkModel::RecordAction(const base::UserMetricsAction& action) { |
+ client_->RecordAction(action); |
+} |
+ |
void BookmarkModel::SetDateAdded(const BookmarkNode* node, Time date_added) { |
DCHECK(node && !is_permanent_node(node)); |
@@ -491,11 +518,11 @@ const BookmarkNode* BookmarkModel::GetMostRecentlyAddedUserNodeForURL( |
// Look for the first node that the user can edit. |
for (size_t i = 0; i < nodes.size(); ++i) { |
- if (client_->CanBeEditedByUser(nodes[i])) |
+ if (CanBeEditedByUser(nodes[i])) |
return nodes[i]; |
} |
- return NULL; |
+ return nullptr; |
} |
bool BookmarkModel::HasBookmarks() { |
@@ -511,7 +538,7 @@ bool BookmarkModel::IsBookmarked(const GURL& url) { |
void BookmarkModel::GetBookmarks( |
std::vector<BookmarkModel::URLAndTitle>* bookmarks) { |
base::AutoLock url_lock(url_lock_); |
- const GURL* last_url = NULL; |
+ const GURL* last_url = nullptr; |
for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); |
i != nodes_ordered_by_url_set_.end(); ++i) { |
const GURL* url = &((*i)->url()); |
@@ -533,7 +560,7 @@ void BookmarkModel::BlockTillLoaded() { |
const BookmarkNode* BookmarkModel::AddFolder(const BookmarkNode* parent, |
int index, |
const base::string16& title) { |
- return AddFolderWithMetaInfo(parent, index, title, NULL); |
+ return AddFolderWithMetaInfo(parent, index, title, nullptr); |
} |
const BookmarkNode* BookmarkModel::AddFolderWithMetaInfo( |
const BookmarkNode* parent, |
@@ -543,7 +570,7 @@ const BookmarkNode* BookmarkModel::AddFolderWithMetaInfo( |
if (!loaded_ || is_root_node(parent) || !IsValidIndex(parent, index, true)) { |
// Can't add to the root. |
NOTREACHED(); |
- return NULL; |
+ return nullptr; |
} |
BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), GURL()); |
@@ -567,7 +594,7 @@ const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent, |
base::CollapseWhitespace(title, false), |
url, |
Time::Now(), |
- NULL); |
+ nullptr); |
} |
const BookmarkNode* BookmarkModel::AddURLWithCreationTimeAndMetaInfo( |
@@ -580,7 +607,7 @@ const BookmarkNode* BookmarkModel::AddURLWithCreationTimeAndMetaInfo( |
if (!loaded_ || !url.is_valid() || is_root_node(parent) || |
!IsValidIndex(parent, index, true)) { |
NOTREACHED(); |
- return NULL; |
+ return nullptr; |
} |
// Syncing may result in dates newer than the last modified date. |
@@ -598,7 +625,7 @@ const BookmarkNode* BookmarkModel::AddURLWithCreationTimeAndMetaInfo( |
} |
void BookmarkModel::SortChildren(const BookmarkNode* parent) { |
- DCHECK(client_->CanBeEditedByUser(parent)); |
+ DCHECK(CanBeEditedByUser(parent)); |
if (!parent || !parent->is_folder() || is_root_node(parent) || |
parent->child_count() <= 1) { |
@@ -611,7 +638,7 @@ void BookmarkModel::SortChildren(const BookmarkNode* parent) { |
UErrorCode error = U_ZERO_ERROR; |
scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); |
if (U_FAILURE(error)) |
- collator.reset(NULL); |
+ collator.reset(nullptr); |
BookmarkNode* mutable_parent = AsMutable(parent); |
std::sort(mutable_parent->children().begin(), |
mutable_parent->children().end(), |
@@ -627,7 +654,7 @@ void BookmarkModel::SortChildren(const BookmarkNode* parent) { |
void BookmarkModel::ReorderChildren( |
const BookmarkNode* parent, |
const std::vector<const BookmarkNode*>& ordered_nodes) { |
- DCHECK(client_->CanBeEditedByUser(parent)); |
+ DCHECK(CanBeEditedByUser(parent)); |
// Ensure that all children in |parent| are in |ordered_nodes|. |
DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); |
@@ -685,7 +712,7 @@ void BookmarkModel::ClearStore() { |
void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, |
bool value) { |
BookmarkPermanentNode* node = AsMutable(PermanentNode(type)); |
- node->set_visible(value || client_->IsPermanentNodeVisible(node)); |
+ node->set_visible(value || IsPermanentNodeVisible(node)); |
} |
const BookmarkPermanentNode* BookmarkModel::PermanentNode( |
@@ -700,7 +727,7 @@ const BookmarkPermanentNode* BookmarkModel::PermanentNode( |
return mobile_node_; |
default: |
NOTREACHED(); |
- return NULL; |
+ return nullptr; |
} |
} |
@@ -789,7 +816,7 @@ void BookmarkModel::DoneLoading(scoped_ptr<BookmarkLoadDetails> details) { |
std::stable_sort(root_children.begin(), |
root_children.end(), |
- VisibilityComparator(client_)); |
+ VisibilityComparator(this)); |
for (size_t i = 0; i < root_children.size(); ++i) |
root_.Add(root_children[i], static_cast<int>(i)); |
@@ -819,6 +846,9 @@ void BookmarkModel::DoneLoading(scoped_ptr<BookmarkLoadDetails> details) { |
// Notify our direct observers. |
FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
BookmarkModelLoaded(this, details->ids_reassigned())); |
+ |
+ // Notify client. |
+ client_->DoneLoading(managed_node_, supervised_node_); |
} |
void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { |
@@ -930,7 +960,7 @@ BookmarkPermanentNode* BookmarkModel::CreatePermanentNode( |
BookmarkPermanentNode* node = |
new BookmarkPermanentNode(generate_next_node_id()); |
node->set_type(type); |
- node->set_visible(client_->IsPermanentNodeVisible(node)); |
+ node->set_visible(IsPermanentNodeVisible(node)); |
int title_id; |
switch (type) { |
@@ -966,7 +996,7 @@ void BookmarkModel::OnFaviconDataAvailable( |
FaviconLoaded(node); |
} else if (icon_type == favicon_base::TOUCH_ICON) { |
// Couldn't load the touch icon, fallback to the regular favicon. |
- DCHECK(client_->PreferTouchIcon()); |
+ DCHECK(PreferTouchIcon()); |
LoadFavicon(node, favicon_base::FAVICON); |
} |
} |
@@ -1025,13 +1055,52 @@ scoped_ptr<BookmarkLoadDetails> BookmarkModel::CreateLoadDetails( |
CreatePermanentNode(BookmarkNode::OTHER_NODE); |
BookmarkPermanentNode* mobile_node = |
CreatePermanentNode(BookmarkNode::MOBILE); |
+ // Create the managed_node and supervised_node with a temporary id of 0 now. |
+ // They will be populated and assigned property ids by the LoadExtraCallback |
+ // returned by GetLoadExtraNodesCallback(). Ownership of the node is |
+ // transferred to the closure. |
+ scoped_ptr<BookmarkPermanentNode> managed_node(new BookmarkPermanentNode(0)); |
+ scoped_ptr<BookmarkPermanentNode> supervised_node( |
+ new BookmarkPermanentNode(0)); |
return scoped_ptr<BookmarkLoadDetails>(new BookmarkLoadDetails( |
- bb_node, |
- other_node, |
- mobile_node, |
- client_->GetLoadExtraNodesCallback(), |
- new BookmarkIndex(client_, accept_languages), |
- next_node_id_)); |
+ bb_node, other_node, mobile_node, |
+ client_->GetLoadExtraNodesCallback( |
+ managed_node.Pass(), supervised_node.Pass(), |
+ base::Bind(&BookmarkModel::OnExtraNodeLoaded, |
+ base::Unretained(this))), |
+ new BookmarkIndex(client_, accept_languages), next_node_id_)); |
+} |
+ |
+void BookmarkModel::OnExtraNodeLoaded(BookmarkPermanentNode* managed_node, |
+ BookmarkPermanentNode* supervised_node) { |
+ managed_node_ = managed_node; |
+ supervised_node_ = supervised_node; |
+} |
+ |
+bool BookmarkModel::IsTopLevelPermanentNode(const BookmarkPermanentNode* node) { |
+ return node->type() == BookmarkNode::BOOKMARK_BAR || |
+ node->type() == BookmarkNode::OTHER_NODE || |
+ node->type() == BookmarkNode::MOBILE || |
+ node == supervised_node_ || |
+ node == managed_node_; |
+} |
+ |
+bool BookmarkModel::CanSetPermanentNodeTitle(const BookmarkNode* node) { |
+ // The |managed_node_| can have its title updated if the user signs in or |
+ // out, since the name of the managed domain can appear in it. |
+ // Also, both |managed_node_| and |supervised_node_| can have their title |
+ // updated on locale changes (crbug.com/459448). |
+ return (!bookmarks::IsDescendantOf(node, managed_node_) && |
+ !bookmarks::IsDescendantOf(node, supervised_node_)) || |
+ node == managed_node_ || node == supervised_node_; |
+} |
+ |
+bool BookmarkModel::PreferTouchIcon() { |
+#if !defined(OS_IOS) |
+ return false; |
+#else |
+ return true; |
+#endif |
} |
} // namespace bookmarks |