Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / extensions / api / bookmark_manager_private / bookmark_manager_private_api.cc
blob189aee713b1a7944c3ff276856b9d8f875937de5
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/bookmarks/chrome_bookmark_client.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
20 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
21 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
22 #include "chrome/browser/extensions/extension_web_ui.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
25 #include "chrome/browser/undo/bookmark_undo_service.h"
26 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
27 #include "chrome/common/extensions/api/bookmark_manager_private.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/grit/generated_resources.h"
30 #include "components/bookmarks/browser/bookmark_model.h"
31 #include "components/bookmarks/browser/bookmark_node_data.h"
32 #include "components/bookmarks/browser/bookmark_utils.h"
33 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
34 #include "components/enhanced_bookmarks/enhanced_bookmark_model.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 const std::string& event_name,
188 scoped_ptr<base::ListValue> event_args) {
189 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(
190 make_scoped_ptr(new extensions::Event(event_name, event_args.Pass())));
193 void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {}
195 void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted(
196 BookmarkModel* model) {
197 bookmark_model_ = NULL;
200 void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo(
201 BookmarkModel* model,
202 const BookmarkNode* node) {
203 DCHECK(prev_meta_info_.empty());
204 if (node->GetMetaInfoMap())
205 prev_meta_info_ = *node->GetMetaInfoMap();
208 void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged(
209 BookmarkModel* model,
210 const BookmarkNode* node) {
211 const BookmarkNode::MetaInfoMap* new_meta_info = node->GetMetaInfoMap();
212 bookmark_manager_private::MetaInfoFields changes;
214 // Identify changed/removed fields:
215 for (BookmarkNode::MetaInfoMap::const_iterator it = prev_meta_info_.begin();
216 it != prev_meta_info_.end();
217 ++it) {
218 if (!new_meta_info) {
219 changes.additional_properties[it->first] = "";
220 } else {
221 BookmarkNode::MetaInfoMap::const_iterator new_meta_field =
222 new_meta_info->find(it->first);
223 if (new_meta_field == new_meta_info->end()) {
224 changes.additional_properties[it->first] = "";
225 } else if (it->second != new_meta_field->second) {
226 changes.additional_properties[it->first] = new_meta_field->second;
231 // Identify added fields:
232 if (new_meta_info) {
233 for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin();
234 it != new_meta_info->end();
235 ++it) {
236 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field =
237 prev_meta_info_.find(it->first);
238 if (prev_meta_field == prev_meta_info_.end())
239 changes.additional_properties[it->first] = it->second;
243 prev_meta_info_.clear();
244 DispatchEvent(bookmark_manager_private::OnMetaInfoChanged::kEventName,
245 bookmark_manager_private::OnMetaInfoChanged::Create(
246 base::Int64ToString(node->id()), changes));
249 BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI(
250 content::BrowserContext* browser_context)
251 : browser_context_(browser_context) {
252 EventRouter* event_router = EventRouter::Get(browser_context);
253 event_router->RegisterObserver(
254 this, bookmark_manager_private::OnMetaInfoChanged::kEventName);
257 BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {}
259 void BookmarkManagerPrivateAPI::Shutdown() {
260 EventRouter::Get(browser_context_)->UnregisterObserver(this);
263 static base::LazyInstance<
264 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI> > g_factory =
265 LAZY_INSTANCE_INITIALIZER;
267 // static
268 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI>*
269 BookmarkManagerPrivateAPI::GetFactoryInstance() {
270 return g_factory.Pointer();
273 void BookmarkManagerPrivateAPI::OnListenerAdded(
274 const EventListenerInfo& details) {
275 EventRouter::Get(browser_context_)->UnregisterObserver(this);
276 event_router_.reset(new BookmarkManagerPrivateEventRouter(
277 browser_context_,
278 BookmarkModelFactory::GetForProfile(
279 Profile::FromBrowserContext(browser_context_))));
282 BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter(
283 Profile* profile,
284 content::WebContents* web_contents)
285 : profile_(profile), web_contents_(web_contents) {
286 BookmarkTabHelper* bookmark_tab_helper =
287 BookmarkTabHelper::FromWebContents(web_contents_);
288 bookmark_tab_helper->set_bookmark_drag_delegate(this);
291 BookmarkManagerPrivateDragEventRouter::
292 ~BookmarkManagerPrivateDragEventRouter() {
293 BookmarkTabHelper* bookmark_tab_helper =
294 BookmarkTabHelper::FromWebContents(web_contents_);
295 if (bookmark_tab_helper->bookmark_drag_delegate() == this)
296 bookmark_tab_helper->set_bookmark_drag_delegate(NULL);
299 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
300 const std::string& event_name,
301 scoped_ptr<base::ListValue> args) {
302 EventRouter* event_router = EventRouter::Get(profile_);
303 if (!event_router)
304 return;
306 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
307 event_router->BroadcastEvent(event.Pass());
310 void BookmarkManagerPrivateDragEventRouter::OnDragEnter(
311 const BookmarkNodeData& data) {
312 if (!data.is_valid())
313 return;
314 DispatchEvent(bookmark_manager_private::OnDragEnter::kEventName,
315 bookmark_manager_private::OnDragEnter::Create(
316 *CreateApiBookmarkNodeData(profile_, data)));
319 void BookmarkManagerPrivateDragEventRouter::OnDragOver(
320 const BookmarkNodeData& data) {
321 // Intentionally empty since these events happens too often and floods the
322 // message queue. We do not need this event for the bookmark manager anyway.
325 void BookmarkManagerPrivateDragEventRouter::OnDragLeave(
326 const BookmarkNodeData& data) {
327 if (!data.is_valid())
328 return;
329 DispatchEvent(bookmark_manager_private::OnDragLeave::kEventName,
330 bookmark_manager_private::OnDragLeave::Create(
331 *CreateApiBookmarkNodeData(profile_, data)));
334 void BookmarkManagerPrivateDragEventRouter::OnDrop(
335 const BookmarkNodeData& data) {
336 if (!data.is_valid())
337 return;
338 DispatchEvent(bookmark_manager_private::OnDrop::kEventName,
339 bookmark_manager_private::OnDrop::Create(
340 *CreateApiBookmarkNodeData(profile_, data)));
342 // Make a copy that is owned by this instance.
343 ClearBookmarkNodeData();
344 bookmark_drag_data_ = data;
347 const BookmarkNodeData*
348 BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() {
349 if (bookmark_drag_data_.is_valid())
350 return &bookmark_drag_data_;
351 return NULL;
354 void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() {
355 bookmark_drag_data_.Clear();
358 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut,
359 const std::vector<std::string>& id_list) {
360 BookmarkModel* model = GetBookmarkModel();
361 ChromeBookmarkClient* client = GetChromeBookmarkClient();
362 std::vector<const BookmarkNode*> nodes;
363 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model, id_list, &nodes));
364 if (cut && bookmarks::HasDescendantsOf(nodes, client->managed_node())) {
365 error_ = bookmark_keys::kModifyManagedError;
366 return false;
368 bookmarks::CopyToClipboard(model, nodes, cut);
369 return true;
372 bool BookmarkManagerPrivateCopyFunction::RunOnReady() {
373 scoped_ptr<Copy::Params> params(Copy::Params::Create(*args_));
374 EXTENSION_FUNCTION_VALIDATE(params);
375 return CopyOrCut(false, params->id_list);
378 bool BookmarkManagerPrivateCutFunction::RunOnReady() {
379 if (!EditBookmarksEnabled())
380 return false;
382 scoped_ptr<Cut::Params> params(Cut::Params::Create(*args_));
383 EXTENSION_FUNCTION_VALIDATE(params);
384 return CopyOrCut(true, params->id_list);
387 bool BookmarkManagerPrivatePasteFunction::RunOnReady() {
388 if (!EditBookmarksEnabled())
389 return false;
391 scoped_ptr<Paste::Params> params(Paste::Params::Create(*args_));
392 EXTENSION_FUNCTION_VALIDATE(params);
393 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
394 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
395 if (!CanBeModified(parent_node))
396 return false;
397 bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node);
398 if (!can_paste)
399 return false;
401 // We want to use the highest index of the selected nodes as a destination.
402 std::vector<const BookmarkNode*> nodes;
403 // No need to test return value, if we got an empty list, we insert at end.
404 if (params->selected_id_list)
405 GetNodesFromVector(model, *params->selected_id_list, &nodes);
406 int highest_index = -1; // -1 means insert at end of list.
407 for (size_t i = 0; i < nodes.size(); ++i) {
408 // + 1 so that we insert after the selection.
409 int index = parent_node->GetIndexOf(nodes[i]) + 1;
410 if (index > highest_index)
411 highest_index = index;
414 bookmarks::PasteFromClipboard(model, parent_node, highest_index);
415 return true;
418 bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() {
419 if (!EditBookmarksEnabled())
420 return false;
422 scoped_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_));
423 EXTENSION_FUNCTION_VALIDATE(params);
425 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
426 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
427 if (!parent_node) {
428 error_ = bookmark_keys::kNoParentError;
429 return false;
431 bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node);
432 SetResult(new base::FundamentalValue(can_paste));
433 return true;
436 bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() {
437 if (!EditBookmarksEnabled())
438 return false;
440 scoped_ptr<SortChildren::Params> params(SortChildren::Params::Create(*args_));
441 EXTENSION_FUNCTION_VALIDATE(params);
443 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
444 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
445 if (!CanBeModified(parent_node))
446 return false;
447 model->SortChildren(parent_node);
448 return true;
451 bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
452 base::DictionaryValue* localized_strings = new base::DictionaryValue();
454 localized_strings->SetString("title",
455 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE));
456 localized_strings->SetString("search_button",
457 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON));
458 localized_strings->SetString("folders_menu",
459 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_FOLDERS_MENU));
460 localized_strings->SetString("organize_menu",
461 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU));
462 localized_strings->SetString("show_in_folder",
463 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER));
464 localized_strings->SetString("sort",
465 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT));
466 localized_strings->SetString("import_menu",
467 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
468 localized_strings->SetString("export_menu",
469 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
470 localized_strings->SetString("rename_folder",
471 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER));
472 localized_strings->SetString("edit",
473 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT));
474 localized_strings->SetString("should_open_all",
475 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL));
476 localized_strings->SetString("open_incognito",
477 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO));
478 localized_strings->SetString("open_in_new_tab",
479 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB));
480 localized_strings->SetString("open_in_new_window",
481 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW));
482 localized_strings->SetString("add_new_bookmark",
483 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
484 localized_strings->SetString("new_folder",
485 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER));
486 localized_strings->SetString("open_all",
487 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL));
488 localized_strings->SetString("open_all_new_window",
489 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
490 localized_strings->SetString("open_all_incognito",
491 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
492 localized_strings->SetString("remove",
493 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE));
494 localized_strings->SetString("copy",
495 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY));
496 localized_strings->SetString("cut",
497 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT));
498 localized_strings->SetString("paste",
499 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE));
500 localized_strings->SetString("delete",
501 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE));
502 localized_strings->SetString("undo_delete",
503 l10n_util::GetStringUTF16(IDS_UNDO_DELETE));
504 localized_strings->SetString("new_folder_name",
505 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME));
506 localized_strings->SetString("name_input_placeholder",
507 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER));
508 localized_strings->SetString("url_input_placeholder",
509 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER));
510 localized_strings->SetString("invalid_url",
511 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL));
512 localized_strings->SetString("recent",
513 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT));
514 localized_strings->SetString("search",
515 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH));
516 localized_strings->SetString("save",
517 l10n_util::GetStringUTF16(IDS_SAVE));
518 localized_strings->SetString("cancel",
519 l10n_util::GetStringUTF16(IDS_CANCEL));
521 const std::string& app_locale = g_browser_process->GetApplicationLocale();
522 webui::SetLoadTimeDataDefaults(app_locale, localized_strings);
524 SetResult(localized_strings);
526 // This is needed because unlike the rest of these functions, this class
527 // inherits from AsyncFunction directly, rather than BookmarkFunction.
528 SendResponse(true);
530 return true;
533 bool BookmarkManagerPrivateStartDragFunction::RunOnReady() {
534 if (!EditBookmarksEnabled())
535 return false;
537 scoped_ptr<StartDrag::Params> params(StartDrag::Params::Create(*args_));
538 EXTENSION_FUNCTION_VALIDATE(params);
540 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
541 std::vector<const BookmarkNode*> nodes;
542 EXTENSION_FUNCTION_VALIDATE(
543 GetNodesFromVector(model, params->id_list, &nodes));
545 WebContents* web_contents =
546 WebContents::FromRenderViewHost(render_view_host_);
547 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) {
548 WebContents* web_contents =
549 dispatcher()->delegate()->GetAssociatedWebContents();
550 CHECK(web_contents);
552 ui::DragDropTypes::DragEventSource source =
553 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
554 if (params->is_from_touch)
555 source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
557 chrome::DragBookmarks(
558 GetProfile(), nodes, web_contents->GetNativeView(), source);
560 return true;
561 } else {
562 NOTREACHED();
563 return false;
567 bool BookmarkManagerPrivateDropFunction::RunOnReady() {
568 if (!EditBookmarksEnabled())
569 return false;
571 scoped_ptr<Drop::Params> params(Drop::Params::Create(*args_));
572 EXTENSION_FUNCTION_VALIDATE(params);
574 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
576 const BookmarkNode* drop_parent = GetNodeFromString(model, params->parent_id);
577 if (!CanBeModified(drop_parent))
578 return false;
580 int drop_index;
581 if (params->index)
582 drop_index = *params->index;
583 else
584 drop_index = drop_parent->child_count();
586 WebContents* web_contents =
587 WebContents::FromRenderViewHost(render_view_host_);
588 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) {
589 WebContents* web_contents =
590 dispatcher()->delegate()->GetAssociatedWebContents();
591 CHECK(web_contents);
592 ExtensionWebUI* web_ui =
593 static_cast<ExtensionWebUI*>(web_contents->GetWebUI()->GetController());
594 CHECK(web_ui);
595 BookmarkManagerPrivateDragEventRouter* router =
596 web_ui->bookmark_manager_private_drag_event_router();
598 DCHECK(router);
599 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData();
600 if (drag_data == NULL) {
601 NOTREACHED() <<"Somehow we're dropping null bookmark data";
602 return false;
604 const bool copy = false;
605 chrome::DropBookmarks(
606 GetProfile(), *drag_data, drop_parent, drop_index, copy);
608 router->ClearBookmarkNodeData();
609 return true;
610 } else {
611 NOTREACHED();
612 return false;
616 bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() {
617 scoped_ptr<GetSubtree::Params> params(GetSubtree::Params::Create(*args_));
618 EXTENSION_FUNCTION_VALIDATE(params);
620 const BookmarkNode* node = NULL;
622 if (params->id.empty()) {
623 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
624 node = model->root_node();
625 } else {
626 node = GetBookmarkNodeFromId(params->id);
627 if (!node)
628 return false;
631 std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> > nodes;
632 ChromeBookmarkClient* client = GetChromeBookmarkClient();
633 if (params->folders_only)
634 bookmark_api_helpers::AddNodeFoldersOnly(client, node, &nodes, true);
635 else
636 bookmark_api_helpers::AddNode(client, node, &nodes, true);
637 results_ = GetSubtree::Results::Create(nodes);
638 return true;
641 bool BookmarkManagerPrivateCanEditFunction::RunOnReady() {
642 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile());
643 SetResult(new base::FundamentalValue(
644 prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled)));
645 return true;
648 bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() {
649 RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER);
650 return true;
653 bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() {
654 scoped_ptr<CreateWithMetaInfo::Params> params(
655 CreateWithMetaInfo::Params::Create(*args_));
656 EXTENSION_FUNCTION_VALIDATE(params);
658 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
659 const BookmarkNode* node = CreateBookmarkNode(
660 model, params->bookmark, &params->meta_info.additional_properties);
661 if (!node)
662 return false;
664 scoped_ptr<api::bookmarks::BookmarkTreeNode> result_node(
665 bookmark_api_helpers::GetBookmarkTreeNode(
666 GetChromeBookmarkClient(), node, false, false));
667 results_ = CreateWithMetaInfo::Results::Create(*result_node);
669 return true;
672 bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() {
673 scoped_ptr<GetMetaInfo::Params> params(GetMetaInfo::Params::Create(*args_));
674 EXTENSION_FUNCTION_VALIDATE(params);
676 if (params->id) {
677 const BookmarkNode* node = GetBookmarkNodeFromId(*params->id);
678 if (!node)
679 return false;
681 if (params->key) {
682 std::string value;
683 if (node->GetMetaInfo(*params->key, &value)) {
684 GetMetaInfo::Results::Value result;
685 result.as_string.reset(new std::string(value));
686 results_ = GetMetaInfo::Results::Create(result);
688 } else {
689 GetMetaInfo::Results::Value result;
690 result.as_object.reset(new GetMetaInfo::Results::Value::Object);
692 const BookmarkNode::MetaInfoMap* meta_info = node->GetMetaInfoMap();
693 if (meta_info) {
694 BookmarkNode::MetaInfoMap::const_iterator itr;
695 base::DictionaryValue& temp = result.as_object->additional_properties;
696 for (itr = meta_info->begin(); itr != meta_info->end(); itr++) {
697 temp.SetStringWithoutPathExpansion(itr->first, itr->second);
700 results_ = GetMetaInfo::Results::Create(result);
702 } else {
703 if (params->key) {
704 error_ = bookmark_api_constants::kInvalidParamError;
705 return true;
708 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
709 const BookmarkNode* node = model->root_node();
711 GetMetaInfo::Results::Value result;
712 result.as_object.reset(new GetMetaInfo::Results::Value::Object);
714 bookmark_api_helpers::GetMetaInfo(*node,
715 &result.as_object->additional_properties);
717 results_ = GetMetaInfo::Results::Create(result);
720 return true;
723 bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() {
724 scoped_ptr<SetMetaInfo::Params> params(SetMetaInfo::Params::Create(*args_));
725 EXTENSION_FUNCTION_VALIDATE(params);
727 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
728 if (!node)
729 return false;
731 if (!CanBeModified(node))
732 return false;
734 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
735 if (model->is_permanent_node(node)) {
736 error_ = bookmark_keys::kModifySpecialError;
737 return false;
740 model->SetNodeMetaInfo(node, params->key, params->value);
741 return true;
744 bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() {
745 scoped_ptr<UpdateMetaInfo::Params> params(
746 UpdateMetaInfo::Params::Create(*args_));
747 EXTENSION_FUNCTION_VALIDATE(params);
749 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
750 if (!node)
751 return false;
753 if (!CanBeModified(node))
754 return false;
756 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
757 if (model->is_permanent_node(node)) {
758 error_ = bookmark_keys::kModifySpecialError;
759 return false;
762 BookmarkNode::MetaInfoMap new_meta_info(
763 params->meta_info_changes.additional_properties);
764 if (node->GetMetaInfoMap()) {
765 new_meta_info.insert(node->GetMetaInfoMap()->begin(),
766 node->GetMetaInfoMap()->end());
768 model->SetNodeMetaInfoMap(node, new_meta_info);
770 return true;
773 bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() {
774 bool can_open_new_windows = true;
775 SetResult(new base::FundamentalValue(can_open_new_windows));
776 return true;
779 bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() {
780 scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_));
781 EXTENSION_FUNCTION_VALIDATE(params);
783 BookmarkModel* model = GetBookmarkModel();
784 ChromeBookmarkClient* client = GetChromeBookmarkClient();
785 bookmarks::ScopedGroupBookmarkActions group_deletes(model);
786 int64 id;
787 for (size_t i = 0; i < params->id_list.size(); ++i) {
788 if (!GetBookmarkIdAsInt64(params->id_list[i], &id))
789 return false;
790 if (!bookmark_api_helpers::RemoveNode(model, client, id, true, &error_))
791 return false;
794 return true;
797 bool BookmarkManagerPrivateUndoFunction::RunOnReady() {
798 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
799 Undo();
800 return true;
803 bool BookmarkManagerPrivateRedoFunction::RunOnReady() {
804 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
805 Redo();
806 return true;
809 bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() {
810 UndoManager* undo_manager =
811 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
813 UndoInfo::Results::Result result;
814 result.enabled = undo_manager->undo_count() > 0;
815 result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel());
817 results_ = UndoInfo::Results::Create(result);
818 return true;
821 bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() {
822 UndoManager* undo_manager =
823 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
825 RedoInfo::Results::Result result;
826 result.enabled = undo_manager->redo_count() > 0;
827 result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel());
829 results_ = RedoInfo::Results::Create(result);
830 return true;
833 bool BookmarkManagerPrivateSetVersionFunction::RunOnReady() {
834 scoped_ptr<SetVersion::Params> params = SetVersion::Params::Create(*args_);
836 enhanced_bookmarks::EnhancedBookmarkModel* model =
837 enhanced_bookmarks::EnhancedBookmarkModelFactory::GetForBrowserContext(
838 browser_context());
839 model->SetVersionSuffix(params->version);
841 return true;
844 } // namespace extensions