Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / extensions / api / bookmark_manager_private / bookmark_manager_private_api.cc
blob78203725167384c62ff2777f775dfa8bae95cddc
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.
5 #include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h"
7 #include <vector>
9 #include "base/lazy_instance.h"
10 #include "base/memory/linked_ptr.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
16 #include "chrome/browser/bookmarks/bookmark_stats.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
19 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
20 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
21 #include "chrome/browser/extensions/extension_web_ui.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
24 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
25 #include "chrome/common/extensions/api/bookmark_manager_private.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/grit/generated_resources.h"
28 #include "components/bookmarks/browser/bookmark_model.h"
29 #include "components/bookmarks/browser/bookmark_node_data.h"
30 #include "components/bookmarks/browser/bookmark_utils.h"
31 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
32 #include "components/bookmarks/managed/managed_bookmark_service.h"
33 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
34 #include "components/undo/bookmark_undo_service.h"
35 #include "components/user_prefs/user_prefs.h"
36 #include "content/public/browser/render_view_host.h"
37 #include "content/public/browser/web_contents.h"
38 #include "content/public/browser/web_ui.h"
39 #include "extensions/browser/extension_function_dispatcher.h"
40 #include "extensions/browser/view_type_utils.h"
41 #include "ui/base/dragdrop/drag_drop_types.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/base/webui/web_ui_util.h"
45 using bookmarks::BookmarkModel;
46 using bookmarks::BookmarkNode;
47 using bookmarks::BookmarkNodeData;
48 using content::WebContents;
50 namespace extensions {
52 namespace bookmark_keys = bookmark_api_constants;
53 namespace bookmark_manager_private = api::bookmark_manager_private;
54 namespace CanPaste = api::bookmark_manager_private::CanPaste;
55 namespace Copy = api::bookmark_manager_private::Copy;
56 namespace CreateWithMetaInfo =
57 api::bookmark_manager_private::CreateWithMetaInfo;
58 namespace Cut = api::bookmark_manager_private::Cut;
59 namespace Drop = api::bookmark_manager_private::Drop;
60 namespace GetSubtree = api::bookmark_manager_private::GetSubtree;
61 namespace GetMetaInfo = api::bookmark_manager_private::GetMetaInfo;
62 namespace Paste = api::bookmark_manager_private::Paste;
63 namespace RedoInfo = api::bookmark_manager_private::GetRedoInfo;
64 namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees;
65 namespace SetMetaInfo = api::bookmark_manager_private::SetMetaInfo;
66 namespace SetVersion = api::bookmark_manager_private::SetVersion;
67 namespace SortChildren = api::bookmark_manager_private::SortChildren;
68 namespace StartDrag = api::bookmark_manager_private::StartDrag;
69 namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo;
70 namespace UpdateMetaInfo = api::bookmark_manager_private::UpdateMetaInfo;
72 namespace {
74 // Returns a single bookmark node from the argument ID.
75 // This returns NULL in case of failure.
76 const BookmarkNode* GetNodeFromString(BookmarkModel* model,
77 const std::string& id_string) {
78 int64 id;
79 if (!base::StringToInt64(id_string, &id))
80 return NULL;
81 return bookmarks::GetBookmarkNodeByID(model, id);
84 // Gets a vector of bookmark nodes from the argument list of IDs.
85 // This returns false in the case of failure.
86 bool GetNodesFromVector(BookmarkModel* model,
87 const std::vector<std::string>& id_strings,
88 std::vector<const BookmarkNode*>* nodes) {
89 if (id_strings.empty())
90 return false;
92 for (size_t i = 0; i < id_strings.size(); ++i) {
93 const BookmarkNode* node = GetNodeFromString(model, id_strings[i]);
94 if (!node)
95 return false;
96 nodes->push_back(node);
99 return true;
102 // Recursively create a bookmark_manager_private::BookmarkNodeDataElement from
103 // a bookmark node. This is by used |BookmarkNodeDataToJSON| when the data comes
104 // from the current profile. In this case we have a BookmarkNode since we got
105 // the data from the current profile.
106 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement>
107 CreateNodeDataElementFromBookmarkNode(const BookmarkNode& node) {
108 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> element(
109 new bookmark_manager_private::BookmarkNodeDataElement);
110 // Add id and parentId so we can associate the data with existing nodes on the
111 // client side.
112 element->id.reset(new std::string(base::Int64ToString(node.id())));
113 element->parent_id.reset(
114 new std::string(base::Int64ToString(node.parent()->id())));
116 if (node.is_url())
117 element->url.reset(new std::string(node.url().spec()));
119 element->title = base::UTF16ToUTF8(node.GetTitle());
120 for (int i = 0; i < node.child_count(); ++i) {
121 element->children.push_back(
122 CreateNodeDataElementFromBookmarkNode(*node.GetChild(i)));
125 return element;
128 // Recursively create a bookmark_manager_private::BookmarkNodeDataElement from
129 // a BookmarkNodeData::Element. This is used by |BookmarkNodeDataToJSON| when
130 // the data comes from a different profile. When the data comes from a different
131 // profile we do not have any IDs or parent IDs.
132 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement>
133 CreateApiNodeDataElement(const BookmarkNodeData::Element& element) {
134 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> node_element(
135 new bookmark_manager_private::BookmarkNodeDataElement);
137 if (element.is_url)
138 node_element->url.reset(new std::string(element.url.spec()));
139 node_element->title = base::UTF16ToUTF8(element.title);
140 for (size_t i = 0; i < element.children.size(); ++i) {
141 node_element->children.push_back(
142 CreateApiNodeDataElement(element.children[i]));
145 return node_element;
148 // Creates a bookmark_manager_private::BookmarkNodeData from a BookmarkNodeData.
149 scoped_ptr<bookmark_manager_private::BookmarkNodeData>
150 CreateApiBookmarkNodeData(Profile* profile, const BookmarkNodeData& data) {
151 const base::FilePath& profile_path = profile->GetPath();
153 scoped_ptr<bookmark_manager_private::BookmarkNodeData> node_data(
154 new bookmark_manager_private::BookmarkNodeData);
155 node_data->same_profile = data.IsFromProfilePath(profile_path);
157 if (node_data->same_profile) {
158 std::vector<const BookmarkNode*> nodes = data.GetNodes(
159 BookmarkModelFactory::GetForProfile(profile), profile_path);
160 for (size_t i = 0; i < nodes.size(); ++i) {
161 node_data->elements.push_back(
162 CreateNodeDataElementFromBookmarkNode(*nodes[i]));
164 } else {
165 // We do not have a node IDs when the data comes from a different profile.
166 for (size_t i = 0; i < data.size(); ++i)
167 node_data->elements.push_back(CreateApiNodeDataElement(data.elements[i]));
169 return node_data.Pass();
172 } // namespace
174 BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter(
175 content::BrowserContext* browser_context,
176 BookmarkModel* bookmark_model)
177 : browser_context_(browser_context), bookmark_model_(bookmark_model) {
178 bookmark_model_->AddObserver(this);
181 BookmarkManagerPrivateEventRouter::~BookmarkManagerPrivateEventRouter() {
182 if (bookmark_model_)
183 bookmark_model_->RemoveObserver(this);
186 void BookmarkManagerPrivateEventRouter::DispatchEvent(
187 events::HistogramValue histogram_value,
188 const std::string& event_name,
189 scoped_ptr<base::ListValue> event_args) {
190 EventRouter::Get(browser_context_)
191 ->BroadcastEvent(make_scoped_ptr(
192 new Event(histogram_value, event_name, event_args.Pass())));
195 void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {}
197 void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted(
198 BookmarkModel* model) {
199 bookmark_model_ = NULL;
202 void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo(
203 BookmarkModel* model,
204 const BookmarkNode* node) {
205 DCHECK(prev_meta_info_.empty());
206 if (node->GetMetaInfoMap())
207 prev_meta_info_ = *node->GetMetaInfoMap();
210 void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged(
211 BookmarkModel* model,
212 const BookmarkNode* node) {
213 const BookmarkNode::MetaInfoMap* new_meta_info = node->GetMetaInfoMap();
214 bookmark_manager_private::MetaInfoFields changes;
216 // Identify changed/removed fields:
217 for (BookmarkNode::MetaInfoMap::const_iterator it = prev_meta_info_.begin();
218 it != prev_meta_info_.end();
219 ++it) {
220 if (!new_meta_info) {
221 changes.additional_properties[it->first] = "";
222 } else {
223 BookmarkNode::MetaInfoMap::const_iterator new_meta_field =
224 new_meta_info->find(it->first);
225 if (new_meta_field == new_meta_info->end()) {
226 changes.additional_properties[it->first] = "";
227 } else if (it->second != new_meta_field->second) {
228 changes.additional_properties[it->first] = new_meta_field->second;
233 // Identify added fields:
234 if (new_meta_info) {
235 for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin();
236 it != new_meta_info->end();
237 ++it) {
238 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field =
239 prev_meta_info_.find(it->first);
240 if (prev_meta_field == prev_meta_info_.end())
241 changes.additional_properties[it->first] = it->second;
245 prev_meta_info_.clear();
246 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_META_INFO_CHANGED,
247 bookmark_manager_private::OnMetaInfoChanged::kEventName,
248 bookmark_manager_private::OnMetaInfoChanged::Create(
249 base::Int64ToString(node->id()), changes));
252 BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI(
253 content::BrowserContext* browser_context)
254 : browser_context_(browser_context) {
255 EventRouter* event_router = EventRouter::Get(browser_context);
256 event_router->RegisterObserver(
257 this, bookmark_manager_private::OnMetaInfoChanged::kEventName);
260 BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {}
262 void BookmarkManagerPrivateAPI::Shutdown() {
263 EventRouter::Get(browser_context_)->UnregisterObserver(this);
266 static base::LazyInstance<
267 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI> > g_factory =
268 LAZY_INSTANCE_INITIALIZER;
270 // static
271 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI>*
272 BookmarkManagerPrivateAPI::GetFactoryInstance() {
273 return g_factory.Pointer();
276 void BookmarkManagerPrivateAPI::OnListenerAdded(
277 const EventListenerInfo& details) {
278 EventRouter::Get(browser_context_)->UnregisterObserver(this);
279 event_router_.reset(new BookmarkManagerPrivateEventRouter(
280 browser_context_,
281 BookmarkModelFactory::GetForProfile(
282 Profile::FromBrowserContext(browser_context_))));
285 BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter(
286 Profile* profile,
287 content::WebContents* web_contents)
288 : profile_(profile), web_contents_(web_contents) {
289 BookmarkTabHelper* bookmark_tab_helper =
290 BookmarkTabHelper::FromWebContents(web_contents_);
291 bookmark_tab_helper->set_bookmark_drag_delegate(this);
294 BookmarkManagerPrivateDragEventRouter::
295 ~BookmarkManagerPrivateDragEventRouter() {
296 BookmarkTabHelper* bookmark_tab_helper =
297 BookmarkTabHelper::FromWebContents(web_contents_);
298 if (bookmark_tab_helper->bookmark_drag_delegate() == this)
299 bookmark_tab_helper->set_bookmark_drag_delegate(NULL);
302 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
303 events::HistogramValue histogram_value,
304 const std::string& event_name,
305 scoped_ptr<base::ListValue> args) {
306 EventRouter* event_router = EventRouter::Get(profile_);
307 if (!event_router)
308 return;
310 scoped_ptr<Event> event(new Event(histogram_value, event_name, args.Pass()));
311 event_router->BroadcastEvent(event.Pass());
314 void BookmarkManagerPrivateDragEventRouter::OnDragEnter(
315 const BookmarkNodeData& data) {
316 if (!data.is_valid())
317 return;
318 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_DRAG_ENTER,
319 bookmark_manager_private::OnDragEnter::kEventName,
320 bookmark_manager_private::OnDragEnter::Create(
321 *CreateApiBookmarkNodeData(profile_, data)));
324 void BookmarkManagerPrivateDragEventRouter::OnDragOver(
325 const BookmarkNodeData& data) {
326 // Intentionally empty since these events happens too often and floods the
327 // message queue. We do not need this event for the bookmark manager anyway.
330 void BookmarkManagerPrivateDragEventRouter::OnDragLeave(
331 const BookmarkNodeData& data) {
332 if (!data.is_valid())
333 return;
334 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_DRAG_LEAVE,
335 bookmark_manager_private::OnDragLeave::kEventName,
336 bookmark_manager_private::OnDragLeave::Create(
337 *CreateApiBookmarkNodeData(profile_, data)));
340 void BookmarkManagerPrivateDragEventRouter::OnDrop(
341 const BookmarkNodeData& data) {
342 if (!data.is_valid())
343 return;
344 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_DROP,
345 bookmark_manager_private::OnDrop::kEventName,
346 bookmark_manager_private::OnDrop::Create(
347 *CreateApiBookmarkNodeData(profile_, data)));
349 // Make a copy that is owned by this instance.
350 ClearBookmarkNodeData();
351 bookmark_drag_data_ = data;
354 const BookmarkNodeData*
355 BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() {
356 if (bookmark_drag_data_.is_valid())
357 return &bookmark_drag_data_;
358 return NULL;
361 void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() {
362 bookmark_drag_data_.Clear();
365 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut,
366 const std::vector<std::string>& id_list) {
367 BookmarkModel* model = GetBookmarkModel();
368 bookmarks::ManagedBookmarkService* managed = GetManagedBookmarkService();
369 std::vector<const BookmarkNode*> nodes;
370 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model, id_list, &nodes));
371 if (cut && bookmarks::HasDescendantsOf(nodes, managed->managed_node())) {
372 error_ = bookmark_keys::kModifyManagedError;
373 return false;
375 bookmarks::CopyToClipboard(model, nodes, cut);
376 return true;
379 bool BookmarkManagerPrivateCopyFunction::RunOnReady() {
380 scoped_ptr<Copy::Params> params(Copy::Params::Create(*args_));
381 EXTENSION_FUNCTION_VALIDATE(params);
382 return CopyOrCut(false, params->id_list);
385 bool BookmarkManagerPrivateCutFunction::RunOnReady() {
386 if (!EditBookmarksEnabled())
387 return false;
389 scoped_ptr<Cut::Params> params(Cut::Params::Create(*args_));
390 EXTENSION_FUNCTION_VALIDATE(params);
391 return CopyOrCut(true, params->id_list);
394 bool BookmarkManagerPrivatePasteFunction::RunOnReady() {
395 if (!EditBookmarksEnabled())
396 return false;
398 scoped_ptr<Paste::Params> params(Paste::Params::Create(*args_));
399 EXTENSION_FUNCTION_VALIDATE(params);
400 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
401 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
402 if (!CanBeModified(parent_node))
403 return false;
404 bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node);
405 if (!can_paste)
406 return false;
408 // We want to use the highest index of the selected nodes as a destination.
409 std::vector<const BookmarkNode*> nodes;
410 // No need to test return value, if we got an empty list, we insert at end.
411 if (params->selected_id_list)
412 GetNodesFromVector(model, *params->selected_id_list, &nodes);
413 int highest_index = -1; // -1 means insert at end of list.
414 for (size_t i = 0; i < nodes.size(); ++i) {
415 // + 1 so that we insert after the selection.
416 int index = parent_node->GetIndexOf(nodes[i]) + 1;
417 if (index > highest_index)
418 highest_index = index;
421 bookmarks::PasteFromClipboard(model, parent_node, highest_index);
422 return true;
425 bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() {
426 scoped_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_));
427 EXTENSION_FUNCTION_VALIDATE(params);
429 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile());
430 if (!prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled)) {
431 SetResult(new base::FundamentalValue(false));
432 return true;
435 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
436 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
437 if (!parent_node) {
438 error_ = bookmark_keys::kNoParentError;
439 return false;
441 bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node);
442 SetResult(new base::FundamentalValue(can_paste));
443 return true;
446 bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() {
447 if (!EditBookmarksEnabled())
448 return false;
450 scoped_ptr<SortChildren::Params> params(SortChildren::Params::Create(*args_));
451 EXTENSION_FUNCTION_VALIDATE(params);
453 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
454 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
455 if (!CanBeModified(parent_node))
456 return false;
457 model->SortChildren(parent_node);
458 return true;
461 bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
462 base::DictionaryValue* localized_strings = new base::DictionaryValue();
464 localized_strings->SetString("title",
465 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE));
466 localized_strings->SetString("search_button",
467 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON));
468 localized_strings->SetString("folders_menu",
469 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_FOLDERS_MENU));
470 localized_strings->SetString("organize_menu",
471 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU));
472 localized_strings->SetString("show_in_folder",
473 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER));
474 localized_strings->SetString("sort",
475 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT));
476 localized_strings->SetString("import_menu",
477 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
478 localized_strings->SetString("export_menu",
479 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
480 localized_strings->SetString("rename_folder",
481 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER));
482 localized_strings->SetString("edit",
483 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT));
484 localized_strings->SetString("should_open_all",
485 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL));
486 localized_strings->SetString("open_incognito",
487 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO));
488 localized_strings->SetString("open_in_new_tab",
489 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB));
490 localized_strings->SetString("open_in_new_window",
491 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW));
492 localized_strings->SetString("add_new_bookmark",
493 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
494 localized_strings->SetString("new_folder",
495 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER));
496 localized_strings->SetString("open_all",
497 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL));
498 localized_strings->SetString("open_all_new_window",
499 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
500 localized_strings->SetString("open_all_incognito",
501 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
502 localized_strings->SetString("remove",
503 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE));
504 localized_strings->SetString("copy",
505 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY));
506 localized_strings->SetString("cut",
507 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT));
508 localized_strings->SetString("paste",
509 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE));
510 localized_strings->SetString("delete",
511 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE));
512 localized_strings->SetString("undo_delete",
513 l10n_util::GetStringUTF16(IDS_UNDO_DELETE));
514 localized_strings->SetString("new_folder_name",
515 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME));
516 localized_strings->SetString("name_input_placeholder",
517 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER));
518 localized_strings->SetString("url_input_placeholder",
519 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER));
520 localized_strings->SetString("invalid_url",
521 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL));
522 localized_strings->SetString("recent",
523 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT));
524 localized_strings->SetString("search",
525 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH));
526 localized_strings->SetString("save",
527 l10n_util::GetStringUTF16(IDS_SAVE));
528 localized_strings->SetString("cancel",
529 l10n_util::GetStringUTF16(IDS_CANCEL));
531 const std::string& app_locale = g_browser_process->GetApplicationLocale();
532 webui::SetLoadTimeDataDefaults(app_locale, localized_strings);
534 SetResult(localized_strings);
536 // This is needed because unlike the rest of these functions, this class
537 // inherits from AsyncFunction directly, rather than BookmarkFunction.
538 SendResponse(true);
540 return true;
543 bool BookmarkManagerPrivateStartDragFunction::RunOnReady() {
544 if (!EditBookmarksEnabled())
545 return false;
547 if (GetViewType(GetSenderWebContents()) != VIEW_TYPE_TAB_CONTENTS) {
548 NOTREACHED();
549 return false;
552 scoped_ptr<StartDrag::Params> params(StartDrag::Params::Create(*args_));
553 EXTENSION_FUNCTION_VALIDATE(params);
555 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
556 std::vector<const BookmarkNode*> nodes;
557 EXTENSION_FUNCTION_VALIDATE(
558 GetNodesFromVector(model, params->id_list, &nodes));
560 content::WebContents* web_contents = GetAssociatedWebContents();
561 CHECK(web_contents);
563 ui::DragDropTypes::DragEventSource source =
564 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
565 if (params->is_from_touch)
566 source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
568 chrome::DragBookmarks(
569 GetProfile(), nodes, web_contents->GetNativeView(), source);
571 return true;
574 bool BookmarkManagerPrivateDropFunction::RunOnReady() {
575 if (!EditBookmarksEnabled())
576 return false;
578 scoped_ptr<Drop::Params> params(Drop::Params::Create(*args_));
579 EXTENSION_FUNCTION_VALIDATE(params);
581 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
583 const BookmarkNode* drop_parent = GetNodeFromString(model, params->parent_id);
584 if (!CanBeModified(drop_parent))
585 return false;
587 if (GetViewType(GetSenderWebContents()) != VIEW_TYPE_TAB_CONTENTS) {
588 NOTREACHED();
589 return false;
592 int drop_index;
593 if (params->index)
594 drop_index = *params->index;
595 else
596 drop_index = drop_parent->child_count();
598 WebContents* web_contents = GetAssociatedWebContents();
599 CHECK(web_contents);
600 ExtensionWebUI* web_ui =
601 static_cast<ExtensionWebUI*>(web_contents->GetWebUI()->GetController());
602 CHECK(web_ui);
603 BookmarkManagerPrivateDragEventRouter* router =
604 web_ui->bookmark_manager_private_drag_event_router();
606 DCHECK(router);
607 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData();
608 if (drag_data == NULL) {
609 NOTREACHED() <<"Somehow we're dropping null bookmark data";
610 return false;
612 const bool copy = false;
613 chrome::DropBookmarks(
614 GetProfile(), *drag_data, drop_parent, drop_index, copy);
616 router->ClearBookmarkNodeData();
617 return true;
620 bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() {
621 scoped_ptr<GetSubtree::Params> params(GetSubtree::Params::Create(*args_));
622 EXTENSION_FUNCTION_VALIDATE(params);
624 const BookmarkNode* node = NULL;
626 if (params->id.empty()) {
627 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
628 node = model->root_node();
629 } else {
630 node = GetBookmarkNodeFromId(params->id);
631 if (!node)
632 return false;
635 std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> > nodes;
636 bookmarks::ManagedBookmarkService* managed = GetManagedBookmarkService();
637 if (params->folders_only)
638 bookmark_api_helpers::AddNodeFoldersOnly(managed, node, &nodes, true);
639 else
640 bookmark_api_helpers::AddNode(managed, node, &nodes, true);
641 results_ = GetSubtree::Results::Create(nodes);
642 return true;
645 bool BookmarkManagerPrivateCanEditFunction::RunOnReady() {
646 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile());
647 SetResult(new base::FundamentalValue(
648 prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled)));
649 return true;
652 bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() {
653 RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER);
654 return true;
657 bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() {
658 if (!EditBookmarksEnabled())
659 return false;
661 scoped_ptr<CreateWithMetaInfo::Params> params(
662 CreateWithMetaInfo::Params::Create(*args_));
663 EXTENSION_FUNCTION_VALIDATE(params);
665 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
666 const BookmarkNode* node = CreateBookmarkNode(
667 model, params->bookmark, &params->meta_info.additional_properties);
668 if (!node)
669 return false;
671 scoped_ptr<api::bookmarks::BookmarkTreeNode> result_node(
672 bookmark_api_helpers::GetBookmarkTreeNode(GetManagedBookmarkService(),
673 node, false, false));
674 results_ = CreateWithMetaInfo::Results::Create(*result_node);
676 return true;
679 bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() {
680 scoped_ptr<GetMetaInfo::Params> params(GetMetaInfo::Params::Create(*args_));
681 EXTENSION_FUNCTION_VALIDATE(params);
683 if (params->id) {
684 const BookmarkNode* node = GetBookmarkNodeFromId(*params->id);
685 if (!node)
686 return false;
688 if (params->key) {
689 std::string value;
690 if (node->GetMetaInfo(*params->key, &value)) {
691 GetMetaInfo::Results::Value result;
692 result.as_string.reset(new std::string(value));
693 results_ = GetMetaInfo::Results::Create(result);
695 } else {
696 GetMetaInfo::Results::Value result;
697 result.as_object.reset(new GetMetaInfo::Results::Value::Object);
699 const BookmarkNode::MetaInfoMap* meta_info = node->GetMetaInfoMap();
700 if (meta_info) {
701 BookmarkNode::MetaInfoMap::const_iterator itr;
702 base::DictionaryValue& temp = result.as_object->additional_properties;
703 for (itr = meta_info->begin(); itr != meta_info->end(); itr++) {
704 temp.SetStringWithoutPathExpansion(itr->first, itr->second);
707 results_ = GetMetaInfo::Results::Create(result);
709 } else {
710 if (params->key) {
711 error_ = bookmark_api_constants::kInvalidParamError;
712 return true;
715 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
716 const BookmarkNode* node = model->root_node();
718 GetMetaInfo::Results::Value result;
719 result.as_object.reset(new GetMetaInfo::Results::Value::Object);
721 bookmark_api_helpers::GetMetaInfo(*node,
722 &result.as_object->additional_properties);
724 results_ = GetMetaInfo::Results::Create(result);
727 return true;
730 bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() {
731 if (!EditBookmarksEnabled())
732 return false;
734 scoped_ptr<SetMetaInfo::Params> params(SetMetaInfo::Params::Create(*args_));
735 EXTENSION_FUNCTION_VALIDATE(params);
737 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
738 if (!node)
739 return false;
741 if (!CanBeModified(node))
742 return false;
744 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
745 if (model->is_permanent_node(node)) {
746 error_ = bookmark_keys::kModifySpecialError;
747 return false;
750 model->SetNodeMetaInfo(node, params->key, params->value);
751 return true;
754 bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() {
755 if (!EditBookmarksEnabled())
756 return false;
758 scoped_ptr<UpdateMetaInfo::Params> params(
759 UpdateMetaInfo::Params::Create(*args_));
760 EXTENSION_FUNCTION_VALIDATE(params);
762 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
763 if (!node)
764 return false;
766 if (!CanBeModified(node))
767 return false;
769 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
770 if (model->is_permanent_node(node)) {
771 error_ = bookmark_keys::kModifySpecialError;
772 return false;
775 BookmarkNode::MetaInfoMap new_meta_info(
776 params->meta_info_changes.additional_properties);
777 if (node->GetMetaInfoMap()) {
778 new_meta_info.insert(node->GetMetaInfoMap()->begin(),
779 node->GetMetaInfoMap()->end());
781 model->SetNodeMetaInfoMap(node, new_meta_info);
783 return true;
786 bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() {
787 bool can_open_new_windows = true;
788 SetResult(new base::FundamentalValue(can_open_new_windows));
789 return true;
792 bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() {
793 if (!EditBookmarksEnabled())
794 return false;
796 scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_));
797 EXTENSION_FUNCTION_VALIDATE(params);
799 BookmarkModel* model = GetBookmarkModel();
800 bookmarks::ManagedBookmarkService* managed = GetManagedBookmarkService();
801 bookmarks::ScopedGroupBookmarkActions group_deletes(model);
802 int64 id;
803 for (size_t i = 0; i < params->id_list.size(); ++i) {
804 if (!GetBookmarkIdAsInt64(params->id_list[i], &id))
805 return false;
806 if (!bookmark_api_helpers::RemoveNode(model, managed, id, true, &error_))
807 return false;
810 return true;
813 bool BookmarkManagerPrivateUndoFunction::RunOnReady() {
814 if (!EditBookmarksEnabled())
815 return false;
817 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
818 Undo();
819 return true;
822 bool BookmarkManagerPrivateRedoFunction::RunOnReady() {
823 if (!EditBookmarksEnabled())
824 return false;
826 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
827 Redo();
828 return true;
831 bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() {
832 UndoManager* undo_manager =
833 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
835 UndoInfo::Results::Result result;
836 result.enabled = undo_manager->undo_count() > 0;
837 result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel());
839 results_ = UndoInfo::Results::Create(result);
840 return true;
843 bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() {
844 UndoManager* undo_manager =
845 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
847 RedoInfo::Results::Result result;
848 result.enabled = undo_manager->redo_count() > 0;
849 result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel());
851 results_ = RedoInfo::Results::Create(result);
852 return true;
855 bool BookmarkManagerPrivateSetVersionFunction::RunOnReady() {
856 scoped_ptr<SetVersion::Params> params = SetVersion::Params::Create(*args_);
858 enhanced_bookmarks::EnhancedBookmarkModel* model =
859 enhanced_bookmarks::EnhancedBookmarkModelFactory::GetForBrowserContext(
860 browser_context());
861 model->SetVersionSuffix(params->version);
863 return true;
866 } // namespace extensions