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"
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/extensions/api/bookmarks/bookmark_api_constants.h"
18 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
19 #include "chrome/browser/extensions/extension_web_ui.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
22 #include "chrome/browser/undo/bookmark_undo_service.h"
23 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
24 #include "chrome/common/extensions/api/bookmark_manager_private.h"
25 #include "chrome/common/pref_names.h"
26 #include "components/bookmarks/core/browser/bookmark_model.h"
27 #include "components/bookmarks/core/browser/bookmark_node_data.h"
28 #include "components/bookmarks/core/browser/bookmark_utils.h"
29 #include "components/bookmarks/core/browser/scoped_group_bookmark_actions.h"
30 #include "components/user_prefs/user_prefs.h"
31 #include "content/public/browser/render_view_host.h"
32 #include "content/public/browser/web_contents.h"
33 #include "content/public/browser/web_ui.h"
34 #include "extensions/browser/extension_function_dispatcher.h"
35 #include "extensions/browser/view_type_utils.h"
36 #include "grit/generated_resources.h"
37 #include "ui/base/dragdrop/drag_drop_types.h"
38 #include "ui/base/l10n/l10n_util.h"
39 #include "ui/base/webui/web_ui_util.h"
41 namespace extensions {
43 namespace bookmark_keys = bookmark_api_constants;
44 namespace bookmark_manager_private = api::bookmark_manager_private;
45 namespace CanPaste = api::bookmark_manager_private::CanPaste;
46 namespace Copy = api::bookmark_manager_private::Copy;
47 namespace CreateWithMetaInfo =
48 api::bookmark_manager_private::CreateWithMetaInfo;
49 namespace Cut = api::bookmark_manager_private::Cut;
50 namespace Drop = api::bookmark_manager_private::Drop;
51 namespace GetSubtree = api::bookmark_manager_private::GetSubtree;
52 namespace GetMetaInfo = api::bookmark_manager_private::GetMetaInfo;
53 namespace Paste = api::bookmark_manager_private::Paste;
54 namespace RedoInfo = api::bookmark_manager_private::GetRedoInfo;
55 namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees;
56 namespace SetMetaInfo = api::bookmark_manager_private::SetMetaInfo;
57 namespace SortChildren = api::bookmark_manager_private::SortChildren;
58 namespace StartDrag = api::bookmark_manager_private::StartDrag;
59 namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo;
60 namespace UpdateMetaInfo = api::bookmark_manager_private::UpdateMetaInfo;
62 using content::WebContents;
66 // Returns a single bookmark node from the argument ID.
67 // This returns NULL in case of failure.
68 const BookmarkNode* GetNodeFromString(BookmarkModel* model,
69 const std::string& id_string) {
71 if (!base::StringToInt64(id_string, &id))
73 return GetBookmarkNodeByID(model, id);
76 // Gets a vector of bookmark nodes from the argument list of IDs.
77 // This returns false in the case of failure.
78 bool GetNodesFromVector(BookmarkModel* model,
79 const std::vector<std::string>& id_strings,
80 std::vector<const BookmarkNode*>* nodes) {
82 if (id_strings.empty())
85 for (size_t i = 0; i < id_strings.size(); ++i) {
86 const BookmarkNode* node = GetNodeFromString(model, id_strings[i]);
89 nodes->push_back(node);
95 // Recursively create a bookmark_manager_private::BookmarkNodeDataElement from
96 // a bookmark node. This is by used |BookmarkNodeDataToJSON| when the data comes
97 // from the current profile. In this case we have a BookmarkNode since we got
98 // the data from the current profile.
99 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement>
100 CreateNodeDataElementFromBookmarkNode(const BookmarkNode& node) {
101 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> element(
102 new bookmark_manager_private::BookmarkNodeDataElement);
103 // Add id and parentId so we can associate the data with existing nodes on the
105 element->id.reset(new std::string(base::Int64ToString(node.id())));
106 element->parent_id.reset(
107 new std::string(base::Int64ToString(node.parent()->id())));
110 element->url.reset(new std::string(node.url().spec()));
112 element->title = base::UTF16ToUTF8(node.GetTitle());
113 for (int i = 0; i < node.child_count(); ++i) {
114 element->children.push_back(
115 CreateNodeDataElementFromBookmarkNode(*node.GetChild(i)));
121 // Recursively create a bookmark_manager_private::BookmarkNodeDataElement from
122 // a BookmarkNodeData::Element. This is used by |BookmarkNodeDataToJSON| when
123 // the data comes from a different profile. When the data comes from a different
124 // profile we do not have any IDs or parent IDs.
125 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement>
126 CreateApiNodeDataElement(const BookmarkNodeData::Element& element) {
127 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> node_element(
128 new bookmark_manager_private::BookmarkNodeDataElement);
131 node_element->url.reset(new std::string(element.url.spec()));
132 node_element->title = base::UTF16ToUTF8(element.title);
133 for (size_t i = 0; i < element.children.size(); ++i) {
134 node_element->children.push_back(
135 CreateApiNodeDataElement(element.children[i]));
141 // Creates a bookmark_manager_private::BookmarkNodeData from a BookmarkNodeData.
142 scoped_ptr<bookmark_manager_private::BookmarkNodeData>
143 CreateApiBookmarkNodeData(Profile* profile, const BookmarkNodeData& data) {
144 const base::FilePath& profile_path = profile->GetPath();
146 scoped_ptr<bookmark_manager_private::BookmarkNodeData> node_data(
147 new bookmark_manager_private::BookmarkNodeData);
148 node_data->same_profile = data.IsFromProfilePath(profile_path);
150 if (node_data->same_profile) {
151 std::vector<const BookmarkNode*> nodes = data.GetNodes(
152 BookmarkModelFactory::GetForProfile(profile), profile_path);
153 for (size_t i = 0; i < nodes.size(); ++i) {
154 node_data->elements.push_back(
155 CreateNodeDataElementFromBookmarkNode(*nodes[i]));
158 // We do not have a node IDs when the data comes from a different profile.
159 std::vector<BookmarkNodeData::Element> elements = data.elements;
160 for (size_t i = 0; i < elements.size(); ++i)
161 node_data->elements.push_back(CreateApiNodeDataElement(elements[i]));
163 return node_data.Pass();
168 BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter(
169 content::BrowserContext* browser_context,
170 BookmarkModel* bookmark_model)
171 : browser_context_(browser_context), bookmark_model_(bookmark_model) {
172 bookmark_model_->AddObserver(this);
175 BookmarkManagerPrivateEventRouter::~BookmarkManagerPrivateEventRouter() {
177 bookmark_model_->RemoveObserver(this);
180 void BookmarkManagerPrivateEventRouter::DispatchEvent(
181 const std::string& event_name,
182 scoped_ptr<base::ListValue> event_args) {
183 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(
184 make_scoped_ptr(new extensions::Event(event_name, event_args.Pass())));
187 void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {}
189 void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted(
190 BookmarkModel* model) {
191 bookmark_model_ = NULL;
194 void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo(
195 BookmarkModel* model,
196 const BookmarkNode* node) {
197 DCHECK(prev_meta_info_.empty());
198 if (node->GetMetaInfoMap())
199 prev_meta_info_ = *node->GetMetaInfoMap();
202 void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged(
203 BookmarkModel* model,
204 const BookmarkNode* node) {
205 const BookmarkNode::MetaInfoMap* new_meta_info = node->GetMetaInfoMap();
206 bookmark_manager_private::MetaInfoFields changes;
208 // Identify changed/removed fields:
209 for (BookmarkNode::MetaInfoMap::const_iterator it = prev_meta_info_.begin();
210 it != prev_meta_info_.end();
212 if (!new_meta_info) {
213 changes.additional_properties[it->first] = "";
215 BookmarkNode::MetaInfoMap::const_iterator new_meta_field =
216 new_meta_info->find(it->first);
217 if (new_meta_field == new_meta_info->end()) {
218 changes.additional_properties[it->first] = "";
219 } else if (it->second != new_meta_field->second) {
220 changes.additional_properties[it->first] = new_meta_field->second;
225 // Identify added fields:
227 for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin();
228 it != new_meta_info->end();
230 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field =
231 prev_meta_info_.find(it->first);
232 if (prev_meta_field == prev_meta_info_.end())
233 changes.additional_properties[it->first] = it->second;
237 prev_meta_info_.clear();
238 DispatchEvent(bookmark_manager_private::OnMetaInfoChanged::kEventName,
239 bookmark_manager_private::OnMetaInfoChanged::Create(
240 base::Int64ToString(node->id()), changes));
243 BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI(
244 content::BrowserContext* browser_context)
245 : browser_context_(browser_context) {
246 EventRouter* event_router = EventRouter::Get(browser_context);
247 event_router->RegisterObserver(
248 this, bookmark_manager_private::OnMetaInfoChanged::kEventName);
251 BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {}
253 void BookmarkManagerPrivateAPI::Shutdown() {
254 EventRouter::Get(browser_context_)->UnregisterObserver(this);
257 static base::LazyInstance<
258 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI> > g_factory =
259 LAZY_INSTANCE_INITIALIZER;
262 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI>*
263 BookmarkManagerPrivateAPI::GetFactoryInstance() {
264 return g_factory.Pointer();
267 void BookmarkManagerPrivateAPI::OnListenerAdded(
268 const EventListenerInfo& details) {
269 EventRouter::Get(browser_context_)->UnregisterObserver(this);
270 event_router_.reset(new BookmarkManagerPrivateEventRouter(
272 BookmarkModelFactory::GetForProfile(
273 Profile::FromBrowserContext(browser_context_))));
276 BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter(
278 content::WebContents* web_contents)
279 : profile_(profile), web_contents_(web_contents) {
280 BookmarkTabHelper* bookmark_tab_helper =
281 BookmarkTabHelper::FromWebContents(web_contents_);
282 bookmark_tab_helper->set_bookmark_drag_delegate(this);
285 BookmarkManagerPrivateDragEventRouter::
286 ~BookmarkManagerPrivateDragEventRouter() {
287 BookmarkTabHelper* bookmark_tab_helper =
288 BookmarkTabHelper::FromWebContents(web_contents_);
289 if (bookmark_tab_helper->bookmark_drag_delegate() == this)
290 bookmark_tab_helper->set_bookmark_drag_delegate(NULL);
293 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
294 const std::string& event_name,
295 scoped_ptr<base::ListValue> args) {
296 EventRouter* event_router = EventRouter::Get(profile_);
300 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
301 event_router->BroadcastEvent(event.Pass());
304 void BookmarkManagerPrivateDragEventRouter::OnDragEnter(
305 const BookmarkNodeData& data) {
306 if (data.size() == 0)
308 DispatchEvent(bookmark_manager_private::OnDragEnter::kEventName,
309 bookmark_manager_private::OnDragEnter::Create(
310 *CreateApiBookmarkNodeData(profile_, data)));
313 void BookmarkManagerPrivateDragEventRouter::OnDragOver(
314 const BookmarkNodeData& data) {
315 // Intentionally empty since these events happens too often and floods the
316 // message queue. We do not need this event for the bookmark manager anyway.
319 void BookmarkManagerPrivateDragEventRouter::OnDragLeave(
320 const BookmarkNodeData& data) {
321 if (data.size() == 0)
323 DispatchEvent(bookmark_manager_private::OnDragLeave::kEventName,
324 bookmark_manager_private::OnDragLeave::Create(
325 *CreateApiBookmarkNodeData(profile_, data)));
328 void BookmarkManagerPrivateDragEventRouter::OnDrop(
329 const BookmarkNodeData& data) {
330 if (data.size() == 0)
332 DispatchEvent(bookmark_manager_private::OnDrop::kEventName,
333 bookmark_manager_private::OnDrop::Create(
334 *CreateApiBookmarkNodeData(profile_, data)));
336 // Make a copy that is owned by this instance.
337 ClearBookmarkNodeData();
338 bookmark_drag_data_ = data;
341 const BookmarkNodeData*
342 BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() {
343 if (bookmark_drag_data_.is_valid())
344 return &bookmark_drag_data_;
348 void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() {
349 bookmark_drag_data_.Clear();
352 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut,
353 const std::vector<std::string>& id_list) {
354 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
355 std::vector<const BookmarkNode*> nodes;
356 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model, id_list, &nodes));
357 bookmark_utils::CopyToClipboard(model, nodes, cut);
361 bool BookmarkManagerPrivateCopyFunction::RunOnReady() {
362 scoped_ptr<Copy::Params> params(Copy::Params::Create(*args_));
363 EXTENSION_FUNCTION_VALIDATE(params);
364 return CopyOrCut(false, params->id_list);
367 bool BookmarkManagerPrivateCutFunction::RunOnReady() {
368 if (!EditBookmarksEnabled())
371 scoped_ptr<Cut::Params> params(Cut::Params::Create(*args_));
372 EXTENSION_FUNCTION_VALIDATE(params);
373 return CopyOrCut(true, params->id_list);
376 bool BookmarkManagerPrivatePasteFunction::RunOnReady() {
377 if (!EditBookmarksEnabled())
380 scoped_ptr<Paste::Params> params(Paste::Params::Create(*args_));
381 EXTENSION_FUNCTION_VALIDATE(params);
382 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
383 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
385 error_ = bookmark_keys::kNoParentError;
388 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node);
392 // We want to use the highest index of the selected nodes as a destination.
393 std::vector<const BookmarkNode*> nodes;
394 // No need to test return value, if we got an empty list, we insert at end.
395 if (params->selected_id_list)
396 GetNodesFromVector(model, *params->selected_id_list, &nodes);
397 int highest_index = -1; // -1 means insert at end of list.
398 for (size_t i = 0; i < nodes.size(); ++i) {
399 // + 1 so that we insert after the selection.
400 int index = parent_node->GetIndexOf(nodes[i]) + 1;
401 if (index > highest_index)
402 highest_index = index;
405 bookmark_utils::PasteFromClipboard(model, parent_node, highest_index);
409 bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() {
410 if (!EditBookmarksEnabled())
413 scoped_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_));
414 EXTENSION_FUNCTION_VALIDATE(params);
416 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
417 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
419 error_ = bookmark_keys::kNoParentError;
422 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node);
423 SetResult(new base::FundamentalValue(can_paste));
427 bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() {
428 if (!EditBookmarksEnabled())
431 scoped_ptr<SortChildren::Params> params(SortChildren::Params::Create(*args_));
432 EXTENSION_FUNCTION_VALIDATE(params);
434 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
435 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
437 error_ = bookmark_keys::kNoParentError;
440 model->SortChildren(parent_node);
444 bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
445 base::DictionaryValue* localized_strings = new base::DictionaryValue();
447 localized_strings->SetString("title",
448 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE));
449 localized_strings->SetString("search_button",
450 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON));
451 localized_strings->SetString("organize_menu",
452 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU));
453 localized_strings->SetString("show_in_folder",
454 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER));
455 localized_strings->SetString("sort",
456 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT));
457 localized_strings->SetString("import_menu",
458 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
459 localized_strings->SetString("export_menu",
460 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
461 localized_strings->SetString("rename_folder",
462 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER));
463 localized_strings->SetString("edit",
464 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT));
465 localized_strings->SetString("should_open_all",
466 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL));
467 localized_strings->SetString("open_incognito",
468 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO));
469 localized_strings->SetString("open_in_new_tab",
470 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB));
471 localized_strings->SetString("open_in_new_window",
472 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW));
473 localized_strings->SetString("add_new_bookmark",
474 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
475 localized_strings->SetString("new_folder",
476 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER));
477 localized_strings->SetString("open_all",
478 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL));
479 localized_strings->SetString("open_all_new_window",
480 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
481 localized_strings->SetString("open_all_incognito",
482 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
483 localized_strings->SetString("remove",
484 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE));
485 localized_strings->SetString("copy",
486 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY));
487 localized_strings->SetString("cut",
488 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT));
489 localized_strings->SetString("paste",
490 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE));
491 localized_strings->SetString("delete",
492 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE));
493 localized_strings->SetString("undo_delete",
494 l10n_util::GetStringUTF16(IDS_UNDO_DELETE));
495 localized_strings->SetString("new_folder_name",
496 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME));
497 localized_strings->SetString("name_input_placeholder",
498 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER));
499 localized_strings->SetString("url_input_placeholder",
500 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER));
501 localized_strings->SetString("invalid_url",
502 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL));
503 localized_strings->SetString("recent",
504 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT));
505 localized_strings->SetString("search",
506 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH));
507 localized_strings->SetString("save",
508 l10n_util::GetStringUTF16(IDS_SAVE));
509 localized_strings->SetString("cancel",
510 l10n_util::GetStringUTF16(IDS_CANCEL));
512 webui::SetFontAndTextDirection(localized_strings);
514 SetResult(localized_strings);
516 // This is needed because unlike the rest of these functions, this class
517 // inherits from AsyncFunction directly, rather than BookmarkFunction.
523 bool BookmarkManagerPrivateStartDragFunction::RunOnReady() {
524 if (!EditBookmarksEnabled())
527 scoped_ptr<StartDrag::Params> params(StartDrag::Params::Create(*args_));
528 EXTENSION_FUNCTION_VALIDATE(params);
530 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
531 std::vector<const BookmarkNode*> nodes;
532 EXTENSION_FUNCTION_VALIDATE(
533 GetNodesFromVector(model, params->id_list, &nodes));
535 WebContents* web_contents =
536 WebContents::FromRenderViewHost(render_view_host_);
537 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) {
538 WebContents* web_contents =
539 dispatcher()->delegate()->GetAssociatedWebContents();
542 ui::DragDropTypes::DragEventSource source =
543 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
544 if (params->is_from_touch)
545 source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
547 chrome::DragBookmarks(
548 GetProfile(), nodes, web_contents->GetNativeView(), source);
557 bool BookmarkManagerPrivateDropFunction::RunOnReady() {
558 if (!EditBookmarksEnabled())
561 scoped_ptr<Drop::Params> params(Drop::Params::Create(*args_));
562 EXTENSION_FUNCTION_VALIDATE(params);
564 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
566 const BookmarkNode* drop_parent = GetNodeFromString(model, params->parent_id);
568 error_ = bookmark_keys::kNoParentError;
574 drop_index = *params->index;
576 drop_index = drop_parent->child_count();
578 WebContents* web_contents =
579 WebContents::FromRenderViewHost(render_view_host_);
580 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) {
581 WebContents* web_contents =
582 dispatcher()->delegate()->GetAssociatedWebContents();
584 ExtensionWebUI* web_ui =
585 static_cast<ExtensionWebUI*>(web_contents->GetWebUI()->GetController());
587 BookmarkManagerPrivateDragEventRouter* router =
588 web_ui->bookmark_manager_private_drag_event_router();
591 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData();
592 if (drag_data == NULL) {
593 NOTREACHED() <<"Somehow we're dropping null bookmark data";
596 chrome::DropBookmarks(GetProfile(), *drag_data, drop_parent, drop_index);
598 router->ClearBookmarkNodeData();
606 bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() {
607 scoped_ptr<GetSubtree::Params> params(GetSubtree::Params::Create(*args_));
608 EXTENSION_FUNCTION_VALIDATE(params);
610 const BookmarkNode* node = NULL;
612 if (params->id == "") {
613 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
614 node = model->root_node();
616 node = GetBookmarkNodeFromId(params->id);
621 std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> > nodes;
622 if (params->folders_only)
623 bookmark_api_helpers::AddNodeFoldersOnly(node, &nodes, true);
625 bookmark_api_helpers::AddNode(node, &nodes, true);
626 results_ = GetSubtree::Results::Create(nodes);
630 bool BookmarkManagerPrivateCanEditFunction::RunOnReady() {
631 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile());
632 SetResult(new base::FundamentalValue(
633 prefs->GetBoolean(prefs::kEditBookmarksEnabled)));
637 bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() {
638 RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER);
642 bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() {
643 scoped_ptr<CreateWithMetaInfo::Params> params(
644 CreateWithMetaInfo::Params::Create(*args_));
645 EXTENSION_FUNCTION_VALIDATE(params);
647 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
648 const BookmarkNode* node = CreateBookmarkNode(
649 model, params->bookmark, ¶ms->meta_info.additional_properties);
653 scoped_ptr<api::bookmarks::BookmarkTreeNode> result_node(
654 bookmark_api_helpers::GetBookmarkTreeNode(node, false, false));
655 results_ = CreateWithMetaInfo::Results::Create(*result_node);
660 bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() {
661 scoped_ptr<GetMetaInfo::Params> params(GetMetaInfo::Params::Create(*args_));
662 EXTENSION_FUNCTION_VALIDATE(params);
664 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
670 if (node->GetMetaInfo(*params->key, &value)) {
671 GetMetaInfo::Results::Value result;
672 result.as_string.reset(new std::string(value));
673 results_ = GetMetaInfo::Results::Create(result);
676 GetMetaInfo::Results::Value result;
677 result.as_meta_info_fields.reset(
678 new bookmark_manager_private::MetaInfoFields);
680 const BookmarkNode::MetaInfoMap* meta_info = node->GetMetaInfoMap();
682 result.as_meta_info_fields->additional_properties = *meta_info;
683 results_ = GetMetaInfo::Results::Create(result);
689 bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() {
690 scoped_ptr<SetMetaInfo::Params> params(SetMetaInfo::Params::Create(*args_));
691 EXTENSION_FUNCTION_VALIDATE(params);
693 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
697 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
698 model->SetNodeMetaInfo(node, params->key, params->value);
702 bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() {
703 scoped_ptr<UpdateMetaInfo::Params> params(
704 UpdateMetaInfo::Params::Create(*args_));
705 EXTENSION_FUNCTION_VALIDATE(params);
707 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
711 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
712 BookmarkNode::MetaInfoMap new_meta_info(
713 params->meta_info_changes.additional_properties);
714 if (node->GetMetaInfoMap()) {
715 new_meta_info.insert(node->GetMetaInfoMap()->begin(),
716 node->GetMetaInfoMap()->end());
718 model->SetNodeMetaInfoMap(node, new_meta_info);
723 bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() {
724 bool can_open_new_windows = true;
725 SetResult(new base::FundamentalValue(can_open_new_windows));
729 bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() {
730 scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_));
731 EXTENSION_FUNCTION_VALIDATE(params);
733 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
734 #if !defined(OS_ANDROID)
735 ScopedGroupBookmarkActions group_deletes(model);
738 for (size_t i = 0; i < params->id_list.size(); ++i) {
739 if (!GetBookmarkIdAsInt64(params->id_list[i], &id))
741 if (!bookmark_api_helpers::RemoveNode(model, id, true, &error_))
748 bool BookmarkManagerPrivateUndoFunction::RunOnReady() {
749 #if !defined(OS_ANDROID)
750 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
757 bool BookmarkManagerPrivateRedoFunction::RunOnReady() {
758 #if !defined(OS_ANDROID)
759 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
766 bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() {
767 #if !defined(OS_ANDROID)
768 UndoManager* undo_manager =
769 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
771 UndoInfo::Results::Result result;
772 result.enabled = undo_manager->undo_count() > 0;
773 result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel());
775 results_ = UndoInfo::Results::Create(result);
776 #endif // !defined(OS_ANDROID)
781 bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() {
782 #if !defined(OS_ANDROID)
783 UndoManager* undo_manager =
784 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
786 RedoInfo::Results::Result result;
787 result.enabled = undo_manager->redo_count() > 0;
788 result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel());
790 results_ = RedoInfo::Results::Create(result);
791 #endif // !defined(OS_ANDROID)
796 } // namespace extensions