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/browser_process.h"
18 #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
19 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
20 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
21 #include "chrome/browser/extensions/extension_web_ui.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
24 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
25 #include "chrome/common/extensions/api/bookmark_manager_private.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/grit/generated_resources.h"
28 #include "components/bookmarks/browser/bookmark_model.h"
29 #include "components/bookmarks/browser/bookmark_node_data.h"
30 #include "components/bookmarks/browser/bookmark_utils.h"
31 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
32 #include "components/bookmarks/managed/managed_bookmark_service.h"
33 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
34 #include "components/undo/bookmark_undo_service.h"
35 #include "components/user_prefs/user_prefs.h"
36 #include "content/public/browser/render_view_host.h"
37 #include "content/public/browser/web_contents.h"
38 #include "content/public/browser/web_ui.h"
39 #include "extensions/browser/extension_function_dispatcher.h"
40 #include "extensions/browser/view_type_utils.h"
41 #include "ui/base/dragdrop/drag_drop_types.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/base/webui/web_ui_util.h"
45 using bookmarks::BookmarkModel
;
46 using bookmarks::BookmarkNode
;
47 using bookmarks::BookmarkNodeData
;
48 using content::WebContents
;
50 namespace extensions
{
52 namespace bookmark_keys
= bookmark_api_constants
;
53 namespace bookmark_manager_private
= api::bookmark_manager_private
;
54 namespace CanPaste
= api::bookmark_manager_private::CanPaste
;
55 namespace Copy
= api::bookmark_manager_private::Copy
;
56 namespace CreateWithMetaInfo
=
57 api::bookmark_manager_private::CreateWithMetaInfo
;
58 namespace Cut
= api::bookmark_manager_private::Cut
;
59 namespace Drop
= api::bookmark_manager_private::Drop
;
60 namespace GetSubtree
= api::bookmark_manager_private::GetSubtree
;
61 namespace GetMetaInfo
= api::bookmark_manager_private::GetMetaInfo
;
62 namespace Paste
= api::bookmark_manager_private::Paste
;
63 namespace RedoInfo
= api::bookmark_manager_private::GetRedoInfo
;
64 namespace RemoveTrees
= api::bookmark_manager_private::RemoveTrees
;
65 namespace SetMetaInfo
= api::bookmark_manager_private::SetMetaInfo
;
66 namespace SetVersion
= api::bookmark_manager_private::SetVersion
;
67 namespace SortChildren
= api::bookmark_manager_private::SortChildren
;
68 namespace StartDrag
= api::bookmark_manager_private::StartDrag
;
69 namespace UndoInfo
= api::bookmark_manager_private::GetUndoInfo
;
70 namespace UpdateMetaInfo
= api::bookmark_manager_private::UpdateMetaInfo
;
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 events::HistogramValue histogram_value
,
188 const std::string
& event_name
,
189 scoped_ptr
<base::ListValue
> event_args
) {
190 EventRouter::Get(browser_context_
)
191 ->BroadcastEvent(make_scoped_ptr(
192 new Event(histogram_value
, event_name
, event_args
.Pass())));
195 void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {}
197 void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted(
198 BookmarkModel
* model
) {
199 bookmark_model_
= NULL
;
202 void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo(
203 BookmarkModel
* model
,
204 const BookmarkNode
* node
) {
205 DCHECK(prev_meta_info_
.empty());
206 if (node
->GetMetaInfoMap())
207 prev_meta_info_
= *node
->GetMetaInfoMap();
210 void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged(
211 BookmarkModel
* model
,
212 const BookmarkNode
* node
) {
213 const BookmarkNode::MetaInfoMap
* new_meta_info
= node
->GetMetaInfoMap();
214 bookmark_manager_private::MetaInfoFields changes
;
216 // Identify changed/removed fields:
217 for (BookmarkNode::MetaInfoMap::const_iterator it
= prev_meta_info_
.begin();
218 it
!= prev_meta_info_
.end();
220 if (!new_meta_info
) {
221 changes
.additional_properties
[it
->first
] = "";
223 BookmarkNode::MetaInfoMap::const_iterator new_meta_field
=
224 new_meta_info
->find(it
->first
);
225 if (new_meta_field
== new_meta_info
->end()) {
226 changes
.additional_properties
[it
->first
] = "";
227 } else if (it
->second
!= new_meta_field
->second
) {
228 changes
.additional_properties
[it
->first
] = new_meta_field
->second
;
233 // Identify added fields:
235 for (BookmarkNode::MetaInfoMap::const_iterator it
= new_meta_info
->begin();
236 it
!= new_meta_info
->end();
238 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field
=
239 prev_meta_info_
.find(it
->first
);
240 if (prev_meta_field
== prev_meta_info_
.end())
241 changes
.additional_properties
[it
->first
] = it
->second
;
245 prev_meta_info_
.clear();
246 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_META_INFO_CHANGED
,
247 bookmark_manager_private::OnMetaInfoChanged::kEventName
,
248 bookmark_manager_private::OnMetaInfoChanged::Create(
249 base::Int64ToString(node
->id()), changes
));
252 BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI(
253 content::BrowserContext
* browser_context
)
254 : browser_context_(browser_context
) {
255 EventRouter
* event_router
= EventRouter::Get(browser_context
);
256 event_router
->RegisterObserver(
257 this, bookmark_manager_private::OnMetaInfoChanged::kEventName
);
260 BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {}
262 void BookmarkManagerPrivateAPI::Shutdown() {
263 EventRouter::Get(browser_context_
)->UnregisterObserver(this);
266 static base::LazyInstance
<
267 BrowserContextKeyedAPIFactory
<BookmarkManagerPrivateAPI
> > g_factory
=
268 LAZY_INSTANCE_INITIALIZER
;
271 BrowserContextKeyedAPIFactory
<BookmarkManagerPrivateAPI
>*
272 BookmarkManagerPrivateAPI::GetFactoryInstance() {
273 return g_factory
.Pointer();
276 void BookmarkManagerPrivateAPI::OnListenerAdded(
277 const EventListenerInfo
& details
) {
278 EventRouter::Get(browser_context_
)->UnregisterObserver(this);
279 event_router_
.reset(new BookmarkManagerPrivateEventRouter(
281 BookmarkModelFactory::GetForProfile(
282 Profile::FromBrowserContext(browser_context_
))));
285 BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter(
287 content::WebContents
* web_contents
)
288 : profile_(profile
), web_contents_(web_contents
) {
289 BookmarkTabHelper
* bookmark_tab_helper
=
290 BookmarkTabHelper::FromWebContents(web_contents_
);
291 bookmark_tab_helper
->set_bookmark_drag_delegate(this);
294 BookmarkManagerPrivateDragEventRouter::
295 ~BookmarkManagerPrivateDragEventRouter() {
296 BookmarkTabHelper
* bookmark_tab_helper
=
297 BookmarkTabHelper::FromWebContents(web_contents_
);
298 if (bookmark_tab_helper
->bookmark_drag_delegate() == this)
299 bookmark_tab_helper
->set_bookmark_drag_delegate(NULL
);
302 void BookmarkManagerPrivateDragEventRouter::DispatchEvent(
303 events::HistogramValue histogram_value
,
304 const std::string
& event_name
,
305 scoped_ptr
<base::ListValue
> args
) {
306 EventRouter
* event_router
= EventRouter::Get(profile_
);
310 scoped_ptr
<Event
> event(new Event(histogram_value
, event_name
, args
.Pass()));
311 event_router
->BroadcastEvent(event
.Pass());
314 void BookmarkManagerPrivateDragEventRouter::OnDragEnter(
315 const BookmarkNodeData
& data
) {
316 if (!data
.is_valid())
318 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_DRAG_ENTER
,
319 bookmark_manager_private::OnDragEnter::kEventName
,
320 bookmark_manager_private::OnDragEnter::Create(
321 *CreateApiBookmarkNodeData(profile_
, data
)));
324 void BookmarkManagerPrivateDragEventRouter::OnDragOver(
325 const BookmarkNodeData
& data
) {
326 // Intentionally empty since these events happens too often and floods the
327 // message queue. We do not need this event for the bookmark manager anyway.
330 void BookmarkManagerPrivateDragEventRouter::OnDragLeave(
331 const BookmarkNodeData
& data
) {
332 if (!data
.is_valid())
334 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_DRAG_LEAVE
,
335 bookmark_manager_private::OnDragLeave::kEventName
,
336 bookmark_manager_private::OnDragLeave::Create(
337 *CreateApiBookmarkNodeData(profile_
, data
)));
340 void BookmarkManagerPrivateDragEventRouter::OnDrop(
341 const BookmarkNodeData
& data
) {
342 if (!data
.is_valid())
344 DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_DROP
,
345 bookmark_manager_private::OnDrop::kEventName
,
346 bookmark_manager_private::OnDrop::Create(
347 *CreateApiBookmarkNodeData(profile_
, data
)));
349 // Make a copy that is owned by this instance.
350 ClearBookmarkNodeData();
351 bookmark_drag_data_
= data
;
354 const BookmarkNodeData
*
355 BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() {
356 if (bookmark_drag_data_
.is_valid())
357 return &bookmark_drag_data_
;
361 void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() {
362 bookmark_drag_data_
.Clear();
365 bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut
,
366 const std::vector
<std::string
>& id_list
) {
367 BookmarkModel
* model
= GetBookmarkModel();
368 bookmarks::ManagedBookmarkService
* managed
= GetManagedBookmarkService();
369 std::vector
<const BookmarkNode
*> nodes
;
370 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model
, id_list
, &nodes
));
371 if (cut
&& bookmarks::HasDescendantsOf(nodes
, managed
->managed_node())) {
372 error_
= bookmark_keys::kModifyManagedError
;
375 bookmarks::CopyToClipboard(model
, nodes
, cut
);
379 bool BookmarkManagerPrivateCopyFunction::RunOnReady() {
380 scoped_ptr
<Copy::Params
> params(Copy::Params::Create(*args_
));
381 EXTENSION_FUNCTION_VALIDATE(params
);
382 return CopyOrCut(false, params
->id_list
);
385 bool BookmarkManagerPrivateCutFunction::RunOnReady() {
386 if (!EditBookmarksEnabled())
389 scoped_ptr
<Cut::Params
> params(Cut::Params::Create(*args_
));
390 EXTENSION_FUNCTION_VALIDATE(params
);
391 return CopyOrCut(true, params
->id_list
);
394 bool BookmarkManagerPrivatePasteFunction::RunOnReady() {
395 if (!EditBookmarksEnabled())
398 scoped_ptr
<Paste::Params
> params(Paste::Params::Create(*args_
));
399 EXTENSION_FUNCTION_VALIDATE(params
);
400 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
401 const BookmarkNode
* parent_node
= GetNodeFromString(model
, params
->parent_id
);
402 if (!CanBeModified(parent_node
))
404 bool can_paste
= bookmarks::CanPasteFromClipboard(model
, parent_node
);
408 // We want to use the highest index of the selected nodes as a destination.
409 std::vector
<const BookmarkNode
*> nodes
;
410 // No need to test return value, if we got an empty list, we insert at end.
411 if (params
->selected_id_list
)
412 GetNodesFromVector(model
, *params
->selected_id_list
, &nodes
);
413 int highest_index
= -1; // -1 means insert at end of list.
414 for (size_t i
= 0; i
< nodes
.size(); ++i
) {
415 // + 1 so that we insert after the selection.
416 int index
= parent_node
->GetIndexOf(nodes
[i
]) + 1;
417 if (index
> highest_index
)
418 highest_index
= index
;
421 bookmarks::PasteFromClipboard(model
, parent_node
, highest_index
);
425 bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() {
426 scoped_ptr
<CanPaste::Params
> params(CanPaste::Params::Create(*args_
));
427 EXTENSION_FUNCTION_VALIDATE(params
);
429 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetProfile());
430 if (!prefs
->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled
)) {
431 SetResult(new base::FundamentalValue(false));
435 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
436 const BookmarkNode
* parent_node
= GetNodeFromString(model
, params
->parent_id
);
438 error_
= bookmark_keys::kNoParentError
;
441 bool can_paste
= bookmarks::CanPasteFromClipboard(model
, parent_node
);
442 SetResult(new base::FundamentalValue(can_paste
));
446 bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() {
447 if (!EditBookmarksEnabled())
450 scoped_ptr
<SortChildren::Params
> params(SortChildren::Params::Create(*args_
));
451 EXTENSION_FUNCTION_VALIDATE(params
);
453 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
454 const BookmarkNode
* parent_node
= GetNodeFromString(model
, params
->parent_id
);
455 if (!CanBeModified(parent_node
))
457 model
->SortChildren(parent_node
);
461 bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
462 base::DictionaryValue
* localized_strings
= new base::DictionaryValue();
464 localized_strings
->SetString("title",
465 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE
));
466 localized_strings
->SetString("search_button",
467 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON
));
468 localized_strings
->SetString("folders_menu",
469 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_FOLDERS_MENU
));
470 localized_strings
->SetString("organize_menu",
471 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU
));
472 localized_strings
->SetString("show_in_folder",
473 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER
));
474 localized_strings
->SetString("sort",
475 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT
));
476 localized_strings
->SetString("import_menu",
477 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU
));
478 localized_strings
->SetString("export_menu",
479 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU
));
480 localized_strings
->SetString("rename_folder",
481 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER
));
482 localized_strings
->SetString("edit",
483 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT
));
484 localized_strings
->SetString("should_open_all",
485 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL
));
486 localized_strings
->SetString("open_incognito",
487 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO
));
488 localized_strings
->SetString("open_in_new_tab",
489 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB
));
490 localized_strings
->SetString("open_in_new_window",
491 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW
));
492 localized_strings
->SetString("add_new_bookmark",
493 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK
));
494 localized_strings
->SetString("new_folder",
495 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER
));
496 localized_strings
->SetString("open_all",
497 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL
));
498 localized_strings
->SetString("open_all_new_window",
499 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW
));
500 localized_strings
->SetString("open_all_incognito",
501 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO
));
502 localized_strings
->SetString("remove",
503 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE
));
504 localized_strings
->SetString("copy",
505 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY
));
506 localized_strings
->SetString("cut",
507 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT
));
508 localized_strings
->SetString("paste",
509 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE
));
510 localized_strings
->SetString("delete",
511 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE
));
512 localized_strings
->SetString("undo_delete",
513 l10n_util::GetStringUTF16(IDS_UNDO_DELETE
));
514 localized_strings
->SetString("new_folder_name",
515 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME
));
516 localized_strings
->SetString("name_input_placeholder",
517 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER
));
518 localized_strings
->SetString("url_input_placeholder",
519 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER
));
520 localized_strings
->SetString("invalid_url",
521 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL
));
522 localized_strings
->SetString("recent",
523 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT
));
524 localized_strings
->SetString("search",
525 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH
));
526 localized_strings
->SetString("save",
527 l10n_util::GetStringUTF16(IDS_SAVE
));
528 localized_strings
->SetString("cancel",
529 l10n_util::GetStringUTF16(IDS_CANCEL
));
531 const std::string
& app_locale
= g_browser_process
->GetApplicationLocale();
532 webui::SetLoadTimeDataDefaults(app_locale
, localized_strings
);
534 SetResult(localized_strings
);
536 // This is needed because unlike the rest of these functions, this class
537 // inherits from AsyncFunction directly, rather than BookmarkFunction.
543 bool BookmarkManagerPrivateStartDragFunction::RunOnReady() {
544 if (!EditBookmarksEnabled())
547 if (GetViewType(GetSenderWebContents()) != VIEW_TYPE_TAB_CONTENTS
) {
552 scoped_ptr
<StartDrag::Params
> params(StartDrag::Params::Create(*args_
));
553 EXTENSION_FUNCTION_VALIDATE(params
);
555 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
556 std::vector
<const BookmarkNode
*> nodes
;
557 EXTENSION_FUNCTION_VALIDATE(
558 GetNodesFromVector(model
, params
->id_list
, &nodes
));
560 content::WebContents
* web_contents
= GetAssociatedWebContents();
563 ui::DragDropTypes::DragEventSource source
=
564 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE
;
565 if (params
->is_from_touch
)
566 source
= ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH
;
568 chrome::DragBookmarks(
569 GetProfile(), nodes
, web_contents
->GetNativeView(), source
);
574 bool BookmarkManagerPrivateDropFunction::RunOnReady() {
575 if (!EditBookmarksEnabled())
578 scoped_ptr
<Drop::Params
> params(Drop::Params::Create(*args_
));
579 EXTENSION_FUNCTION_VALIDATE(params
);
581 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
583 const BookmarkNode
* drop_parent
= GetNodeFromString(model
, params
->parent_id
);
584 if (!CanBeModified(drop_parent
))
587 if (GetViewType(GetSenderWebContents()) != VIEW_TYPE_TAB_CONTENTS
) {
594 drop_index
= *params
->index
;
596 drop_index
= drop_parent
->child_count();
598 WebContents
* web_contents
= GetAssociatedWebContents();
600 ExtensionWebUI
* web_ui
=
601 static_cast<ExtensionWebUI
*>(web_contents
->GetWebUI()->GetController());
603 BookmarkManagerPrivateDragEventRouter
* router
=
604 web_ui
->bookmark_manager_private_drag_event_router();
607 const BookmarkNodeData
* drag_data
= router
->GetBookmarkNodeData();
608 if (drag_data
== NULL
) {
609 NOTREACHED() <<"Somehow we're dropping null bookmark data";
612 const bool copy
= false;
613 chrome::DropBookmarks(
614 GetProfile(), *drag_data
, drop_parent
, drop_index
, copy
);
616 router
->ClearBookmarkNodeData();
620 bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() {
621 scoped_ptr
<GetSubtree::Params
> params(GetSubtree::Params::Create(*args_
));
622 EXTENSION_FUNCTION_VALIDATE(params
);
624 const BookmarkNode
* node
= NULL
;
626 if (params
->id
.empty()) {
627 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
628 node
= model
->root_node();
630 node
= GetBookmarkNodeFromId(params
->id
);
635 std::vector
<linked_ptr
<api::bookmarks::BookmarkTreeNode
> > nodes
;
636 bookmarks::ManagedBookmarkService
* managed
= GetManagedBookmarkService();
637 if (params
->folders_only
)
638 bookmark_api_helpers::AddNodeFoldersOnly(managed
, node
, &nodes
, true);
640 bookmark_api_helpers::AddNode(managed
, node
, &nodes
, true);
641 results_
= GetSubtree::Results::Create(nodes
);
645 bool BookmarkManagerPrivateCanEditFunction::RunOnReady() {
646 PrefService
* prefs
= user_prefs::UserPrefs::Get(GetProfile());
647 SetResult(new base::FundamentalValue(
648 prefs
->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled
)));
652 bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() {
653 RecordBookmarkLaunch(NULL
, BOOKMARK_LAUNCH_LOCATION_MANAGER
);
657 bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() {
658 if (!EditBookmarksEnabled())
661 scoped_ptr
<CreateWithMetaInfo::Params
> params(
662 CreateWithMetaInfo::Params::Create(*args_
));
663 EXTENSION_FUNCTION_VALIDATE(params
);
665 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
666 const BookmarkNode
* node
= CreateBookmarkNode(
667 model
, params
->bookmark
, ¶ms
->meta_info
.additional_properties
);
671 scoped_ptr
<api::bookmarks::BookmarkTreeNode
> result_node(
672 bookmark_api_helpers::GetBookmarkTreeNode(GetManagedBookmarkService(),
673 node
, false, false));
674 results_
= CreateWithMetaInfo::Results::Create(*result_node
);
679 bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() {
680 scoped_ptr
<GetMetaInfo::Params
> params(GetMetaInfo::Params::Create(*args_
));
681 EXTENSION_FUNCTION_VALIDATE(params
);
684 const BookmarkNode
* node
= GetBookmarkNodeFromId(*params
->id
);
690 if (node
->GetMetaInfo(*params
->key
, &value
)) {
691 GetMetaInfo::Results::Value result
;
692 result
.as_string
.reset(new std::string(value
));
693 results_
= GetMetaInfo::Results::Create(result
);
696 GetMetaInfo::Results::Value result
;
697 result
.as_object
.reset(new GetMetaInfo::Results::Value::Object
);
699 const BookmarkNode::MetaInfoMap
* meta_info
= node
->GetMetaInfoMap();
701 BookmarkNode::MetaInfoMap::const_iterator itr
;
702 base::DictionaryValue
& temp
= result
.as_object
->additional_properties
;
703 for (itr
= meta_info
->begin(); itr
!= meta_info
->end(); itr
++) {
704 temp
.SetStringWithoutPathExpansion(itr
->first
, itr
->second
);
707 results_
= GetMetaInfo::Results::Create(result
);
711 error_
= bookmark_api_constants::kInvalidParamError
;
715 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
716 const BookmarkNode
* node
= model
->root_node();
718 GetMetaInfo::Results::Value result
;
719 result
.as_object
.reset(new GetMetaInfo::Results::Value::Object
);
721 bookmark_api_helpers::GetMetaInfo(*node
,
722 &result
.as_object
->additional_properties
);
724 results_
= GetMetaInfo::Results::Create(result
);
730 bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() {
731 if (!EditBookmarksEnabled())
734 scoped_ptr
<SetMetaInfo::Params
> params(SetMetaInfo::Params::Create(*args_
));
735 EXTENSION_FUNCTION_VALIDATE(params
);
737 const BookmarkNode
* node
= GetBookmarkNodeFromId(params
->id
);
741 if (!CanBeModified(node
))
744 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
745 if (model
->is_permanent_node(node
)) {
746 error_
= bookmark_keys::kModifySpecialError
;
750 model
->SetNodeMetaInfo(node
, params
->key
, params
->value
);
754 bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() {
755 if (!EditBookmarksEnabled())
758 scoped_ptr
<UpdateMetaInfo::Params
> params(
759 UpdateMetaInfo::Params::Create(*args_
));
760 EXTENSION_FUNCTION_VALIDATE(params
);
762 const BookmarkNode
* node
= GetBookmarkNodeFromId(params
->id
);
766 if (!CanBeModified(node
))
769 BookmarkModel
* model
= BookmarkModelFactory::GetForProfile(GetProfile());
770 if (model
->is_permanent_node(node
)) {
771 error_
= bookmark_keys::kModifySpecialError
;
775 BookmarkNode::MetaInfoMap
new_meta_info(
776 params
->meta_info_changes
.additional_properties
);
777 if (node
->GetMetaInfoMap()) {
778 new_meta_info
.insert(node
->GetMetaInfoMap()->begin(),
779 node
->GetMetaInfoMap()->end());
781 model
->SetNodeMetaInfoMap(node
, new_meta_info
);
786 bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() {
787 bool can_open_new_windows
= true;
788 SetResult(new base::FundamentalValue(can_open_new_windows
));
792 bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() {
793 if (!EditBookmarksEnabled())
796 scoped_ptr
<RemoveTrees::Params
> params(RemoveTrees::Params::Create(*args_
));
797 EXTENSION_FUNCTION_VALIDATE(params
);
799 BookmarkModel
* model
= GetBookmarkModel();
800 bookmarks::ManagedBookmarkService
* managed
= GetManagedBookmarkService();
801 bookmarks::ScopedGroupBookmarkActions
group_deletes(model
);
803 for (size_t i
= 0; i
< params
->id_list
.size(); ++i
) {
804 if (!GetBookmarkIdAsInt64(params
->id_list
[i
], &id
))
806 if (!bookmark_api_helpers::RemoveNode(model
, managed
, id
, true, &error_
))
813 bool BookmarkManagerPrivateUndoFunction::RunOnReady() {
814 if (!EditBookmarksEnabled())
817 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
822 bool BookmarkManagerPrivateRedoFunction::RunOnReady() {
823 if (!EditBookmarksEnabled())
826 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()->
831 bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() {
832 UndoManager
* undo_manager
=
833 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
835 UndoInfo::Results::Result result
;
836 result
.enabled
= undo_manager
->undo_count() > 0;
837 result
.label
= base::UTF16ToUTF8(undo_manager
->GetUndoLabel());
839 results_
= UndoInfo::Results::Create(result
);
843 bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() {
844 UndoManager
* undo_manager
=
845 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager();
847 RedoInfo::Results::Result result
;
848 result
.enabled
= undo_manager
->redo_count() > 0;
849 result
.label
= base::UTF16ToUTF8(undo_manager
->GetRedoLabel());
851 results_
= RedoInfo::Results::Create(result
);
855 bool BookmarkManagerPrivateSetVersionFunction::RunOnReady() {
856 scoped_ptr
<SetVersion::Params
> params
= SetVersion::Params::Create(*args_
);
858 enhanced_bookmarks::EnhancedBookmarkModel
* model
=
859 enhanced_bookmarks::EnhancedBookmarkModelFactory::GetForBrowserContext(
861 model
->SetVersionSuffix(params
->version
);
866 } // namespace extensions