- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / bookmarks / bookmark_api_helpers.cc
1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
6
7 #include <math.h>  // For floor()
8 #include <vector>
9
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/bookmarks/bookmark_model.h"
14 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
15 #include "chrome/common/extensions/api/bookmarks.h"
16
17 namespace extensions {
18
19 namespace keys = bookmark_api_constants;
20 using api::bookmarks::BookmarkTreeNode;
21
22 namespace bookmark_api_helpers {
23
24 namespace {
25
26 void AddNodeHelper(const BookmarkNode* node,
27                    std::vector<linked_ptr<BookmarkTreeNode> >* nodes,
28                    bool recurse,
29                    bool only_folders) {
30   if (node->IsVisible()) {
31     linked_ptr<BookmarkTreeNode> new_node(GetBookmarkTreeNode(node,
32                                                               recurse,
33                                                               only_folders));
34     nodes->push_back(new_node);
35   }
36 }
37
38 // TODO(mwrosen): Remove this function once chrome.bookmarkManagerPrivate is
39 // refactored to use the JSON schema compiler.
40 void AddNodeHelper(const BookmarkNode* node,
41                    base::ListValue* list,
42                    bool recurse,
43                    bool only_folders) {
44   if (node->IsVisible()) {
45     base::DictionaryValue* dict =
46         GetNodeDictionary(node, recurse, only_folders);
47     list->Append(dict);
48   }
49 }
50
51 }  // namespace
52
53 BookmarkTreeNode* GetBookmarkTreeNode(const BookmarkNode* node,
54                                       bool recurse,
55                                       bool only_folders) {
56   BookmarkTreeNode* bookmark_tree_node = new BookmarkTreeNode;
57
58   bookmark_tree_node->id = base::Int64ToString(node->id());
59
60   const BookmarkNode* parent = node->parent();
61   if (parent) {
62     bookmark_tree_node->parent_id.reset(new std::string(
63         base::Int64ToString(parent->id())));
64     bookmark_tree_node->index.reset(new int(parent->GetIndexOf(node)));
65   }
66
67   if (!node->is_folder()) {
68     bookmark_tree_node->url.reset(new std::string(node->url().spec()));
69   } else {
70     // Javascript Date wants milliseconds since the epoch, ToDoubleT is seconds.
71     base::Time t = node->date_folder_modified();
72     if (!t.is_null()) {
73       bookmark_tree_node->date_group_modified.reset(
74           new double(floor(t.ToDoubleT() * 1000)));
75     }
76   }
77
78   bookmark_tree_node->title = UTF16ToUTF8(node->GetTitle());
79   if (!node->date_added().is_null()) {
80     // Javascript Date wants milliseconds since the epoch, ToDoubleT is seconds.
81     bookmark_tree_node->date_added.reset(
82         new double(floor(node->date_added().ToDoubleT() * 1000)));
83   }
84
85   if (recurse && node->is_folder()) {
86     std::vector<linked_ptr<BookmarkTreeNode> > children;
87     for (int i = 0; i < node->child_count(); ++i) {
88       const BookmarkNode* child = node->GetChild(i);
89       if (child->IsVisible() && (!only_folders || child->is_folder())) {
90         linked_ptr<BookmarkTreeNode> child_node(
91             GetBookmarkTreeNode(child, true, only_folders));
92         children.push_back(child_node);
93       }
94     }
95     bookmark_tree_node->children.reset(
96         new std::vector<linked_ptr<BookmarkTreeNode> >(children));
97   }
98   return bookmark_tree_node;
99 }
100
101 base::DictionaryValue* GetNodeDictionary(const BookmarkNode* node,
102                                          bool recurse,
103                                          bool only_folders) {
104   base::DictionaryValue* dict = new base::DictionaryValue;
105   dict->SetString(keys::kIdKey, base::Int64ToString(node->id()));
106
107   const BookmarkNode* parent = node->parent();
108   if (parent) {
109     dict->SetString(keys::kParentIdKey, base::Int64ToString(parent->id()));
110     dict->SetInteger(keys::kIndexKey, parent->GetIndexOf(node));
111   }
112
113   if (!node->is_folder()) {
114     dict->SetString(keys::kUrlKey, node->url().spec());
115   } else {
116     // Javascript Date wants milliseconds since the epoch, ToDoubleT is seconds.
117     base::Time t = node->date_folder_modified();
118     if (!t.is_null())
119       dict->SetDouble(keys::kDateFolderModifiedKey,
120                       floor(t.ToDoubleT() * 1000));
121   }
122
123   dict->SetString(keys::kTitleKey, node->GetTitle());
124   if (!node->date_added().is_null()) {
125     // Javascript Date wants milliseconds since the epoch, ToDoubleT is seconds.
126     dict->SetDouble(keys::kDateAddedKey,
127                     floor(node->date_added().ToDoubleT() * 1000));
128   }
129
130   if (recurse && node->is_folder()) {
131     base::ListValue* children = new base::ListValue;
132     for (int i = 0; i < node->child_count(); ++i) {
133       const BookmarkNode* child = node->GetChild(i);
134       if (child->IsVisible() && (!only_folders || child->is_folder())) {
135         base::DictionaryValue* dict =
136             GetNodeDictionary(child, true, only_folders);
137         children->Append(dict);
138       }
139     }
140     dict->Set(keys::kChildrenKey, children);
141   }
142   return dict;
143 }
144
145 void AddNode(const BookmarkNode* node,
146              std::vector<linked_ptr<BookmarkTreeNode> >* nodes,
147              bool recurse) {
148   return AddNodeHelper(node, nodes, recurse, false);
149 }
150
151 void AddNodeFoldersOnly(const BookmarkNode* node,
152                         std::vector<linked_ptr<BookmarkTreeNode> >* nodes,
153                         bool recurse) {
154   return AddNodeHelper(node, nodes, recurse, true);
155 }
156
157 void AddNode(const BookmarkNode* node, base::ListValue* list, bool recurse) {
158   return AddNodeHelper(node, list, recurse, false);
159 }
160
161 void AddNodeFoldersOnly(const BookmarkNode* node,
162                         base::ListValue* list,
163                         bool recurse) {
164   return AddNodeHelper(node, list, recurse, true);
165 }
166
167 bool RemoveNode(BookmarkModel* model,
168                 int64 id,
169                 bool recursive,
170                 std::string* error) {
171   const BookmarkNode* node = model->GetNodeByID(id);
172   if (!node) {
173     *error = keys::kNoNodeError;
174     return false;
175   }
176   if (model->is_permanent_node(node)) {
177     *error = keys::kModifySpecialError;
178     return false;
179   }
180   if (node->is_folder() && !node->empty() && !recursive) {
181     *error = keys::kFolderNotEmptyError;
182     return false;
183   }
184
185   const BookmarkNode* parent = node->parent();
186   model->Remove(parent, parent->GetIndexOf(node));
187   return true;
188 }
189
190 }  // namespace bookmark_api_helpers
191 }  // namespace extensions