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
3// found in the LICENSE file.
4
5#include "components/bookmarks/browser/bookmark_node.h"
6
7#include <map>
8#include <string>
9
10#include "base/strings/string_util.h"
11#include "base/strings/utf_string_conversions.h"
12
13namespace {
14
15// Whitespace characters to strip from bookmark titles.
16const base::char16 kInvalidChars[] = {
17  '\n', '\r', '\t',
18  0x2028,  // Line separator
19  0x2029,  // Paragraph separator
20  0
21};
22
23}  // namespace
24
25// BookmarkNode ---------------------------------------------------------------
26
27const int64 BookmarkNode::kInvalidSyncTransactionVersion = -1;
28
29BookmarkNode::BookmarkNode(const GURL& url)
30    : url_(url) {
31  Initialize(0);
32}
33
34BookmarkNode::BookmarkNode(int64 id, const GURL& url)
35    : url_(url) {
36  Initialize(id);
37}
38
39BookmarkNode::~BookmarkNode() {
40}
41
42void BookmarkNode::SetTitle(const base::string16& title) {
43  // Replace newlines and other problematic whitespace characters in
44  // folder/bookmark names with spaces.
45  base::string16 trimmed_title;
46  base::ReplaceChars(title, kInvalidChars, base::ASCIIToUTF16(" "),
47                     &trimmed_title);
48  ui::TreeNode<BookmarkNode>::SetTitle(trimmed_title);
49}
50
51bool BookmarkNode::IsVisible() const {
52  return true;
53}
54
55bool BookmarkNode::GetMetaInfo(const std::string& key,
56                               std::string* value) const {
57  if (!meta_info_map_)
58    return false;
59
60  MetaInfoMap::const_iterator it = meta_info_map_->find(key);
61  if (it == meta_info_map_->end())
62    return false;
63
64  *value = it->second;
65  return true;
66}
67
68bool BookmarkNode::SetMetaInfo(const std::string& key,
69                               const std::string& value) {
70  if (!meta_info_map_)
71    meta_info_map_.reset(new MetaInfoMap);
72
73  MetaInfoMap::iterator it = meta_info_map_->find(key);
74  if (it == meta_info_map_->end()) {
75    (*meta_info_map_)[key] = value;
76    return true;
77  }
78  // Key already in map, check if the value has changed.
79  if (it->second == value)
80    return false;
81  it->second = value;
82  return true;
83}
84
85bool BookmarkNode::DeleteMetaInfo(const std::string& key) {
86  if (!meta_info_map_)
87    return false;
88  bool erased = meta_info_map_->erase(key) != 0;
89  if (meta_info_map_->empty())
90    meta_info_map_.reset();
91  return erased;
92}
93
94void BookmarkNode::SetMetaInfoMap(const MetaInfoMap& meta_info_map) {
95  if (meta_info_map.empty())
96    meta_info_map_.reset();
97  else
98    meta_info_map_.reset(new MetaInfoMap(meta_info_map));
99}
100
101const BookmarkNode::MetaInfoMap* BookmarkNode::GetMetaInfoMap() const {
102  return meta_info_map_.get();
103}
104
105void BookmarkNode::Initialize(int64 id) {
106  id_ = id;
107  type_ = url_.is_empty() ? FOLDER : URL;
108  date_added_ = base::Time::Now();
109  favicon_type_ = favicon_base::INVALID_ICON;
110  favicon_state_ = INVALID_FAVICON;
111  favicon_load_task_id_ = base::CancelableTaskTracker::kBadTaskId;
112  meta_info_map_.reset();
113  sync_transaction_version_ = kInvalidSyncTransactionVersion;
114}
115
116void BookmarkNode::InvalidateFavicon() {
117  icon_url_ = GURL();
118  favicon_ = gfx::Image();
119  favicon_type_ = favicon_base::INVALID_ICON;
120  favicon_state_ = INVALID_FAVICON;
121}
122
123// BookmarkPermanentNode -------------------------------------------------------
124
125BookmarkPermanentNode::BookmarkPermanentNode(int64 id)
126    : BookmarkNode(id, GURL()),
127      visible_(true) {
128}
129
130BookmarkPermanentNode::~BookmarkPermanentNode() {
131}
132
133bool BookmarkPermanentNode::IsVisible() const {
134  return visible_ || !empty();
135}
136