| Index: components/enhanced_bookmarks/enhanced_bookmark_model.cc
|
| diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.cc b/components/enhanced_bookmarks/enhanced_bookmark_model.cc
|
| index a20e38bac31b494cd8b63e2ff329fd38d645477e..013f45753f28acddfa8c6e295c822ba79f16e0de 100644
|
| --- a/components/enhanced_bookmarks/enhanced_bookmark_model.cc
|
| +++ b/components/enhanced_bookmarks/enhanced_bookmark_model.cc
|
| @@ -9,10 +9,13 @@
|
|
|
| #include "base/base64.h"
|
| #include "base/logging.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| #include "base/rand_util.h"
|
| #include "components/bookmarks/browser/bookmark_model.h"
|
| #include "components/bookmarks/browser/bookmark_node.h"
|
| +#include "components/enhanced_bookmarks/enhanced_bookmark_model_observer.h"
|
| #include "components/enhanced_bookmarks/proto/metadata.pb.h"
|
| +#include "ui/base/models/tree_node_iterator.h"
|
| #include "url/gurl.h"
|
|
|
| namespace {
|
| @@ -21,11 +24,10 @@ const char* kBookmarkBarId = "f_bookmarks_bar";
|
| const char* kIdKey = "stars.id";
|
| const char* kImageDataKey = "stars.imageData";
|
| const char* kNoteKey = "stars.note";
|
| +const char* kOldIdKey = "stars.oldId";
|
| const char* kPageDataKey = "stars.pageData";
|
| -const char* kUserEditKey = "stars.userEdit";
|
| const char* kVersionKey = "stars.version";
|
|
|
| -const char* kFolderPrefix = "ebf_";
|
| const char* kBookmarkPrefix = "ebc_";
|
|
|
| // Helper method for working with bookmark metainfo.
|
| @@ -62,13 +64,9 @@ bool PopulateImageData(const image::collections::ImageData_ImageInfo& info,
|
|
|
| // Generate a random remote id, with a prefix that depends on whether the node
|
| // is a folder or a bookmark.
|
| -std::string GenerateRemoteId(bool is_folder) {
|
| +std::string GenerateRemoteId() {
|
| std::stringstream random_id;
|
| - // Add prefix depending on whether the node is a folder or not.
|
| - if (is_folder)
|
| - random_id << kFolderPrefix;
|
| - else
|
| - random_id << kBookmarkPrefix;
|
| + random_id << kBookmarkPrefix;
|
|
|
| // Generate 32 digit hex string random suffix.
|
| random_id << std::hex << std::setfill('0') << std::setw(16);
|
| @@ -81,17 +79,43 @@ namespace enhanced_bookmarks {
|
|
|
| EnhancedBookmarkModel::EnhancedBookmarkModel(BookmarkModel* bookmark_model,
|
| const std::string& version)
|
| - : bookmark_model_(bookmark_model), version_(version) {
|
| + : bookmark_model_(bookmark_model),
|
| + loaded_(false),
|
| + weak_ptr_factory_(this),
|
| + version_(version) {
|
| + bookmark_model_->AddObserver(this);
|
| + if (bookmark_model_->loaded()) {
|
| + InitializeIdMap();
|
| + loaded_ = true;
|
| + }
|
| }
|
|
|
| EnhancedBookmarkModel::~EnhancedBookmarkModel() {
|
| }
|
|
|
| +void EnhancedBookmarkModel::ShutDown() {
|
| + FOR_EACH_OBSERVER(EnhancedBookmarkModelObserver,
|
| + observers_,
|
| + EnhancedBookmarkModelShuttingDown());
|
| + weak_ptr_factory_.InvalidateWeakPtrs();
|
| + bookmark_model_->RemoveObserver(this);
|
| + bookmark_model_ = NULL;
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::AddObserver(
|
| + EnhancedBookmarkModelObserver* observer) {
|
| + observers_.AddObserver(observer);
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::RemoveObserver(
|
| + EnhancedBookmarkModelObserver* observer) {
|
| + observers_.RemoveObserver(observer);
|
| +}
|
| +
|
| // Moves |node| to |new_parent| and inserts it at the given |index|.
|
| void EnhancedBookmarkModel::Move(const BookmarkNode* node,
|
| const BookmarkNode* new_parent,
|
| int index) {
|
| - // TODO(rfevang): Update meta info placement fields.
|
| bookmark_model_->Move(node, new_parent, index);
|
| }
|
|
|
| @@ -100,12 +124,7 @@ const BookmarkNode* EnhancedBookmarkModel::AddFolder(
|
| const BookmarkNode* parent,
|
| int index,
|
| const base::string16& title) {
|
| - BookmarkNode::MetaInfoMap meta_info;
|
| - meta_info[kIdKey] = GenerateRemoteId(true);
|
| -
|
| - // TODO(rfevang): Set meta info placement fields.
|
| - return bookmark_model_->AddFolderWithMetaInfo(
|
| - parent, index, title, &meta_info);
|
| + return bookmark_model_->AddFolder(parent, index, title);
|
| }
|
|
|
| // Adds a url at the specified position.
|
| @@ -116,9 +135,7 @@ const BookmarkNode* EnhancedBookmarkModel::AddURL(
|
| const GURL& url,
|
| const base::Time& creation_time) {
|
| BookmarkNode::MetaInfoMap meta_info;
|
| - meta_info[kIdKey] = GenerateRemoteId(false);
|
| -
|
| - // TODO(rfevang): Set meta info placement fields.
|
| + meta_info[kIdKey] = GenerateRemoteId();
|
| return bookmark_model_->AddURLWithCreationTimeAndMetaInfo(
|
| parent, index, title, url, creation_time, &meta_info);
|
| }
|
| @@ -127,24 +144,23 @@ std::string EnhancedBookmarkModel::GetRemoteId(const BookmarkNode* node) {
|
| if (node == bookmark_model_->bookmark_bar_node())
|
| return kBookmarkBarId;
|
|
|
| - // Permanent nodes other than the bookmarks bar don't have ids.
|
| - DCHECK(!bookmark_model_->is_permanent_node(node));
|
| -
|
| std::string id;
|
| - if (!node->GetMetaInfo(kIdKey, &id) || id.empty())
|
| - return SetRemoteId(node);
|
| + if (!node->GetMetaInfo(kIdKey, &id))
|
| + return std::string();
|
| return id;
|
| }
|
|
|
| -std::string EnhancedBookmarkModel::SetRemoteId(const BookmarkNode* node) {
|
| - std::string remote_id = GenerateRemoteId(node->is_folder());
|
| - SetMetaInfo(node, kIdKey, remote_id, false);
|
| - return remote_id;
|
| +const BookmarkNode* EnhancedBookmarkModel::BookmarkForRemoteId(
|
| + const std::string& remote_id) {
|
| + IdToNodeMap::iterator it = id_map_.find(remote_id);
|
| + if (it != id_map_.end())
|
| + return it->second;
|
| + return NULL;
|
| }
|
|
|
| void EnhancedBookmarkModel::SetDescription(const BookmarkNode* node,
|
| const std::string& description) {
|
| - SetMetaInfo(node, kNoteKey, description, true);
|
| + SetMetaInfo(node, kNoteKey, description);
|
| }
|
|
|
| std::string EnhancedBookmarkModel::GetDescription(const BookmarkNode* node) {
|
| @@ -189,9 +205,7 @@ bool EnhancedBookmarkModel::SetOriginalImage(const BookmarkNode* node,
|
|
|
| std::string encoded;
|
| base::Base64Encode(output, &encoded);
|
| - SetMetaInfo(node, kImageDataKey, encoded, true);
|
| - // Ensure that the bookmark has a stars.id, to trigger the server processing.
|
| - GetRemoteId(node);
|
| + SetMetaInfo(node, kImageDataKey, encoded);
|
| return true;
|
| }
|
|
|
| @@ -251,10 +265,120 @@ void EnhancedBookmarkModel::SetVersionSuffix(
|
| version_suffix_ = version_suffix;
|
| }
|
|
|
| +void EnhancedBookmarkModel::BookmarkModelChanged() {
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::BookmarkModelLoaded(BookmarkModel* model,
|
| + bool ids_reassigned) {
|
| + InitializeIdMap();
|
| + FOR_EACH_OBSERVER(
|
| + EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkModelLoaded());
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::BookmarkNodeAdded(BookmarkModel* model,
|
| + const BookmarkNode* parent,
|
| + int index) {
|
| + const BookmarkNode* node = parent->GetChild(index);
|
| + AddToIdMap(node);
|
| + ScheduleResetDuplicateRemoteIds();
|
| + FOR_EACH_OBSERVER(
|
| + EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkAdded(node));
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::BookmarkNodeRemoved(
|
| + BookmarkModel* model,
|
| + const BookmarkNode* parent,
|
| + int old_index,
|
| + const BookmarkNode* node,
|
| + const std::set<GURL>& removed_urls) {
|
| + std::string remote_id = GetRemoteId(node);
|
| + id_map_.erase(remote_id);
|
| + FOR_EACH_OBSERVER(
|
| + EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkRemoved(node));
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::OnWillChangeBookmarkMetaInfo(
|
| + BookmarkModel* model,
|
| + const BookmarkNode* node) {
|
| + prev_remote_id_ = GetRemoteId(node);
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::BookmarkMetaInfoChanged(BookmarkModel* model,
|
| + const BookmarkNode* node) {
|
| + std::string remote_id = GetRemoteId(node);
|
| + if (remote_id != prev_remote_id_) {
|
| + id_map_.erase(prev_remote_id_);
|
| + if (!remote_id.empty()) {
|
| + AddToIdMap(node);
|
| + ScheduleResetDuplicateRemoteIds();
|
| + }
|
| + FOR_EACH_OBSERVER(
|
| + EnhancedBookmarkModelObserver,
|
| + observers_,
|
| + EnhancedBookmarkRemoteIdChanged(node, prev_remote_id_, remote_id));
|
| + }
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::BookmarkAllUserNodesRemoved(
|
| + BookmarkModel* model,
|
| + const std::set<GURL>& removed_urls) {
|
| + id_map_.clear();
|
| + // Re-initialize so non-user nodes with remote ids are present in the map.
|
| + InitializeIdMap();
|
| + FOR_EACH_OBSERVER(EnhancedBookmarkModelObserver,
|
| + observers_,
|
| + EnhancedBookmarkAllUserNodesRemoved());
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::InitializeIdMap() {
|
| + ui::TreeNodeIterator<const BookmarkNode> iterator(
|
| + bookmark_model_->root_node());
|
| + while (iterator.has_next()) {
|
| + AddToIdMap(iterator.Next());
|
| + }
|
| + ScheduleResetDuplicateRemoteIds();
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::AddToIdMap(const BookmarkNode* node) {
|
| + std::string remote_id = GetRemoteId(node);
|
| + if (remote_id.empty())
|
| + return;
|
| +
|
| + // Try to insert the node.
|
| + std::pair<IdToNodeMap::iterator, bool> result =
|
| + id_map_.insert(make_pair(remote_id, node));
|
| + if (!result.second) {
|
| + // Some node already had the same remote id, so add both nodes to the
|
| + // to-be-reset set.
|
| + nodes_to_reset_[result.first->second] = remote_id;
|
| + nodes_to_reset_[node] = remote_id;
|
| + }
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::ScheduleResetDuplicateRemoteIds() {
|
| + if (!nodes_to_reset_.empty()) {
|
| + base::MessageLoopProxy::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&EnhancedBookmarkModel::ResetDuplicateRemoteIds,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| + }
|
| +}
|
| +
|
| +void EnhancedBookmarkModel::ResetDuplicateRemoteIds() {
|
| + for (NodeToIdMap::iterator it = nodes_to_reset_.begin();
|
| + it != nodes_to_reset_.end();
|
| + ++it) {
|
| + BookmarkNode::MetaInfoMap meta_info;
|
| + meta_info[kIdKey] = "";
|
| + meta_info[kOldIdKey] = it->second;
|
| + SetMultipleMetaInfo(it->first, meta_info);
|
| + }
|
| + nodes_to_reset_.clear();
|
| +}
|
| +
|
| void EnhancedBookmarkModel::SetMetaInfo(const BookmarkNode* node,
|
| const std::string& field,
|
| - const std::string& value,
|
| - bool user_edit) {
|
| + const std::string& value) {
|
| DCHECK(!bookmark_model_->is_permanent_node(node));
|
|
|
| BookmarkNode::MetaInfoMap meta_info;
|
| @@ -269,7 +393,6 @@ void EnhancedBookmarkModel::SetMetaInfo(const BookmarkNode* node,
|
|
|
| meta_info[field] = value;
|
| meta_info[kVersionKey] = GetVersionString();
|
| - meta_info[kUserEditKey] = user_edit ? "true" : "false";
|
| bookmark_model_->SetNodeMetaInfoMap(node, meta_info);
|
| }
|
|
|
| @@ -279,6 +402,37 @@ std::string EnhancedBookmarkModel::GetVersionString() {
|
| return version_ + '/' + version_suffix_;
|
| }
|
|
|
| +void EnhancedBookmarkModel::SetMultipleMetaInfo(
|
| + const BookmarkNode* node,
|
| + BookmarkNode::MetaInfoMap meta_info) {
|
| + DCHECK(!bookmark_model_->is_permanent_node(node));
|
| +
|
| + // Don't update anything if every value is already set correctly.
|
| + if (node->GetMetaInfoMap()) {
|
| + bool changed = false;
|
| + const BookmarkNode::MetaInfoMap* old_meta_info = node->GetMetaInfoMap();
|
| + for (BookmarkNode::MetaInfoMap::iterator it = meta_info.begin();
|
| + it != meta_info.end();
|
| + ++it) {
|
| + BookmarkNode::MetaInfoMap::const_iterator old_field =
|
| + old_meta_info->find(it->first);
|
| + if (old_field == old_meta_info->end() ||
|
| + old_field->second != it->second) {
|
| + changed = true;
|
| + break;
|
| + }
|
| + }
|
| + if (!changed)
|
| + return;
|
| +
|
| + // Fill in the values that aren't changing
|
| + meta_info.insert(old_meta_info->begin(), old_meta_info->end());
|
| + }
|
| +
|
| + meta_info[kVersionKey] = GetVersionString();
|
| + bookmark_model_->SetNodeMetaInfoMap(node, meta_info);
|
| +}
|
| +
|
| bool EnhancedBookmarkModel::SetAllImages(const BookmarkNode* node,
|
| const GURL& image_url,
|
| int image_width,
|
|
|