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/bookmarks/chrome_bookmark_client.h"
18 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
19 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
20 #include "chrome/browser/extensions/extension_web_ui.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
23 #include "chrome/browser/undo/bookmark_undo_service.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/user_prefs/user_prefs.h"
33 #include "content/public/browser/render_view_host.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_ui.h"
36 #include "extensions/browser/extension_function_dispatcher.h"
37 #include "extensions/browser/view_type_utils.h"
38 #include "ui/base/dragdrop/drag_drop_types.h"
39 #include "ui/base/l10n/l10n_util.h"
40 #include "ui/base/webui/web_ui_util.h"
42 using bookmarks::BookmarkNodeData;
44 namespace extensions {
46 namespace bookmark_keys = bookmark_api_constants;
47 namespace bookmark_manager_private = api::bookmark_manager_private;
48 namespace CanPaste = api::bookmark_manager_private::CanPaste;
49 namespace Copy = api::bookmark_manager_private::Copy;
50 namespace CreateWithMetaInfo =
51 api::bookmark_manager_private::CreateWithMetaInfo;
52 namespace Cut = api::bookmark_manager_private::Cut;
53 namespace Drop = api::bookmark_manager_private::Drop;
54 namespace GetSubtree = api::bookmark_manager_private::GetSubtree;
55 namespace GetMetaInfo = api::bookmark_manager_private::GetMetaInfo;
56 namespace Paste = api::bookmark_manager_private::Paste;
57 namespace RedoInfo = api::bookmark_manager_private::GetRedoInfo;
58 namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees;
59 namespace SetMetaInfo = api::bookmark_manager_private::SetMetaInfo;
60 namespace SortChildren = api::bookmark_manager_private::SortChildren;
61 namespace StartDrag = api::bookmark_manager_private::StartDrag;
62 namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo;
63 namespace UpdateMetaInfo = api::bookmark_manager_private::UpdateMetaInfo;
65 using content::WebContents;
69 // Returns a single bookmark node from the argument ID.
70 // This returns NULL in case of failure.
71 const BookmarkNode* GetNodeFromString(BookmarkModel* model,
72 const std::string& id_string) {
74 if (!base::StringToInt64(id_string, &id))
76 return bookmarks::GetBookmarkNodeByID(model, id);
79 // Gets a vector of bookmark nodes from the argument list of IDs.
80 // This returns false in the case of failure.
81 bool GetNodesFromVector(BookmarkModel* model,
82 const std::vector<std::string>& id_strings,
83 std::vector<const BookmarkNode*>* nodes) {
84 if (id_strings.empty())
87 for (size_t i = 0; i < id_strings.size(); ++i) {
88 const BookmarkNode* node = GetNodeFromString(model, id_strings[i]);
91 nodes->push_back(node);
97 // Recursively create a bookmark_manager_private::BookmarkNodeDataElement from
98 // a bookmark node. This is by used |BookmarkNodeDataToJSON| when the data comes
99 // from the current profile. In this case we have a BookmarkNode since we got
100 // the data from the current profile.
101 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement>
102 CreateNodeDataElementFromBookmarkNode(const BookmarkNode& node) {
103 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> element(
104 new bookmark_manager_private::BookmarkNodeDataElement);
105 // Add id and parentId so we can associate the data with existing nodes on the
107 element->id.reset(new std::string(base::Int64ToString(node.id())));
108 element->parent_id.reset(
109 new std::string(base::Int64ToString(node.parent()->id())));
112 element->url.reset(new std::string(node.url().spec()));
114 element->title = base::UTF16ToUTF8(node.GetTitle());
115 for (int i = 0; i < node.child_count(); ++i) {
116 element->children.push_back(
117 CreateNodeDataElementFromBookmarkNode(*node.GetChild(i)));
123 // Recursively create a bookmark_manager_private::BookmarkNodeDataElement from
124 // a BookmarkNodeData::Element. This is used by |BookmarkNodeDataToJSON| when
125 // the data comes from a different profile. When the data comes from a different
126 // profile we do not have any IDs or parent IDs.
127 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement>
128 CreateApiNodeDataElement(const BookmarkNodeData::Element& element) {
129 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> node_element(
130 new bookmark_manager_private::BookmarkNodeDataElement);
133 node_element->url.reset(new std::string(element.url.spec()));
134 node_element->title = base::UTF16ToUTF8(element.title);
135 for (size_t i = 0; i < element.children.size(); ++i) {
136 node_element->children.push_back(
137 CreateApiNodeDataElement(element.children[i]));
143 // Creates a bookmark_manager_private::BookmarkNodeData from a BookmarkNodeData.
144 scoped_ptr<bookmark_manager_private::BookmarkNodeData>
145 CreateApiBookmarkNodeData(Profile* profile, const BookmarkNodeData& data) {
146 const base::FilePath& profile_path = profile->GetPath();
148 scoped_ptr<bookmark_manager_private::BookmarkNodeData> node_data(
149 new bookmark_manager_private::BookmarkNodeData);
150 node_data->same_profile = data.IsFromProfilePath(profile_path);
152 if (node_data->same_profile) {
153 std::vector<const BookmarkNode*> nodes = data.GetNodes(
154 BookmarkModelFactory::GetForProfile(profile), profile_path);
155 for (size_t i = 0; i < nodes.size(); ++i) {
156 node_data->elements.push_back(
157 CreateNodeDataElementFromBookmarkNode(*nodes[i]));
160 // We do not have a node IDs when the data comes from a different profile.
161 std::vector<BookmarkNodeData::Element> elements = data.elements;
162 for (size_t i = 0; i < elements.size(); ++i)
163 node_data->elements.push_back(CreateApiNodeDataElement(elements[i]));
165 return node_data.Pass();
170 BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter(
171 content::BrowserContext* browser_context,
172 BookmarkModel* bookmark_model)
173 : browser_context_(browser_context), bookmark_model_(bookmark_model) {
174 bookmark_model_->AddObserver(this);
177 BookmarkManagerPrivateEventRouter::~BookmarkManagerPrivateEventRouter() {
179 bookmark_model_->RemoveObserver(this);
182 void BookmarkManagerPrivateEventRouter::DispatchEvent(
183 const std::string& event_name,
184 scoped_ptr<base::ListValue> event_args) {
185 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(
186 make_scoped_ptr(new extensions::Event(event_name, event_args.Pass())));
189 void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {}
191 void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted(
192 BookmarkModel* model) {
193 bookmark_model_ = NULL;
196 void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo(
197 BookmarkModel* model,
198 const BookmarkNode* node) {
199 DCHECK(prev_meta_info_.empty());
200 if (node->GetMetaInfoMap())
201 prev_meta_info_ = *node->GetMetaInfoMap();
204 void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged(
205 BookmarkModel* model,
206 const BookmarkNode* node) {
207 const BookmarkNode::MetaInfoMap* new_meta_info = node->GetMetaInfoMap();
208 bookmark_manager_private::MetaInfoFields changes;
210 // Identify changed/removed fields:
211 for (BookmarkNode::MetaInfoMap::const_iterator it = prev_meta_info_.begin();
212 it != prev_meta_info_.end();
214 if (!new_meta_info) {
215 changes.additional_properties[it->first] = "";
217 BookmarkNode::MetaInfoMap::const_iterator new_meta_field =
218 new_meta_info->find(it->first);
219 if (new_meta_field == new_meta_info->end()) {
220 changes.additional_properties[it->first] = "";
221 } else if (it->second != new_meta_field->second) {
222 changes.additional_properties[it->first] = new_meta_field->second;
227 // Identify added fields:
229 for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin();
230 it != new_meta_info->end();
232 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field =
233 prev_meta_info_.find(it->first);
234 if (prev_meta_field == prev_meta_info_.end())
235 changes.additional_properties[it->first] = it->second;
239 prev_meta_info_.clear();
240 DispatchEvent(bookmark_manager_private::OnMetaInfoChanged::kEventName,
241 bookmark_manager_private::OnMetaInfoChanged::Create(
242 base::Int64ToString(node->id()), changes));
245 BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI(
246 content::BrowserContext* browser_context)
247 : browser_context_(browser_context) {
248 EventRouter* event_router = EventRouter::Get(browser_context);
249 event_router->RegisterObserver(
250 this, bookmark_manager_private::OnMetaInfoChanged::kEventName);
253 BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {}
255 void BookmarkManagerPrivateAPI::Shutdown() {
256 EventRouter::Get(browser_context_)->UnregisterObserver(this);
259 static base::LazyInstance<
260 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI> > g_factory =
261 LAZY_INSTANCE_INITIALIZER;
264 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI>*
265 BookmarkManagerPrivateAPI::GetFactoryInstance() {
266 return g_factory.Pointer();
269 void BookmarkManagerPrivateAPI::OnListenerAdded(
270 const EventListenerInfo& details) {
271 EventRouter::Get(browser_context_)->UnregisterObserver(this);
272 event_router_.reset(new BookmarkManagerPrivateEventRouter(
274 BookmarkModelFactory::GetForProfile(
275 Profile::FromBrowserContext(browser_context_))));
278 BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter(
280 content::WebContents* web_contents)
281 : profile_(profile), web_contents_(web_contents) {
282 BookmarkTabHelper* bookmark_tab_helper =
283 BookmarkTabHelper::FromWebContents(web_contents_);
284 bookmark_tab_helper->set_bookmark_drag_delegate(this);
287 BookmarkManagerPrivateDragEventRouter::
288 ~BookmarkManagerPrivateDragEventRouter() {
289 BookmarkTabHelper* bookmark_tab_helper =
290 BookmarkTabHelper::FromWebContents(web_contents_);
291 if (bookmark_tab_helper->bookmark_drag_delegate() == this)
292 bookmark_tab_helper->set_bookmark_drag_delegate(NULL);
295 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
296 const std::string& event_name,
297 scoped_ptr<base::ListValue> args) {
298 EventRouter* event_router = EventRouter::Get(profile_);
302 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
303 event_router->BroadcastEvent(event.Pass());
306 void BookmarkManagerPrivateDragEventRouter::OnDragEnter(
307 const BookmarkNodeData& data) {
308 if (data.size() == 0)
310 DispatchEvent(bookmark_manager_private::OnDragEnter::kEventName,
311 bookmark_manager_private::OnDragEnter::Create(
312 *CreateApiBookmarkNodeData(profile_, data)));
315 void BookmarkManagerPrivateDragEventRouter::OnDragOver(
316 const BookmarkNodeData& data) {
317 // Intentionally empty since these events happens too often and floods the
318 // message queue. We do not need this event for the bookmark manager anyway.
321 void BookmarkManagerPrivateDragEventRouter::OnDragLeave(
322 const BookmarkNodeData& data) {
323 if (data.size() == 0)
325 DispatchEvent(bookmark_manager_private::OnDragLeave::kEventName,
326 bookmark_manager_private::OnDragLeave::Create(
327 *CreateApiBookmarkNodeData(profile_, data)));
330 void BookmarkManagerPrivateDragEventRouter::OnDrop(
331 const BookmarkNodeData& data) {
332 if (data.size() == 0)
334 DispatchEvent(bookmark_manager_private::OnDrop::kEventName,
335 bookmark_manager_private::OnDrop::Create(
336 *CreateApiBookmarkNodeData(profile_, data)));
338 // Make a copy that is owned by this instance.
339 ClearBookmarkNodeData();
340 bookmark_drag_data_ = data;
343 const BookmarkNodeData*
344 BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() {
345 if (bookmark_drag_data_.is_valid())
346 return &bookmark_drag_data_;
350 void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() {
351 bookmark_drag_data_.Clear();
354 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut,
355 const std::vector<std::string>& id_list) {
356 BookmarkModel* model = GetBookmarkModel();
357 ChromeBookmarkClient* client = GetChromeBookmarkClient();
358 std::vector<const BookmarkNode*> nodes;
359 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model, id_list, &nodes));
360 if (cut && client->HasDescendantsOfManagedNode(nodes)) {
361 error_ = bookmark_keys::kModifyManagedError;
364 bookmarks::CopyToClipboard(model, nodes, cut);
368 bool BookmarkManagerPrivateCopyFunction::RunOnReady() {
369 scoped_ptr<Copy::Params> params(Copy::Params::Create(*args_));
370 EXTENSION_FUNCTION_VALIDATE(params);
371 return CopyOrCut(false, params->id_list);
374 bool BookmarkManagerPrivateCutFunction::RunOnReady() {
375 if (!EditBookmarksEnabled())
378 scoped_ptr<Cut::Params> params(Cut::Params::Create(*args_));
379 EXTENSION_FUNCTION_VALIDATE(params);
380 return CopyOrCut(true, params->id_list);
383 bool BookmarkManagerPrivatePasteFunction::RunOnReady() {
384 if (!EditBookmarksEnabled())
387 scoped_ptr<Paste::Params> params(Paste::Params::Create(*args_));
388 EXTENSION_FUNCTION_VALIDATE(params);
389 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
390 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
391 if (!CanBeModified(parent_node))
393 bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node);
397 // We want to use the highest index of the selected nodes as a destination.
398 std::vector<const BookmarkNode*> nodes;
399 // No need to test return value, if we got an empty list, we insert at end.
400 if (params->selected_id_list)
401 GetNodesFromVector(model, *params->selected_id_list, &nodes);
402 int highest_index = -1; // -1 means insert at end of list.
403 for (size_t i = 0; i < nodes.size(); ++i) {
404 // + 1 so that we insert after the selection.
405 int index = parent_node->GetIndexOf(nodes[i]) + 1;
406 if (index > highest_index)
407 highest_index = index;
410 bookmarks::PasteFromClipboard(model, parent_node, highest_index);
414 bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() {
415 if (!EditBookmarksEnabled())
418 scoped_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_));
419 EXTENSION_FUNCTION_VALIDATE(params);
421 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
422 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
424 error_ = bookmark_keys::kNoParentError;
427 bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node);
428 SetResult(new base::FundamentalValue(can_paste));
432 bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() {
433 if (!EditBookmarksEnabled())
436 scoped_ptr<SortChildren::Params> params(SortChildren::Params::Create(*args_));
437 EXTENSION_FUNCTION_VALIDATE(params);
439 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
440 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id);
441 if (!CanBeModified(parent_node))
443 model->SortChildren(parent_node);
447 bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
448 base::DictionaryValue* localized_strings = new base::DictionaryValue();
450 localized_strings->SetString("title",
451 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE));
452 localized_strings->SetString("search_button",
453 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON));
454 localized_strings->SetString("organize_menu",
455 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU));
456 localized_strings->SetString("show_in_folder",
457 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER));
458 localized_strings->SetString("sort",
459 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT));
460 localized_strings->SetString("import_menu",
461 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
462 localized_strings->SetString("export_menu",
463 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
464 localized_strings->SetString("rename_folder",
465 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER));
466 localized_strings->SetString("edit",
467 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT));
468 localized_strings->SetString("should_open_all",
469 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL));
470 localized_strings->SetString("open_incognito",
471 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO));
472 localized_strings->SetString("open_in_new_tab",
473 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB));
474 localized_strings->SetString("open_in_new_window",
475 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW));
476 localized_strings->SetString("add_new_bookmark",
477 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK));
478 localized_strings->SetString("new_folder",
479 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER));
480 localized_strings->SetString("open_all",
481 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL));
482 localized_strings->SetString("open_all_new_window",
483 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW));
484 localized_strings->SetString("open_all_incognito",
485 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO));
486 localized_strings->SetString("remove",
487 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE));
488 localized_strings->SetString("copy",
489 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY));
490 localized_strings->SetString("cut",
491 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT));
492 localized_strings->SetString("paste",
493 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE));
494 localized_strings->SetString("delete",
495 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE));
496 localized_strings->SetString("undo_delete",
497 l10n_util::GetStringUTF16(IDS_UNDO_DELETE));
498 localized_strings->SetString("new_folder_name",
499 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME));
500 localized_strings->SetString("name_input_placeholder",
501 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER));
502 localized_strings->SetString("url_input_placeholder",
503 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER));
504 localized_strings->SetString("invalid_url",
505 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL));
506 localized_strings->SetString("recent",
507 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT));
508 localized_strings->SetString("search",
509 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH));
510 localized_strings->SetString("save",
511 l10n_util::GetStringUTF16(IDS_SAVE));
512 localized_strings->SetString("cancel",
513 l10n_util::GetStringUTF16(IDS_CANCEL));
515 webui::SetFontAndTextDirection(localized_strings);
517 SetResult(localized_strings);
519 // This is needed because unlike the rest of these functions, this class
520 // inherits from AsyncFunction directly, rather than BookmarkFunction.
526 bool BookmarkManagerPrivateStartDragFunction::RunOnReady() {
527 if (!EditBookmarksEnabled())
530 scoped_ptr<StartDrag::Params> params(StartDrag::Params::Create(*args_));
531 EXTENSION_FUNCTION_VALIDATE(params);
533 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
534 std::vector<const BookmarkNode*> nodes;
535 EXTENSION_FUNCTION_VALIDATE(
536 GetNodesFromVector(model, params->id_list, &nodes));
538 WebContents* web_contents =
539 WebContents::FromRenderViewHost(render_view_host_);
540 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) {
541 WebContents* web_contents =
542 dispatcher()->delegate()->GetAssociatedWebContents();
545 ui::DragDropTypes::DragEventSource source =
546 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
547 if (params->is_from_touch)
548 source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
550 chrome::DragBookmarks(
551 GetProfile(), nodes, web_contents->GetNativeView(), source);
560 bool BookmarkManagerPrivateDropFunction::RunOnReady() {
561 if (!EditBookmarksEnabled())
564 scoped_ptr<Drop::Params> params(Drop::Params::Create(*args_));
565 EXTENSION_FUNCTION_VALIDATE(params);
567 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
569 const BookmarkNode* drop_parent = GetNodeFromString(model, params->parent_id);
570 if (!CanBeModified(drop_parent))
575 drop_index = *params->index;
577 drop_index = drop_parent->child_count();
579 WebContents* web_contents =
580 WebContents::FromRenderViewHost(render_view_host_);
581 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) {
582 WebContents* web_contents =
583 dispatcher()->delegate()->GetAssociatedWebContents();
585 ExtensionWebUI* web_ui =
586 static_cast<ExtensionWebUI*>(web_contents->GetWebUI()->GetController());
588 BookmarkManagerPrivateDragEventRouter* router =
589 web_ui->bookmark_manager_private_drag_event_router();
592 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData();
593 if (drag_data == NULL) {
594 NOTREACHED() <<"Somehow we're dropping null bookmark data";
597 const bool copy = false;
598 chrome::DropBookmarks(
599 GetProfile(), *drag_data, drop_parent, drop_index, copy);
601 router->ClearBookmarkNodeData();
609 bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() {
610 scoped_ptr<GetSubtree::Params> params(GetSubtree::Params::Create(*args_));
611 EXTENSION_FUNCTION_VALIDATE(params);
613 const BookmarkNode* node = NULL;
615 if (params->id == "") {
616 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
617 node = model->root_node();
619 node = GetBookmarkNodeFromId(params->id);
624 std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> > nodes;
625 ChromeBookmarkClient* client = GetChromeBookmarkClient();
626 if (params->folders_only)
627 bookmark_api_helpers::AddNodeFoldersOnly(client, node, &nodes, true);
629 bookmark_api_helpers::AddNode(client, node, &nodes, true);
630 results_ = GetSubtree::Results::Create(nodes);
634 bool BookmarkManagerPrivateCanEditFunction::RunOnReady() {
635 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile());
636 SetResult(new base::FundamentalValue(
637 prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled)));
641 bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() {
642 RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER);
646 bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() {
647 scoped_ptr<CreateWithMetaInfo::Params> params(
648 CreateWithMetaInfo::Params::Create(*args_));
649 EXTENSION_FUNCTION_VALIDATE(params);
651 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
652 const BookmarkNode* node = CreateBookmarkNode(
653 model, params->bookmark, ¶ms->meta_info.additional_properties);
657 scoped_ptr<api::bookmarks::BookmarkTreeNode> result_node(
658 bookmark_api_helpers::GetBookmarkTreeNode(
659 GetChromeBookmarkClient(), node, false, false));
660 results_ = CreateWithMetaInfo::Results::Create(*result_node);
665 bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() {
666 scoped_ptr<GetMetaInfo::Params> params(GetMetaInfo::Params::Create(*args_));
667 EXTENSION_FUNCTION_VALIDATE(params);
670 const BookmarkNode* node = GetBookmarkNodeFromId(*params->id);
676 if (node->GetMetaInfo(*params->key, &value)) {
677 GetMetaInfo::Results::Value result;
678 result.as_string.reset(new std::string(value));
679 results_ = GetMetaInfo::Results::Create(result);
682 GetMetaInfo::Results::Value result;
683 result.as_object.reset(new GetMetaInfo::Results::Value::Object);
685 const BookmarkNode::MetaInfoMap* meta_info = node->GetMetaInfoMap();
687 BookmarkNode::MetaInfoMap::const_iterator itr;
688 base::DictionaryValue& temp = result.as_object->additional_properties;
689 for (itr = meta_info->begin(); itr != meta_info->end(); itr++) {
690 temp.SetStringWithoutPathExpansion(itr->first, itr->second);
693 results_ = GetMetaInfo::Results::Create(result);
697 error_ = bookmark_api_constants::kInvalidParamError;
701 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
702 const BookmarkNode* node = model->root_node();
704 GetMetaInfo::Results::Value result;
705 result.as_object.reset(new GetMetaInfo::Results::Value::Object);
707 bookmark_api_helpers::GetMetaInfo(*node,
708 &result.as_object->additional_properties);
710 results_ = GetMetaInfo::Results::Create(result);
716 bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() {
717 scoped_ptr<SetMetaInfo::Params> params(SetMetaInfo::Params::Create(*args_));
718 EXTENSION_FUNCTION_VALIDATE(params);
720 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
724 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
725 model->SetNodeMetaInfo(node, params->key, params->value);
729 bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() {
730 scoped_ptr<UpdateMetaInfo::Params> params(
731 UpdateMetaInfo::Params::Create(*args_));
732 EXTENSION_FUNCTION_VALIDATE(params);
734 const BookmarkNode* node = GetBookmarkNodeFromId(params->id);
738 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
739 BookmarkNode::MetaInfoMap new_meta_info(
740 params->meta_info_changes.additional_properties);
741 if (node->GetMetaInfoMap()) {
742 new_meta_info.insert(node->GetMetaInfoMap()->begin(),
743 node->GetMetaInfoMap()->end());
745 model->SetNodeMetaInfoMap(node, new_meta_info);
750 bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() {
751 bool can_open_new_windows = true;
752 SetResult(new base::FundamentalValue(can_open_new_windows));
756 bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() {
757 scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_));
758 EXTENSION_FUNCTION_VALIDATE(params);
760 BookmarkModel* model = GetBookmarkModel();
761 ChromeBookmarkClient* client = GetChromeBookmarkClient();
762 bookmarks::ScopedGroupBookmarkActions group_deletes(model);
764 for (size_t i = 0; i < params->id_list.size(); ++i) {
765 if (!GetBookmarkIdAsInt64(params->id_list[i], &id))
767 if (!bookmark_api_helpers::RemoveNode(model, client, id, true, &error_))
774 bool BookmarkManagerPrivateUndoFunction::RunOnReady() {
775 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
780 bool BookmarkManagerPrivateRedoFunction::RunOnReady() {
781 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
786 bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() {
787 UndoManager* undo_manager =
788 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
790 UndoInfo::Results::Result result;
791 result.enabled = undo_manager->undo_count() > 0;
792 result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel());
794 results_ = UndoInfo::Results::Create(result);
798 bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() {
799 UndoManager* undo_manager =
800 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
802 RedoInfo::Results::Result result;
803 result.enabled = undo_manager->redo_count() > 0;
804 result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel());
806 results_ = RedoInfo::Results::Create(result);
810 } // namespace extensions