bookmark_manager_private_api.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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. 4 5#include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h" 6 7#include <vector> 8 9#include "base/memory/linked_ptr.h" 10#include "base/prefs/pref_service.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/strings/utf_string_conversions.h" 13#include "base/values.h" 14#include "chrome/browser/bookmarks/bookmark_model.h" 15#include "chrome/browser/bookmarks/bookmark_model_factory.h" 16#include "chrome/browser/bookmarks/bookmark_node_data.h" 17#include "chrome/browser/bookmarks/bookmark_stats.h" 18#include "chrome/browser/bookmarks/bookmark_utils.h" 19#include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api_constants.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_function_dispatcher.h" 23#include "chrome/browser/extensions/extension_web_ui.h" 24#include "chrome/browser/profiles/profile.h" 25#include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" 26#include "chrome/browser/undo/bookmark_undo_service.h" 27#include "chrome/browser/undo/bookmark_undo_service_factory.h" 28#include "chrome/browser/undo/bookmark_undo_utils.h" 29#include "chrome/common/extensions/api/bookmark_manager_private.h" 30#include "chrome/common/pref_names.h" 31#include "components/user_prefs/user_prefs.h" 32#include "content/public/browser/render_view_host.h" 33#include "content/public/browser/web_contents.h" 34#include "content/public/browser/web_contents_view.h" 35#include "content/public/browser/web_ui.h" 36#include "extensions/browser/event_router.h" 37#include "extensions/browser/extension_system.h" 38#include "extensions/browser/view_type_utils.h" 39#include "grit/generated_resources.h" 40#include "ui/base/dragdrop/drag_drop_types.h" 41#include "ui/base/l10n/l10n_util.h" 42#include "ui/base/webui/web_ui_util.h" 43 44#if defined(OS_WIN) 45#include "win8/util/win8_util.h" 46#endif // OS_WIN 47 48namespace extensions { 49 50namespace bookmark_keys = bookmark_api_constants; 51namespace bookmark_manager_private = api::bookmark_manager_private; 52namespace CanPaste = api::bookmark_manager_private::CanPaste; 53namespace Copy = api::bookmark_manager_private::Copy; 54namespace Cut = api::bookmark_manager_private::Cut; 55namespace Drop = api::bookmark_manager_private::Drop; 56namespace GetSubtree = api::bookmark_manager_private::GetSubtree; 57namespace manager_keys = bookmark_manager_api_constants; 58namespace GetMetaInfo = api::bookmark_manager_private::GetMetaInfo; 59namespace Paste = api::bookmark_manager_private::Paste; 60namespace RedoInfo = api::bookmark_manager_private::GetRedoInfo; 61namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees; 62namespace SetMetaInfo = api::bookmark_manager_private::SetMetaInfo; 63namespace SortChildren = api::bookmark_manager_private::SortChildren; 64namespace StartDrag = api::bookmark_manager_private::StartDrag; 65namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo; 66 67using content::WebContents; 68 69namespace { 70 71// Returns a single bookmark node from the argument ID. 72// This returns NULL in case of failure. 73const BookmarkNode* GetNodeFromString( 74 BookmarkModel* model, const std::string& id_string) { 75 int64 id; 76 if (!base::StringToInt64(id_string, &id)) 77 return NULL; 78 return model->GetNodeByID(id); 79} 80 81// Gets a vector of bookmark nodes from the argument list of IDs. 82// This returns false in the case of failure. 83bool GetNodesFromVector(BookmarkModel* model, 84 const std::vector<std::string>& id_strings, 85 std::vector<const BookmarkNode*>* nodes) { 86 87 if (id_strings.empty()) 88 return false; 89 90 for (size_t i = 0; i < id_strings.size(); ++i) { 91 const BookmarkNode* node = GetNodeFromString(model, id_strings[i]); 92 if (!node) 93 return false; 94 nodes->push_back(node); 95 } 96 97 return true; 98} 99 100// Recursively adds a node to a list. This is by used |BookmarkNodeDataToJSON| 101// when the data comes from the current profile. In this case we have a 102// BookmarkNode since we got the data from the current profile. 103void AddNodeToList(base::ListValue* list, const BookmarkNode& node) { 104 base::DictionaryValue* dict = new base::DictionaryValue(); 105 106 // Add id and parentId so we can associate the data with existing nodes on the 107 // client side. 108 std::string id_string = base::Int64ToString(node.id()); 109 dict->SetString(bookmark_keys::kIdKey, id_string); 110 111 std::string parent_id_string = base::Int64ToString(node.parent()->id()); 112 dict->SetString(bookmark_keys::kParentIdKey, parent_id_string); 113 114 if (node.is_url()) 115 dict->SetString(bookmark_keys::kUrlKey, node.url().spec()); 116 117 dict->SetString(bookmark_keys::kTitleKey, node.GetTitle()); 118 119 base::ListValue* children = new base::ListValue(); 120 for (int i = 0; i < node.child_count(); ++i) 121 AddNodeToList(children, *node.GetChild(i)); 122 dict->Set(bookmark_keys::kChildrenKey, children); 123 124 list->Append(dict); 125} 126 127// Recursively adds an element to a list. This is used by 128// |BookmarkNodeDataToJSON| when the data comes from a different profile. When 129// the data comes from a different profile we do not have any IDs or parent IDs. 130void AddElementToList(base::ListValue* list, 131 const BookmarkNodeData::Element& element) { 132 base::DictionaryValue* dict = new base::DictionaryValue(); 133 134 if (element.is_url) 135 dict->SetString(bookmark_keys::kUrlKey, element.url.spec()); 136 137 dict->SetString(bookmark_keys::kTitleKey, element.title); 138 139 base::ListValue* children = new base::ListValue(); 140 for (size_t i = 0; i < element.children.size(); ++i) 141 AddElementToList(children, element.children[i]); 142 dict->Set(bookmark_keys::kChildrenKey, children); 143 144 list->Append(dict); 145} 146 147// Builds the JSON structure based on the BookmarksDragData. 148void BookmarkNodeDataToJSON(Profile* profile, const BookmarkNodeData& data, 149 base::ListValue* args) { 150 bool same_profile = data.IsFromProfile(profile); 151 base::DictionaryValue* value = new base::DictionaryValue(); 152 value->SetBoolean(manager_keys::kSameProfileKey, same_profile); 153 154 base::ListValue* list = new base::ListValue(); 155 if (same_profile) { 156 std::vector<const BookmarkNode*> nodes = data.GetNodes(profile); 157 for (size_t i = 0; i < nodes.size(); ++i) 158 AddNodeToList(list, *nodes[i]); 159 } else { 160 // We do not have an 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 AddElementToList(list, elements[i]); 164 } 165 value->Set(manager_keys::kElementsKey, list); 166 167 args->Append(value); 168} 169 170} // namespace 171 172BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter( 173 Profile* profile, 174 content::WebContents* web_contents) 175 : profile_(profile), 176 web_contents_(web_contents) { 177 BookmarkTabHelper* bookmark_tab_helper = 178 BookmarkTabHelper::FromWebContents(web_contents_); 179 bookmark_tab_helper->set_bookmark_drag_delegate(this); 180} 181 182BookmarkManagerPrivateEventRouter::~BookmarkManagerPrivateEventRouter() { 183 BookmarkTabHelper* bookmark_tab_helper = 184 BookmarkTabHelper::FromWebContents(web_contents_); 185 if (bookmark_tab_helper->bookmark_drag_delegate() == this) 186 bookmark_tab_helper->set_bookmark_drag_delegate(NULL); 187} 188 189void BookmarkManagerPrivateEventRouter::DispatchEvent( 190 const std::string& event_name, 191 scoped_ptr<base::ListValue> args) { 192 if (!ExtensionSystem::Get(profile_)->event_router()) 193 return; 194 195 scoped_ptr<Event> event(new Event(event_name, args.Pass())); 196 ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(event.Pass()); 197} 198 199void BookmarkManagerPrivateEventRouter::DispatchDragEvent( 200 const BookmarkNodeData& data, 201 const std::string& event_name) { 202 if (data.size() == 0) 203 return; 204 205 scoped_ptr<base::ListValue> args(new base::ListValue()); 206 BookmarkNodeDataToJSON(profile_, data, args.get()); 207 DispatchEvent(event_name, args.Pass()); 208} 209 210void BookmarkManagerPrivateEventRouter::OnDragEnter( 211 const BookmarkNodeData& data) { 212 DispatchDragEvent(data, bookmark_manager_private::OnDragEnter::kEventName); 213} 214 215void BookmarkManagerPrivateEventRouter::OnDragOver( 216 const BookmarkNodeData& data) { 217 // Intentionally empty since these events happens too often and floods the 218 // message queue. We do not need this event for the bookmark manager anyway. 219} 220 221void BookmarkManagerPrivateEventRouter::OnDragLeave( 222 const BookmarkNodeData& data) { 223 DispatchDragEvent(data, bookmark_manager_private::OnDragLeave::kEventName); 224} 225 226void BookmarkManagerPrivateEventRouter::OnDrop(const BookmarkNodeData& data) { 227 DispatchDragEvent(data, bookmark_manager_private::OnDrop::kEventName); 228 229 // Make a copy that is owned by this instance. 230 ClearBookmarkNodeData(); 231 bookmark_drag_data_ = data; 232} 233 234const BookmarkNodeData* 235BookmarkManagerPrivateEventRouter::GetBookmarkNodeData() { 236 if (bookmark_drag_data_.is_valid()) 237 return &bookmark_drag_data_; 238 return NULL; 239} 240 241void BookmarkManagerPrivateEventRouter::ClearBookmarkNodeData() { 242 bookmark_drag_data_.Clear(); 243} 244 245bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut, 246 const std::vector<std::string>& id_list) { 247 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 248 std::vector<const BookmarkNode*> nodes; 249 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model, id_list, &nodes)); 250 bookmark_utils::CopyToClipboard(model, nodes, cut); 251 return true; 252} 253 254bool BookmarkManagerPrivateCopyFunction::RunImpl() { 255 scoped_ptr<Copy::Params> params(Copy::Params::Create(*args_)); 256 EXTENSION_FUNCTION_VALIDATE(params); 257 return CopyOrCut(false, params->id_list); 258} 259 260bool BookmarkManagerPrivateCutFunction::RunImpl() { 261 if (!EditBookmarksEnabled()) 262 return false; 263 264 scoped_ptr<Cut::Params> params(Cut::Params::Create(*args_)); 265 EXTENSION_FUNCTION_VALIDATE(params); 266 return CopyOrCut(true, params->id_list); 267} 268 269bool BookmarkManagerPrivatePasteFunction::RunImpl() { 270 if (!EditBookmarksEnabled()) 271 return false; 272 273 scoped_ptr<Paste::Params> params(Paste::Params::Create(*args_)); 274 EXTENSION_FUNCTION_VALIDATE(params); 275 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 276 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); 277 if (!parent_node) { 278 error_ = bookmark_keys::kNoParentError; 279 return false; 280 } 281 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); 282 if (!can_paste) 283 return false; 284 285 // We want to use the highest index of the selected nodes as a destination. 286 std::vector<const BookmarkNode*> nodes; 287 // No need to test return value, if we got an empty list, we insert at end. 288 if (params->selected_id_list) 289 GetNodesFromVector(model, *params->selected_id_list, &nodes); 290 int highest_index = -1; // -1 means insert at end of list. 291 for (size_t i = 0; i < nodes.size(); ++i) { 292 // + 1 so that we insert after the selection. 293 int index = parent_node->GetIndexOf(nodes[i]) + 1; 294 if (index > highest_index) 295 highest_index = index; 296 } 297 298 bookmark_utils::PasteFromClipboard(model, parent_node, highest_index); 299 return true; 300} 301 302bool BookmarkManagerPrivateCanPasteFunction::RunImpl() { 303 if (!EditBookmarksEnabled()) 304 return false; 305 306 scoped_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_)); 307 EXTENSION_FUNCTION_VALIDATE(params); 308 309 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 310 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); 311 if (!parent_node) { 312 error_ = bookmark_keys::kNoParentError; 313 return false; 314 } 315 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); 316 SetResult(new base::FundamentalValue(can_paste)); 317 return true; 318} 319 320bool BookmarkManagerPrivateSortChildrenFunction::RunImpl() { 321 if (!EditBookmarksEnabled()) 322 return false; 323 324 scoped_ptr<SortChildren::Params> params(SortChildren::Params::Create(*args_)); 325 EXTENSION_FUNCTION_VALIDATE(params); 326 327 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 328 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); 329 if (!parent_node) { 330 error_ = bookmark_keys::kNoParentError; 331 return false; 332 } 333 model->SortChildren(parent_node); 334 return true; 335} 336 337bool BookmarkManagerPrivateGetStringsFunction::RunImpl() { 338 base::DictionaryValue* localized_strings = new base::DictionaryValue(); 339 340 localized_strings->SetString("title", 341 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE)); 342 localized_strings->SetString("search_button", 343 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON)); 344 localized_strings->SetString("organize_menu", 345 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU)); 346 localized_strings->SetString("show_in_folder", 347 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); 348 localized_strings->SetString("sort", 349 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT)); 350 localized_strings->SetString("import_menu", 351 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU)); 352 localized_strings->SetString("export_menu", 353 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU)); 354 localized_strings->SetString("rename_folder", 355 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER)); 356 localized_strings->SetString("edit", 357 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT)); 358 localized_strings->SetString("should_open_all", 359 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL)); 360 localized_strings->SetString("open_incognito", 361 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO)); 362 localized_strings->SetString("open_in_new_tab", 363 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB)); 364 localized_strings->SetString("open_in_new_window", 365 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW)); 366 localized_strings->SetString("add_new_bookmark", 367 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 368 localized_strings->SetString("new_folder", 369 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER)); 370 localized_strings->SetString("open_all", 371 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL)); 372 localized_strings->SetString("open_all_new_window", 373 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 374 localized_strings->SetString("open_all_incognito", 375 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 376 localized_strings->SetString("remove", 377 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE)); 378 localized_strings->SetString("copy", 379 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY)); 380 localized_strings->SetString("cut", 381 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT)); 382 localized_strings->SetString("paste", 383 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE)); 384 localized_strings->SetString("delete", 385 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE)); 386 localized_strings->SetString("undo_delete", 387 l10n_util::GetStringUTF16(IDS_UNDO_DELETE)); 388 localized_strings->SetString("new_folder_name", 389 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME)); 390 localized_strings->SetString("name_input_placeholder", 391 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER)); 392 localized_strings->SetString("url_input_placeholder", 393 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER)); 394 localized_strings->SetString("invalid_url", 395 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL)); 396 localized_strings->SetString("recent", 397 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT)); 398 localized_strings->SetString("search", 399 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH)); 400 localized_strings->SetString("save", 401 l10n_util::GetStringUTF16(IDS_SAVE)); 402 localized_strings->SetString("cancel", 403 l10n_util::GetStringUTF16(IDS_CANCEL)); 404 405 webui::SetFontAndTextDirection(localized_strings); 406 407 SetResult(localized_strings); 408 409 // This is needed because unlike the rest of these functions, this class 410 // inherits from AsyncFunction directly, rather than BookmarkFunction. 411 SendResponse(true); 412 413 return true; 414} 415 416bool BookmarkManagerPrivateStartDragFunction::RunImpl() { 417 if (!EditBookmarksEnabled()) 418 return false; 419 420 scoped_ptr<StartDrag::Params> params(StartDrag::Params::Create(*args_)); 421 EXTENSION_FUNCTION_VALIDATE(params); 422 423 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 424 std::vector<const BookmarkNode*> nodes; 425 EXTENSION_FUNCTION_VALIDATE( 426 GetNodesFromVector(model, params->id_list, &nodes)); 427 428 WebContents* web_contents = 429 WebContents::FromRenderViewHost(render_view_host_); 430 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) { 431 WebContents* web_contents = 432 dispatcher()->delegate()->GetAssociatedWebContents(); 433 CHECK(web_contents); 434 435 ui::DragDropTypes::DragEventSource source = 436 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE; 437 if (params->is_from_touch) 438 source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH; 439 440 chrome::DragBookmarks( 441 GetProfile(), nodes, web_contents->GetView()->GetNativeView(), source); 442 443 return true; 444 } else { 445 NOTREACHED(); 446 return false; 447 } 448} 449 450bool BookmarkManagerPrivateDropFunction::RunImpl() { 451 if (!EditBookmarksEnabled()) 452 return false; 453 454 scoped_ptr<Drop::Params> params(Drop::Params::Create(*args_)); 455 EXTENSION_FUNCTION_VALIDATE(params); 456 457 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 458 459 const BookmarkNode* drop_parent = GetNodeFromString(model, params->parent_id); 460 if (!drop_parent) { 461 error_ = bookmark_keys::kNoParentError; 462 return false; 463 } 464 465 int drop_index; 466 if (params->index) 467 drop_index = *params->index; 468 else 469 drop_index = drop_parent->child_count(); 470 471 WebContents* web_contents = 472 WebContents::FromRenderViewHost(render_view_host_); 473 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) { 474 WebContents* web_contents = 475 dispatcher()->delegate()->GetAssociatedWebContents(); 476 CHECK(web_contents); 477 ExtensionWebUI* web_ui = 478 static_cast<ExtensionWebUI*>(web_contents->GetWebUI()->GetController()); 479 CHECK(web_ui); 480 BookmarkManagerPrivateEventRouter* router = 481 web_ui->bookmark_manager_private_event_router(); 482 483 DCHECK(router); 484 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData(); 485 if (drag_data == NULL) { 486 NOTREACHED() <<"Somehow we're dropping null bookmark data"; 487 return false; 488 } 489 chrome::DropBookmarks(GetProfile(), *drag_data, drop_parent, drop_index); 490 491 router->ClearBookmarkNodeData(); 492 return true; 493 } else { 494 NOTREACHED(); 495 return false; 496 } 497} 498 499bool BookmarkManagerPrivateGetSubtreeFunction::RunImpl() { 500 scoped_ptr<GetSubtree::Params> params(GetSubtree::Params::Create(*args_)); 501 EXTENSION_FUNCTION_VALIDATE(params); 502 503 const BookmarkNode* node = NULL; 504 505 if (params->id == "") { 506 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 507 node = model->root_node(); 508 } else { 509 node = GetBookmarkNodeFromId(params->id); 510 if (!node) 511 return false; 512 } 513 514 std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> > nodes; 515 if (params->folders_only) 516 bookmark_api_helpers::AddNodeFoldersOnly(node, &nodes, true); 517 else 518 bookmark_api_helpers::AddNode(node, &nodes, true); 519 results_ = GetSubtree::Results::Create(nodes); 520 return true; 521} 522 523bool BookmarkManagerPrivateCanEditFunction::RunImpl() { 524 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); 525 SetResult(new base::FundamentalValue( 526 prefs->GetBoolean(prefs::kEditBookmarksEnabled))); 527 return true; 528} 529 530bool BookmarkManagerPrivateRecordLaunchFunction::RunImpl() { 531 RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER); 532 return true; 533} 534 535bool BookmarkManagerPrivateGetMetaInfoFunction::RunImpl() { 536 scoped_ptr<GetMetaInfo::Params> params(GetMetaInfo::Params::Create(*args_)); 537 EXTENSION_FUNCTION_VALIDATE(params); 538 539 const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 540 if (!node) 541 return false; 542 543 std::string value; 544 if (node->GetMetaInfo(params->key, &value)) 545 results_ = GetMetaInfo::Results::Create(value); 546 return true; 547} 548 549bool BookmarkManagerPrivateSetMetaInfoFunction::RunImpl() { 550 scoped_ptr<SetMetaInfo::Params> params(SetMetaInfo::Params::Create(*args_)); 551 EXTENSION_FUNCTION_VALIDATE(params); 552 553 const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 554 if (!node) 555 return false; 556 557 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 558 model->SetNodeMetaInfo(node, params->key, params->value); 559 return true; 560} 561 562bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunImpl() { 563 bool can_open_new_windows = true; 564 565#if defined(OS_WIN) 566 if (win8::IsSingleWindowMetroMode()) 567 can_open_new_windows = false; 568#endif // OS_WIN 569 570 SetResult(new base::FundamentalValue(can_open_new_windows)); 571 return true; 572} 573 574bool BookmarkManagerPrivateRemoveTreesFunction::RunImpl() { 575 scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_)); 576 EXTENSION_FUNCTION_VALIDATE(params); 577 578#if !defined(OS_ANDROID) 579 ScopedGroupBookmarkActions group_deletes(GetProfile()); 580#endif 581 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 582 int64 id; 583 for (size_t i = 0; i < params->id_list.size(); ++i) { 584 if (!GetBookmarkIdAsInt64(params->id_list[i], &id)) 585 return false; 586 if (!bookmark_api_helpers::RemoveNode(model, id, true, &error_)) 587 return false; 588 } 589 590 return true; 591} 592 593bool BookmarkManagerPrivateUndoFunction::RunImpl() { 594#if !defined(OS_ANDROID) 595 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()-> 596 Undo(); 597#endif 598 599 return true; 600} 601 602bool BookmarkManagerPrivateRedoFunction::RunImpl() { 603#if !defined(OS_ANDROID) 604 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()-> 605 Redo(); 606#endif 607 608 return true; 609} 610 611bool BookmarkManagerPrivateGetUndoInfoFunction::RunImpl() { 612#if !defined(OS_ANDROID) 613 UndoManager* undo_manager = 614 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager(); 615 616 UndoInfo::Results::Result result; 617 result.enabled = undo_manager->undo_count() > 0; 618 result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel()); 619 620 results_ = UndoInfo::Results::Create(result); 621#endif // !defined(OS_ANDROID) 622 623 return true; 624} 625 626bool BookmarkManagerPrivateGetRedoInfoFunction::RunImpl() { 627#if !defined(OS_ANDROID) 628 UndoManager* undo_manager = 629 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager(); 630 631 RedoInfo::Results::Result result; 632 result.enabled = undo_manager->redo_count() > 0; 633 result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel()); 634 635 results_ = RedoInfo::Results::Create(result); 636#endif // !defined(OS_ANDROID) 637 638 return true; 639} 640 641} // namespace extensions 642