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