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/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_factory.h"
26 #include "chrome/common/extensions/api/bookmark_manager_private.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/grit/generated_resources.h"
29 #include "components/bookmarks/browser/bookmark_model.h"
30 #include "components/bookmarks/browser/bookmark_node_data.h"
31 #include "components/bookmarks/browser/bookmark_utils.h"
32 #include "components/bookmarks/browser/scoped_group_bookmark_actions.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
;
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
) {
79 if (!base::StringToInt64(id_string
, &id
))
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())
92 for (size_t i
= 0; i
< id_strings
.size(); ++i
) {
93 const BookmarkNode
* node
= GetNodeFromString(model
, id_strings
[i
]);
96 nodes
->push_back(node
);
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
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())));
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
)));
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
);
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
]));
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
]));
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();
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() {
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_
)
190 ->BroadcastEvent(make_scoped_ptr(new extensions::Event(
191 extensions::events::UNKNOWN
, event_name
, event_args
.Pass())));
194 void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {}
196 void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted(
197 BookmarkModel
* model
) {
198 bookmark_model_
= NULL
;
201 void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo(
202 BookmarkModel
* model
,
203 const BookmarkNode
* node
) {
204 DCHECK(prev_meta_info_
.empty());
205 if (node
->GetMetaInfoMap())
206 prev_meta_info_
= *node
->GetMetaInfoMap();
209 void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged(
210 BookmarkModel
* model
,
211 const BookmarkNode
* node
) {
212 const BookmarkNode::MetaInfoMap
* new_meta_info
= node
->GetMetaInfoMap();
213 bookmark_manager_private::MetaInfoFields changes
;
215 // Identify changed/removed fields:
216 for (BookmarkNode::MetaInfoMap::const_iterator it
= prev_meta_info_
.begin();
217 it
!= prev_meta_info_
.end();
219 if (!new_meta_info
) {
220 changes
.additional_properties
[it
->first
] = "";
222 BookmarkNode::MetaInfoMap::const_iterator new_meta_field
=
223 new_meta_info
->find(it
->first
);
224 if (new_meta_field
== new_meta_info
->end()) {
225 changes
.additional_properties
[it
->first
] = "";
226 } else if (it
->second
!= new_meta_field
->second
) {
227 changes
.additional_properties
[it
->first
] = new_meta_field
->second
;
232 // Identify added fields:
234 for (BookmarkNode::MetaInfoMap::const_iterator it
= new_meta_info
->begin();
235 it
!= new_meta_info
->end();
237 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field
=
238 prev_meta_info_
.find(it
->first
);
239 if (prev_meta_field
== prev_meta_info_
.end())
240 changes
.additional_properties
[it
->first
] = it
->second
;
244 prev_meta_info_
.clear();
245 DispatchEvent(bookmark_manager_private::OnMetaInfoChanged::kEventName
,
246 bookmark_manager_private::OnMetaInfoChanged::Create(
247 base::Int64ToString(node
->id()), changes
));
250 BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI(
251 content::BrowserContext
* browser_context
)
252 : browser_context_(browser_context
) {
253 EventRouter
* event_router
= EventRouter::Get(browser_context
);
254 event_router
->RegisterObserver(
255 this, bookmark_manager_private::OnMetaInfoChanged::kEventName
);
258 BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {}
260 void BookmarkManagerPrivateAPI::Shutdown() {
261 EventRouter::Get(browser_context_
)->UnregisterObserver(this);
264 static base::LazyInstance
<
265 BrowserContextKeyedAPIFactory
<BookmarkManagerPrivateAPI
> > g_factory
=
266 LAZY_INSTANCE_INITIALIZER
;
269 BrowserContextKeyedAPIFactory
<BookmarkManagerPrivateAPI
>*
270 BookmarkManagerPrivateAPI::GetFactoryInstance() {
271 return g_factory
.Pointer();
274 void BookmarkManagerPrivateAPI::OnListenerAdded(
275 const EventListenerInfo
& details
) {
276 EventRouter::Get(browser_context_
)->UnregisterObserver(this);
277 event_router_
.reset(new BookmarkManagerPrivateEventRouter(
279 BookmarkModelFactory::GetForProfile(
280 Profile::FromBrowserContext(browser_context_
))));
283 BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter(
285 content::WebContents
* web_contents
)
286 : profile_(profile
), web_contents_(web_contents
) {
287 BookmarkTabHelper
* bookmark_tab_helper
=
288 BookmarkTabHelper::FromWebContents(web_contents_
);
289 bookmark_tab_helper
->set_bookmark_drag_delegate(this);
292 BookmarkManagerPrivateDragEventRouter::
293 ~BookmarkManagerPrivateDragEventRouter() {
294 BookmarkTabHelper
* bookmark_tab_helper
=
295 BookmarkTabHelper::FromWebContents(web_contents_
);
296 if (bookmark_tab_helper
->bookmark_drag_delegate() == this)
297 bookmark_tab_helper
->set_bookmark_drag_delegate(NULL
);
300 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
301 const std::string
& event_name
,
302 scoped_ptr
<base::ListValue
> args
) {
303 EventRouter
* event_router
= EventRouter::Get(profile_
);
307 scoped_ptr
<Event
> event(new Event(events::UNKNOWN
, event_name
, args
.Pass()));
308 event_router
->BroadcastEvent(event
.Pass());
311 void BookmarkManagerPrivateDragEventRouter::OnDragEnter(
312 const BookmarkNodeData
& data
) {
313 if (!data
.is_valid())
315 DispatchEvent(bookmark_manager_private::OnDragEnter::kEventName
,
316 bookmark_manager_private::OnDragEnter::Create(
317 *CreateApiBookmarkNodeData(profile_
, data
)));
320 void BookmarkManagerPrivateDragEventRouter::OnDragOver(
321 const BookmarkNodeData
& data
) {
322 // Intentionally empty since these events happens too often and floods the
323 // message queue. We do not need this event for the bookmark manager anyway.
326 void BookmarkManagerPrivateDragEventRouter::OnDragLeave(
327 const BookmarkNodeData
& data
) {
328 if (!data
.is_valid())
330 DispatchEvent(bookmark_manager_private::OnDragLeave::kEventName
,
331 bookmark_manager_private::OnDragLeave::Create(
332 *CreateApiBookmarkNodeData(profile_
, data
)));
335 void BookmarkManagerPrivateDragEventRouter::OnDrop(
336 const BookmarkNodeData
& data
) {
337 if (!data
.is_valid())
339 DispatchEvent(bookmark_manager_private::OnDrop::kEventName
,
340 bookmark_manager_private::OnDrop::Create(
341 *CreateApiBookmarkNodeData(profile_
, data
)));
343 // Make a copy that is owned by this instance.
344 ClearBookmarkNodeData();
345 bookmark_drag_data_
= data
;
348 const BookmarkNodeData
*
349 BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() {
350 if (bookmark_drag_data_
.is_valid())
351 return &bookmark_drag_data_
;
355 void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() {
356 bookmark_drag_data_
.Clear();
359 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut
,
360 const std::vector
<std::string
>& id_list
) {
361 BookmarkModel
* model
= GetBookmarkModel();
362 ChromeBookmarkClient
* client
= GetChromeBookmarkClient();
363 std::vector
<const BookmarkNode
*> nodes
;
364 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model
, id_list
, &nodes
));
365 if (cut
&& bookmarks::HasDescendantsOf(nodes
, client
->managed_node())) {
366 error_
= bookmark_keys::kModifyManagedError
;
369 bookmarks::CopyToClipboard(model
, nodes
, cut
);
373 bool BookmarkManagerPrivateCopyFunction::RunOnReady() {
374 scoped_ptr
<Copy::Params
> params(Copy::Params::Create(*args_
));
375 EXTENSION_FUNCTION_VALIDATE(params
);
376 return CopyOrCut(false, params
->id_list
);
379 bool BookmarkManagerPrivateCutFunction::RunOnReady() {
380 if (!EditBookmarksEnabled())
383 scoped_ptr
<Cut::Params
> params(Cut::Params::Create(*args_
));
384 EXTENSION_FUNCTION_VALIDATE(params
);
385 return CopyOrCut(true, params
->id_list
);
388 bool BookmarkManagerPrivatePasteFunction::RunOnReady() {
389 if (!EditBookmarksEnabled())
392 scoped_ptr
<Paste::Params
> params(Paste::Params::Create(*args_
));
393 EXTENSION_FUNCTION_VALIDATE(params
);
394 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
395 const BookmarkNode
* parent_node
= GetNodeFromString(model
, params
->parent_id
);
396 if (!CanBeModified(parent_node
))
398 bool can_paste
= bookmarks::CanPasteFromClipboard(model
, parent_node
);
402 // We want to use the highest index of the selected nodes as a destination.
403 std::vector
<const BookmarkNode
*> nodes
;
404 // No need to test return value, if we got an empty list, we insert at end.
405 if (params
->selected_id_list
)
406 GetNodesFromVector(model
, *params
->selected_id_list
, &nodes
);
407 int highest_index
= -1; // -1 means insert at end of list.
408 for (size_t i
= 0; i
< nodes
.size(); ++i
) {
409 // + 1 so that we insert after the selection.
410 int index
= parent_node
->GetIndexOf(nodes
[i
]) + 1;
411 if (index
> highest_index
)
412 highest_index
= index
;
415 bookmarks::PasteFromClipboard(model
, parent_node
, highest_index
);
419 bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() {
420 scoped_ptr
<CanPaste::Params
> params(CanPaste::Params::Create(*args_
));
421 EXTENSION_FUNCTION_VALIDATE(params
);
423 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetProfile());
424 if (!prefs
->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled
)) {
425 SetResult(new base::FundamentalValue(false));
429 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
430 const BookmarkNode
* parent_node
= GetNodeFromString(model
, params
->parent_id
);
432 error_
= bookmark_keys::kNoParentError
;
435 bool can_paste
= bookmarks::CanPasteFromClipboard(model
, parent_node
);
436 SetResult(new base::FundamentalValue(can_paste
));
440 bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() {
441 if (!EditBookmarksEnabled())
444 scoped_ptr
<SortChildren::Params
> params(SortChildren::Params::Create(*args_
));
445 EXTENSION_FUNCTION_VALIDATE(params
);
447 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
448 const BookmarkNode
* parent_node
= GetNodeFromString(model
, params
->parent_id
);
449 if (!CanBeModified(parent_node
))
451 model
->SortChildren(parent_node
);
455 bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
456 base::DictionaryValue
* localized_strings
= new base::DictionaryValue();
458 localized_strings
->SetString("title",
459 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE
));
460 localized_strings
->SetString("search_button",
461 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON
));
462 localized_strings
->SetString("folders_menu",
463 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_FOLDERS_MENU
));
464 localized_strings
->SetString("organize_menu",
465 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU
));
466 localized_strings
->SetString("show_in_folder",
467 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER
));
468 localized_strings
->SetString("sort",
469 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT
));
470 localized_strings
->SetString("import_menu",
471 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU
));
472 localized_strings
->SetString("export_menu",
473 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU
));
474 localized_strings
->SetString("rename_folder",
475 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER
));
476 localized_strings
->SetString("edit",
477 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT
));
478 localized_strings
->SetString("should_open_all",
479 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL
));
480 localized_strings
->SetString("open_incognito",
481 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO
));
482 localized_strings
->SetString("open_in_new_tab",
483 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB
));
484 localized_strings
->SetString("open_in_new_window",
485 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW
));
486 localized_strings
->SetString("add_new_bookmark",
487 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK
));
488 localized_strings
->SetString("new_folder",
489 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER
));
490 localized_strings
->SetString("open_all",
491 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL
));
492 localized_strings
->SetString("open_all_new_window",
493 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW
));
494 localized_strings
->SetString("open_all_incognito",
495 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO
));
496 localized_strings
->SetString("remove",
497 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE
));
498 localized_strings
->SetString("copy",
499 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY
));
500 localized_strings
->SetString("cut",
501 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT
));
502 localized_strings
->SetString("paste",
503 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE
));
504 localized_strings
->SetString("delete",
505 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE
));
506 localized_strings
->SetString("undo_delete",
507 l10n_util::GetStringUTF16(IDS_UNDO_DELETE
));
508 localized_strings
->SetString("new_folder_name",
509 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME
));
510 localized_strings
->SetString("name_input_placeholder",
511 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER
));
512 localized_strings
->SetString("url_input_placeholder",
513 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER
));
514 localized_strings
->SetString("invalid_url",
515 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL
));
516 localized_strings
->SetString("recent",
517 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT
));
518 localized_strings
->SetString("search",
519 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH
));
520 localized_strings
->SetString("save",
521 l10n_util::GetStringUTF16(IDS_SAVE
));
522 localized_strings
->SetString("cancel",
523 l10n_util::GetStringUTF16(IDS_CANCEL
));
525 const std::string
& app_locale
= g_browser_process
->GetApplicationLocale();
526 webui::SetLoadTimeDataDefaults(app_locale
, localized_strings
);
528 SetResult(localized_strings
);
530 // This is needed because unlike the rest of these functions, this class
531 // inherits from AsyncFunction directly, rather than BookmarkFunction.
537 bool BookmarkManagerPrivateStartDragFunction::RunOnReady() {
538 if (!EditBookmarksEnabled())
541 if (GetViewType(GetSenderWebContents()) != VIEW_TYPE_TAB_CONTENTS
) {
546 scoped_ptr
<StartDrag::Params
> params(StartDrag::Params::Create(*args_
));
547 EXTENSION_FUNCTION_VALIDATE(params
);
549 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
550 std::vector
<const BookmarkNode
*> nodes
;
551 EXTENSION_FUNCTION_VALIDATE(
552 GetNodesFromVector(model
, params
->id_list
, &nodes
));
554 content::WebContents
* web_contents
= GetAssociatedWebContents();
557 ui::DragDropTypes::DragEventSource source
=
558 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE
;
559 if (params
->is_from_touch
)
560 source
= ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH
;
562 chrome::DragBookmarks(
563 GetProfile(), nodes
, web_contents
->GetNativeView(), source
);
568 bool BookmarkManagerPrivateDropFunction::RunOnReady() {
569 if (!EditBookmarksEnabled())
572 scoped_ptr
<Drop::Params
> params(Drop::Params::Create(*args_
));
573 EXTENSION_FUNCTION_VALIDATE(params
);
575 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
577 const BookmarkNode
* drop_parent
= GetNodeFromString(model
, params
->parent_id
);
578 if (!CanBeModified(drop_parent
))
581 if (GetViewType(GetSenderWebContents()) != VIEW_TYPE_TAB_CONTENTS
) {
588 drop_index
= *params
->index
;
590 drop_index
= drop_parent
->child_count();
592 WebContents
* web_contents
= GetAssociatedWebContents();
594 ExtensionWebUI
* web_ui
=
595 static_cast<ExtensionWebUI
*>(web_contents
->GetWebUI()->GetController());
597 BookmarkManagerPrivateDragEventRouter
* router
=
598 web_ui
->bookmark_manager_private_drag_event_router();
601 const BookmarkNodeData
* drag_data
= router
->GetBookmarkNodeData();
602 if (drag_data
== NULL
) {
603 NOTREACHED() <<"Somehow we're dropping null bookmark data";
606 const bool copy
= false;
607 chrome::DropBookmarks(
608 GetProfile(), *drag_data
, drop_parent
, drop_index
, copy
);
610 router
->ClearBookmarkNodeData();
614 bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() {
615 scoped_ptr
<GetSubtree::Params
> params(GetSubtree::Params::Create(*args_
));
616 EXTENSION_FUNCTION_VALIDATE(params
);
618 const BookmarkNode
* node
= NULL
;
620 if (params
->id
.empty()) {
621 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
622 node
= model
->root_node();
624 node
= GetBookmarkNodeFromId(params
->id
);
629 std::vector
<linked_ptr
<api::bookmarks::BookmarkTreeNode
> > nodes
;
630 ChromeBookmarkClient
* client
= GetChromeBookmarkClient();
631 if (params
->folders_only
)
632 bookmark_api_helpers::AddNodeFoldersOnly(client
, node
, &nodes
, true);
634 bookmark_api_helpers::AddNode(client
, node
, &nodes
, true);
635 results_
= GetSubtree::Results::Create(nodes
);
639 bool BookmarkManagerPrivateCanEditFunction::RunOnReady() {
640 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetProfile());
641 SetResult(new base::FundamentalValue(
642 prefs
->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled
)));
646 bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() {
647 RecordBookmarkLaunch(NULL
, BOOKMARK_LAUNCH_LOCATION_MANAGER
);
651 bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() {
652 if (!EditBookmarksEnabled())
655 scoped_ptr
<CreateWithMetaInfo::Params
> params(
656 CreateWithMetaInfo::Params::Create(*args_
));
657 EXTENSION_FUNCTION_VALIDATE(params
);
659 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
660 const BookmarkNode
* node
= CreateBookmarkNode(
661 model
, params
->bookmark
, ¶ms
->meta_info
.additional_properties
);
665 scoped_ptr
<api::bookmarks::BookmarkTreeNode
> result_node(
666 bookmark_api_helpers::GetBookmarkTreeNode(
667 GetChromeBookmarkClient(), node
, false, false));
668 results_
= CreateWithMetaInfo::Results::Create(*result_node
);
673 bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() {
674 scoped_ptr
<GetMetaInfo::Params
> params(GetMetaInfo::Params::Create(*args_
));
675 EXTENSION_FUNCTION_VALIDATE(params
);
678 const BookmarkNode
* node
= GetBookmarkNodeFromId(*params
->id
);
684 if (node
->GetMetaInfo(*params
->key
, &value
)) {
685 GetMetaInfo::Results::Value result
;
686 result
.as_string
.reset(new std::string(value
));
687 results_
= GetMetaInfo::Results::Create(result
);
690 GetMetaInfo::Results::Value result
;
691 result
.as_object
.reset(new GetMetaInfo::Results::Value::Object
);
693 const BookmarkNode::MetaInfoMap
* meta_info
= node
->GetMetaInfoMap();
695 BookmarkNode::MetaInfoMap::const_iterator itr
;
696 base::DictionaryValue
& temp
= result
.as_object
->additional_properties
;
697 for (itr
= meta_info
->begin(); itr
!= meta_info
->end(); itr
++) {
698 temp
.SetStringWithoutPathExpansion(itr
->first
, itr
->second
);
701 results_
= GetMetaInfo::Results::Create(result
);
705 error_
= bookmark_api_constants::kInvalidParamError
;
709 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
710 const BookmarkNode
* node
= model
->root_node();
712 GetMetaInfo::Results::Value result
;
713 result
.as_object
.reset(new GetMetaInfo::Results::Value::Object
);
715 bookmark_api_helpers::GetMetaInfo(*node
,
716 &result
.as_object
->additional_properties
);
718 results_
= GetMetaInfo::Results::Create(result
);
724 bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() {
725 if (!EditBookmarksEnabled())
728 scoped_ptr
<SetMetaInfo::Params
> params(SetMetaInfo::Params::Create(*args_
));
729 EXTENSION_FUNCTION_VALIDATE(params
);
731 const BookmarkNode
* node
= GetBookmarkNodeFromId(params
->id
);
735 if (!CanBeModified(node
))
738 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
739 if (model
->is_permanent_node(node
)) {
740 error_
= bookmark_keys::kModifySpecialError
;
744 model
->SetNodeMetaInfo(node
, params
->key
, params
->value
);
748 bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() {
749 if (!EditBookmarksEnabled())
752 scoped_ptr
<UpdateMetaInfo::Params
> params(
753 UpdateMetaInfo::Params::Create(*args_
));
754 EXTENSION_FUNCTION_VALIDATE(params
);
756 const BookmarkNode
* node
= GetBookmarkNodeFromId(params
->id
);
760 if (!CanBeModified(node
))
763 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
764 if (model
->is_permanent_node(node
)) {
765 error_
= bookmark_keys::kModifySpecialError
;
769 BookmarkNode::MetaInfoMap
new_meta_info(
770 params
->meta_info_changes
.additional_properties
);
771 if (node
->GetMetaInfoMap()) {
772 new_meta_info
.insert(node
->GetMetaInfoMap()->begin(),
773 node
->GetMetaInfoMap()->end());
775 model
->SetNodeMetaInfoMap(node
, new_meta_info
);
780 bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() {
781 bool can_open_new_windows
= true;
782 SetResult(new base::FundamentalValue(can_open_new_windows
));
786 bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() {
787 if (!EditBookmarksEnabled())
790 scoped_ptr
<RemoveTrees::Params
> params(RemoveTrees::Params::Create(*args_
));
791 EXTENSION_FUNCTION_VALIDATE(params
);
793 BookmarkModel
* model
= GetBookmarkModel();
794 ChromeBookmarkClient
* client
= GetChromeBookmarkClient();
795 bookmarks::ScopedGroupBookmarkActions
group_deletes(model
);
797 for (size_t i
= 0; i
< params
->id_list
.size(); ++i
) {
798 if (!GetBookmarkIdAsInt64(params
->id_list
[i
], &id
))
800 if (!bookmark_api_helpers::RemoveNode(model
, client
, id
, true, &error_
))
807 bool BookmarkManagerPrivateUndoFunction::RunOnReady() {
808 if (!EditBookmarksEnabled())
811 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
816 bool BookmarkManagerPrivateRedoFunction::RunOnReady() {
817 if (!EditBookmarksEnabled())
820 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
825 bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() {
826 UndoManager
* undo_manager
=
827 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
829 UndoInfo::Results::Result result
;
830 result
.enabled
= undo_manager
->undo_count() > 0;
831 result
.label
= base::UTF16ToUTF8(undo_manager
->GetUndoLabel());
833 results_
= UndoInfo::Results::Create(result
);
837 bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() {
838 UndoManager
* undo_manager
=
839 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
841 RedoInfo::Results::Result result
;
842 result
.enabled
= undo_manager
->redo_count() > 0;
843 result
.label
= base::UTF16ToUTF8(undo_manager
->GetRedoLabel());
845 results_
= RedoInfo::Results::Create(result
);
849 bool BookmarkManagerPrivateSetVersionFunction::RunOnReady() {
850 scoped_ptr
<SetVersion::Params
> params
= SetVersion::Params::Create(*args_
);
852 enhanced_bookmarks::EnhancedBookmarkModel
* model
=
853 enhanced_bookmarks::EnhancedBookmarkModelFactory::GetForBrowserContext(
855 model
->SetVersionSuffix(params
->version
);
860 } // namespace extensions