Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: chrome/browser/extensions/extension_bookmark_manager_api.cc

Issue 8374023: Move bookmarks extension api implementation to bookmarks dir (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix deps, rebase Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/extension_bookmark_manager_api.h"
6
7 #include <vector>
8
9 #include "base/json/json_writer.h"
10 #include "base/string_number_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/bookmarks/bookmark_model.h"
13 #include "chrome/browser/bookmarks/bookmark_node_data.h"
14 #include "chrome/browser/bookmarks/bookmark_utils.h"
15 #include "chrome/browser/extensions/extension_bookmark_helpers.h"
16 #include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
17 #include "chrome/browser/extensions/extension_event_router.h"
18 #include "chrome/browser/extensions/extension_function_dispatcher.h"
19 #include "chrome/browser/extensions/extension_web_ui.h"
20 #include "chrome/browser/prefs/pref_service.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
23 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/common/chrome_view_types.h"
26 #include "content/browser/renderer_host/render_view_host.h"
27 #include "content/browser/tab_contents/tab_contents.h"
28 #include "grit/generated_resources.h"
29 #include "ui/base/l10n/l10n_util.h"
30
31 namespace keys = extension_bookmarks_module_constants;
32
33 namespace {
34
35 // Returns a single bookmark node from the argument ID.
36 // This returns NULL in case of failure.
37 const BookmarkNode* GetNodeFromArguments(BookmarkModel* model,
38 const ListValue* args) {
39 std::string id_string;
40 if (!args->GetString(0, &id_string))
41 return NULL;
42 int64 id;
43 if (!base::StringToInt64(id_string, &id))
44 return NULL;
45 return model->GetNodeByID(id);
46 }
47
48 // Gets a vector of bookmark nodes from the argument list of IDs.
49 // This returns false in the case of failure.
50 bool GetNodesFromArguments(BookmarkModel* model, const ListValue* args,
51 size_t args_index, std::vector<const BookmarkNode*>* nodes) {
52
53 ListValue* ids;
54 if (!args->GetList(args_index, &ids))
55 return false;
56
57 size_t count = ids->GetSize();
58 if (count == 0)
59 return false;
60
61 for (size_t i = 0; i < count; ++i) {
62 std::string id_string;
63 if (!ids->GetString(i, &id_string))
64 return false;
65 int64 id;
66 if (!base::StringToInt64(id_string, &id))
67 return false;
68 const BookmarkNode* node = model->GetNodeByID(id);
69 if (!node)
70 return false;
71 nodes->push_back(node);
72 }
73
74 return true;
75 }
76
77 // Recursively adds a node to a list. This is by used |BookmarkNodeDataToJSON|
78 // when the data comes from the current profile. In this case we have a
79 // BookmarkNode since we got the data from the current profile.
80 void AddNodeToList(ListValue* list, const BookmarkNode& node) {
81 DictionaryValue* dict = new DictionaryValue();
82
83 // Add id and parentId so we can associate the data with existing nodes on the
84 // client side.
85 std::string id_string = base::Int64ToString(node.id());
86 dict->SetString(keys::kIdKey, id_string);
87
88 std::string parent_id_string = base::Int64ToString(node.parent()->id());
89 dict->SetString(keys::kParentIdKey, parent_id_string);
90
91 if (node.is_url())
92 dict->SetString(keys::kUrlKey, node.url().spec());
93
94 dict->SetString(keys::kTitleKey, node.GetTitle());
95
96 ListValue* children = new ListValue();
97 for (int i = 0; i < node.child_count(); ++i)
98 AddNodeToList(children, *node.GetChild(i));
99 dict->Set(keys::kChildrenKey, children);
100
101 list->Append(dict);
102 }
103
104 // Recursively adds an element to a list. This is used by
105 // |BookmarkNodeDataToJSON| when the data comes from a different profile. When
106 // the data comes from a different profile we do not have any IDs or parent IDs.
107 void AddElementToList(ListValue* list,
108 const BookmarkNodeData::Element& element) {
109 DictionaryValue* dict = new DictionaryValue();
110
111 if (element.is_url)
112 dict->SetString(keys::kUrlKey, element.url.spec());
113
114 dict->SetString(keys::kTitleKey, element.title);
115
116 ListValue* children = new ListValue();
117 for (size_t i = 0; i < element.children.size(); ++i)
118 AddElementToList(children, element.children[i]);
119 dict->Set(keys::kChildrenKey, children);
120
121 list->Append(dict);
122 }
123
124 // Builds the JSON structure based on the BookmarksDragData.
125 void BookmarkNodeDataToJSON(Profile* profile, const BookmarkNodeData& data,
126 ListValue* args) {
127 bool same_profile = data.IsFromProfile(profile);
128 DictionaryValue* value = new DictionaryValue();
129 value->SetBoolean(keys::kSameProfileKey, same_profile);
130
131 ListValue* list = new ListValue();
132 if (same_profile) {
133 std::vector<const BookmarkNode*> nodes = data.GetNodes(profile);
134 for (size_t i = 0; i < nodes.size(); ++i)
135 AddNodeToList(list, *nodes[i]);
136 } else {
137 // We do not have an node IDs when the data comes from a different profile.
138 std::vector<BookmarkNodeData::Element> elements = data.elements;
139 for (size_t i = 0; i < elements.size(); ++i)
140 AddElementToList(list, elements[i]);
141 }
142 value->Set(keys::kElementsKey, list);
143
144 args->Append(value);
145 }
146
147 } // namespace
148
149 ExtensionBookmarkManagerEventRouter::ExtensionBookmarkManagerEventRouter(
150 Profile* profile, TabContentsWrapper* tab)
151 : profile_(profile),
152 tab_(tab) {
153 tab_->bookmark_tab_helper()->SetBookmarkDragDelegate(this);
154 }
155
156 ExtensionBookmarkManagerEventRouter::~ExtensionBookmarkManagerEventRouter() {
157 if (tab_->bookmark_tab_helper()->GetBookmarkDragDelegate() == this)
158 tab_->bookmark_tab_helper()->SetBookmarkDragDelegate(NULL);
159 }
160
161 void ExtensionBookmarkManagerEventRouter::DispatchEvent(const char* event_name,
162 const ListValue* args) {
163 if (!profile_->GetExtensionEventRouter())
164 return;
165
166 std::string json_args;
167 base::JSONWriter::Write(args, false, &json_args);
168 profile_->GetExtensionEventRouter()->DispatchEventToRenderers(
169 event_name, json_args, NULL, GURL());
170 }
171
172 void ExtensionBookmarkManagerEventRouter::DispatchDragEvent(
173 const BookmarkNodeData& data, const char* event_name) {
174 if (data.size() == 0)
175 return;
176
177 ListValue args;
178 BookmarkNodeDataToJSON(profile_, data, &args);
179 DispatchEvent(event_name, &args);
180 }
181
182 void ExtensionBookmarkManagerEventRouter::OnDragEnter(
183 const BookmarkNodeData& data) {
184 DispatchDragEvent(data, keys::kOnBookmarkDragEnter);
185 }
186
187 void ExtensionBookmarkManagerEventRouter::OnDragOver(
188 const BookmarkNodeData& data) {
189 // Intentionally empty since these events happens too often and floods the
190 // message queue. We do not need this event for the bookmark manager anyway.
191 }
192
193 void ExtensionBookmarkManagerEventRouter::OnDragLeave(
194 const BookmarkNodeData& data) {
195 DispatchDragEvent(data, keys::kOnBookmarkDragLeave);
196 }
197
198 void ExtensionBookmarkManagerEventRouter::OnDrop(
199 const BookmarkNodeData& data) {
200 DispatchDragEvent(data, keys::kOnBookmarkDrop);
201
202 // Make a copy that is owned by this instance.
203 ClearBookmarkNodeData();
204 bookmark_drag_data_ = data;
205 }
206
207 const BookmarkNodeData*
208 ExtensionBookmarkManagerEventRouter::GetBookmarkNodeData() {
209 if (bookmark_drag_data_.is_valid())
210 return &bookmark_drag_data_;
211 return NULL;
212 }
213
214 void ExtensionBookmarkManagerEventRouter::ClearBookmarkNodeData() {
215 bookmark_drag_data_.Clear();
216 }
217
218 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut) {
219 BookmarkModel* model = profile()->GetBookmarkModel();
220 std::vector<const BookmarkNode*> nodes;
221 EXTENSION_FUNCTION_VALIDATE(GetNodesFromArguments(model, args_.get(),
222 0, &nodes));
223 bookmark_utils::CopyToClipboard(model, nodes, cut);
224 return true;
225 }
226
227 bool CopyBookmarkManagerFunction::RunImpl() {
228 return CopyOrCut(false);
229 }
230
231 bool CutBookmarkManagerFunction::RunImpl() {
232 if (!EditBookmarksEnabled())
233 return false;
234 return CopyOrCut(true);
235 }
236
237 bool PasteBookmarkManagerFunction::RunImpl() {
238 if (!EditBookmarksEnabled())
239 return false;
240 BookmarkModel* model = profile()->GetBookmarkModel();
241 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get());
242 if (!parent_node) {
243 error_ = keys::kNoParentError;
244 return false;
245 }
246 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node);
247 if (!can_paste)
248 return false;
249
250 // We want to use the highest index of the selected nodes as a destination.
251 std::vector<const BookmarkNode*> nodes;
252 // No need to test return value, if we got an empty list, we insert at end.
253 GetNodesFromArguments(model, args_.get(), 1, &nodes);
254 int highest_index = -1; // -1 means insert at end of list.
255 for (size_t node = 0; node < nodes.size(); ++node) {
256 // + 1 so that we insert after the selection.
257 int this_node_index = parent_node->GetIndexOf(nodes[node]) + 1;
258 if (this_node_index > highest_index)
259 highest_index = this_node_index;
260 }
261
262 bookmark_utils::PasteFromClipboard(model, parent_node, highest_index);
263 return true;
264 }
265
266 bool CanPasteBookmarkManagerFunction::RunImpl() {
267 if (!EditBookmarksEnabled())
268 return false;
269 BookmarkModel* model = profile()->GetBookmarkModel();
270 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get());
271 if (!parent_node) {
272 error_ = keys::kNoParentError;
273 return false;
274 }
275 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node);
276 result_.reset(Value::CreateBooleanValue(can_paste));
277 SendResponse(true);
278 return true;
279 }
280
281 bool SortChildrenBookmarkManagerFunction::RunImpl() {
282 if (!EditBookmarksEnabled())
283 return false;
284 BookmarkModel* model = profile()->GetBookmarkModel();
285 const BookmarkNode* parent_node = GetNodeFromArguments(model, args_.get());
286 if (!parent_node) {
287 error_ = keys::kNoParentError;
288 return false;
289 }
290 model->SortChildren(parent_node);
291 return true;
292 }
293
294 bool BookmarkManagerGetStringsFunction::RunImpl() {
295 DictionaryValue* localized_strings = new DictionaryValue();
296
297 localized_strings->SetString("title",
298 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE));
299 localized_strings->SetString("search_button",
300 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON));
301 localized_strings->SetString("show_in_folder",
302 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER));
303 localized_strings->SetString("sort",
304 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT));
305 localized_strings->SetString("organize_menu",
306 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU));
307 localized_strings->SetString("tools_menu",
308 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TOOLS_MENU));
309 localized_strings->SetString("import_menu",
310 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
311 localized_strings->SetString("export_menu",
312 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
313 localized_strings->SetString("rename_folder",
314 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER));
315 localized_strings->SetString("edit",
316 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT));
317 localized_strings->SetString("should_open_all",
318 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL));
319 localized_strings->SetString("open_incognito",
320 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO));
321 localized_strings->SetString("open_in_new_tab",
322 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB));
323 localized_strings->SetString("open_in_new_window",
324 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW));
325 localized_strings->SetString("add_new_bookmark",
326 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
327 localized_strings->SetString("new_folder",
328 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER));
329 localized_strings->SetString("open_all",
330 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL));
331 localized_strings->SetString("open_all_new_window",
332 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
333 localized_strings->SetString("open_all_incognito",
334 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
335 localized_strings->SetString("remove",
336 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE));
337 localized_strings->SetString("copy",
338 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY));
339 localized_strings->SetString("cut",
340 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT));
341 localized_strings->SetString("paste",
342 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE));
343 localized_strings->SetString("delete",
344 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE));
345 localized_strings->SetString("new_folder_name",
346 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME));
347 localized_strings->SetString("name_input_placeholder",
348 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER));
349 localized_strings->SetString("url_input_placeholder",
350 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER));
351 localized_strings->SetString("invalid_url",
352 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL));
353 localized_strings->SetString("recent",
354 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT));
355 localized_strings->SetString("search",
356 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH));
357
358 ChromeURLDataManager::DataSource::SetFontAndTextDirection(localized_strings);
359
360 result_.reset(localized_strings);
361 SendResponse(true);
362 return true;
363 }
364
365 bool StartDragBookmarkManagerFunction::RunImpl() {
366 if (!EditBookmarksEnabled())
367 return false;
368 BookmarkModel* model = profile()->GetBookmarkModel();
369 std::vector<const BookmarkNode*> nodes;
370 EXTENSION_FUNCTION_VALIDATE(
371 GetNodesFromArguments(model, args_.get(), 0, &nodes));
372
373 if (render_view_host_->delegate()->GetRenderViewType() ==
374 content::VIEW_TYPE_TAB_CONTENTS) {
375 TabContents* tab_contents =
376 dispatcher()->delegate()->GetAssociatedTabContents();
377 CHECK(tab_contents);
378 bookmark_utils::DragBookmarks(profile(), nodes,
379 tab_contents->GetNativeView());
380
381 return true;
382 } else {
383 NOTREACHED();
384 return false;
385 }
386 }
387
388 bool DropBookmarkManagerFunction::RunImpl() {
389 if (!EditBookmarksEnabled())
390 return false;
391
392 BookmarkModel* model = profile()->GetBookmarkModel();
393
394 int64 id;
395 std::string id_string;
396 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id_string));
397
398 if (!base::StringToInt64(id_string, &id)) {
399 error_ = keys::kInvalidIdError;
400 return false;
401 }
402
403 const BookmarkNode* drop_parent = model->GetNodeByID(id);
404 if (!drop_parent) {
405 error_ = keys::kNoParentError;
406 return false;
407 }
408
409 int drop_index;
410 if (args_->GetSize() == 2)
411 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &drop_index));
412 else
413 drop_index = drop_parent->child_count();
414
415 if (render_view_host_->delegate()->GetRenderViewType() ==
416 content::VIEW_TYPE_TAB_CONTENTS) {
417 TabContents* tab_contents =
418 dispatcher()->delegate()->GetAssociatedTabContents();
419 CHECK(tab_contents);
420 ExtensionWebUI* web_ui =
421 static_cast<ExtensionWebUI*>(tab_contents->web_ui());
422 CHECK(web_ui);
423 ExtensionBookmarkManagerEventRouter* router =
424 web_ui->extension_bookmark_manager_event_router();
425
426 DCHECK(router);
427 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData();
428 if (drag_data == NULL) {
429 NOTREACHED() <<"Somehow we're dropping null bookmark data";
430 return false;
431 }
432 bookmark_utils::PerformBookmarkDrop(profile(),
433 *drag_data,
434 drop_parent, drop_index);
435
436 router->ClearBookmarkNodeData();
437 SendResponse(true);
438 return true;
439 } else {
440 NOTREACHED();
441 return false;
442 }
443 }
444
445 bool GetSubtreeBookmarkManagerFunction::RunImpl() {
446 BookmarkModel* model = profile()->GetBookmarkModel();
447 const BookmarkNode* node;
448 int64 id;
449 std::string id_string;
450 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id_string));
451 bool folders_only;
452 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &folders_only));
453 if (id_string == "") {
454 node = model->root_node();
455 } else {
456 if (!base::StringToInt64(id_string, &id)) {
457 error_ = keys::kInvalidIdError;
458 return false;
459 }
460 node = model->GetNodeByID(id);
461 }
462 if (!node) {
463 error_ = keys::kNoNodeError;
464 return false;
465 }
466 scoped_ptr<ListValue> json(new ListValue());
467 if (folders_only) {
468 extension_bookmark_helpers::AddNodeFoldersOnly(node,
469 json.get(),
470 true);
471 } else {
472 extension_bookmark_helpers::AddNode(node, json.get(), true);
473 }
474 result_.reset(json.release());
475 return true;
476 }
477
478 bool CanEditBookmarkManagerFunction::RunImpl() {
479 result_.reset(Value::CreateBooleanValue(
480 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled)));
481 return true;
482 }
483
484 bool RecordLaunchBookmarkFunction::RunImpl() {
485 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_MANAGER);
486 return true;
487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698