bookmark_manager_private_api.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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/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/extensions/api/bookmarks/bookmark_api_constants.h" 18#include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h" 19#include "chrome/browser/extensions/extension_web_ui.h" 20#include "chrome/browser/profiles/profile.h" 21#include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" 22#include "chrome/browser/undo/bookmark_undo_service.h" 23#include "chrome/browser/undo/bookmark_undo_service_factory.h" 24#include "chrome/common/extensions/api/bookmark_manager_private.h" 25#include "chrome/common/pref_names.h" 26#include "components/bookmarks/browser/bookmark_model.h" 27#include "components/bookmarks/browser/bookmark_node_data.h" 28#include "components/bookmarks/browser/bookmark_utils.h" 29#include "components/bookmarks/browser/scoped_group_bookmark_actions.h" 30#include "components/user_prefs/user_prefs.h" 31#include "content/public/browser/render_view_host.h" 32#include "content/public/browser/web_contents.h" 33#include "content/public/browser/web_ui.h" 34#include "extensions/browser/extension_function_dispatcher.h" 35#include "extensions/browser/view_type_utils.h" 36#include "grit/generated_resources.h" 37#include "ui/base/dragdrop/drag_drop_types.h" 38#include "ui/base/l10n/l10n_util.h" 39#include "ui/base/webui/web_ui_util.h" 40 41namespace extensions { 42 43namespace bookmark_keys = bookmark_api_constants; 44namespace bookmark_manager_private = api::bookmark_manager_private; 45namespace CanPaste = api::bookmark_manager_private::CanPaste; 46namespace Copy = api::bookmark_manager_private::Copy; 47namespace CreateWithMetaInfo = 48 api::bookmark_manager_private::CreateWithMetaInfo; 49namespace Cut = api::bookmark_manager_private::Cut; 50namespace Drop = api::bookmark_manager_private::Drop; 51namespace GetSubtree = api::bookmark_manager_private::GetSubtree; 52namespace GetMetaInfo = api::bookmark_manager_private::GetMetaInfo; 53namespace Paste = api::bookmark_manager_private::Paste; 54namespace RedoInfo = api::bookmark_manager_private::GetRedoInfo; 55namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees; 56namespace SetMetaInfo = api::bookmark_manager_private::SetMetaInfo; 57namespace SortChildren = api::bookmark_manager_private::SortChildren; 58namespace StartDrag = api::bookmark_manager_private::StartDrag; 59namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo; 60namespace UpdateMetaInfo = api::bookmark_manager_private::UpdateMetaInfo; 61 62using content::WebContents; 63 64namespace { 65 66// Returns a single bookmark node from the argument ID. 67// This returns NULL in case of failure. 68const BookmarkNode* GetNodeFromString(BookmarkModel* model, 69 const std::string& id_string) { 70 int64 id; 71 if (!base::StringToInt64(id_string, &id)) 72 return NULL; 73 return GetBookmarkNodeByID(model, id); 74} 75 76// Gets a vector of bookmark nodes from the argument list of IDs. 77// This returns false in the case of failure. 78bool GetNodesFromVector(BookmarkModel* model, 79 const std::vector<std::string>& id_strings, 80 std::vector<const BookmarkNode*>* nodes) { 81 82 if (id_strings.empty()) 83 return false; 84 85 for (size_t i = 0; i < id_strings.size(); ++i) { 86 const BookmarkNode* node = GetNodeFromString(model, id_strings[i]); 87 if (!node) 88 return false; 89 nodes->push_back(node); 90 } 91 92 return true; 93} 94 95// Recursively create a bookmark_manager_private::BookmarkNodeDataElement from 96// a bookmark node. This is by used |BookmarkNodeDataToJSON| when the data comes 97// from the current profile. In this case we have a BookmarkNode since we got 98// the data from the current profile. 99linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> 100CreateNodeDataElementFromBookmarkNode(const BookmarkNode& node) { 101 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> element( 102 new bookmark_manager_private::BookmarkNodeDataElement); 103 // Add id and parentId so we can associate the data with existing nodes on the 104 // client side. 105 element->id.reset(new std::string(base::Int64ToString(node.id()))); 106 element->parent_id.reset( 107 new std::string(base::Int64ToString(node.parent()->id()))); 108 109 if (node.is_url()) 110 element->url.reset(new std::string(node.url().spec())); 111 112 element->title = base::UTF16ToUTF8(node.GetTitle()); 113 for (int i = 0; i < node.child_count(); ++i) { 114 element->children.push_back( 115 CreateNodeDataElementFromBookmarkNode(*node.GetChild(i))); 116 } 117 118 return element; 119} 120 121// Recursively create a bookmark_manager_private::BookmarkNodeDataElement from 122// a BookmarkNodeData::Element. This is used by |BookmarkNodeDataToJSON| when 123// the data comes from a different profile. When the data comes from a different 124// profile we do not have any IDs or parent IDs. 125linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> 126CreateApiNodeDataElement(const BookmarkNodeData::Element& element) { 127 linked_ptr<bookmark_manager_private::BookmarkNodeDataElement> node_element( 128 new bookmark_manager_private::BookmarkNodeDataElement); 129 130 if (element.is_url) 131 node_element->url.reset(new std::string(element.url.spec())); 132 node_element->title = base::UTF16ToUTF8(element.title); 133 for (size_t i = 0; i < element.children.size(); ++i) { 134 node_element->children.push_back( 135 CreateApiNodeDataElement(element.children[i])); 136 } 137 138 return node_element; 139} 140 141// Creates a bookmark_manager_private::BookmarkNodeData from a BookmarkNodeData. 142scoped_ptr<bookmark_manager_private::BookmarkNodeData> 143CreateApiBookmarkNodeData(Profile* profile, const BookmarkNodeData& data) { 144 const base::FilePath& profile_path = profile->GetPath(); 145 146 scoped_ptr<bookmark_manager_private::BookmarkNodeData> node_data( 147 new bookmark_manager_private::BookmarkNodeData); 148 node_data->same_profile = data.IsFromProfilePath(profile_path); 149 150 if (node_data->same_profile) { 151 std::vector<const BookmarkNode*> nodes = data.GetNodes( 152 BookmarkModelFactory::GetForProfile(profile), profile_path); 153 for (size_t i = 0; i < nodes.size(); ++i) { 154 node_data->elements.push_back( 155 CreateNodeDataElementFromBookmarkNode(*nodes[i])); 156 } 157 } else { 158 // We do not have a node IDs when the data comes from a different profile. 159 std::vector<BookmarkNodeData::Element> elements = data.elements; 160 for (size_t i = 0; i < elements.size(); ++i) 161 node_data->elements.push_back(CreateApiNodeDataElement(elements[i])); 162 } 163 return node_data.Pass(); 164} 165 166} // namespace 167 168BookmarkManagerPrivateEventRouter::BookmarkManagerPrivateEventRouter( 169 content::BrowserContext* browser_context, 170 BookmarkModel* bookmark_model) 171 : browser_context_(browser_context), bookmark_model_(bookmark_model) { 172 bookmark_model_->AddObserver(this); 173} 174 175BookmarkManagerPrivateEventRouter::~BookmarkManagerPrivateEventRouter() { 176 if (bookmark_model_) 177 bookmark_model_->RemoveObserver(this); 178} 179 180void BookmarkManagerPrivateEventRouter::DispatchEvent( 181 const std::string& event_name, 182 scoped_ptr<base::ListValue> event_args) { 183 extensions::EventRouter::Get(browser_context_)->BroadcastEvent( 184 make_scoped_ptr(new extensions::Event(event_name, event_args.Pass()))); 185} 186 187void BookmarkManagerPrivateEventRouter::BookmarkModelChanged() {} 188 189void BookmarkManagerPrivateEventRouter::BookmarkModelBeingDeleted( 190 BookmarkModel* model) { 191 bookmark_model_ = NULL; 192} 193 194void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo( 195 BookmarkModel* model, 196 const BookmarkNode* node) { 197 DCHECK(prev_meta_info_.empty()); 198 if (node->GetMetaInfoMap()) 199 prev_meta_info_ = *node->GetMetaInfoMap(); 200} 201 202void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged( 203 BookmarkModel* model, 204 const BookmarkNode* node) { 205 const BookmarkNode::MetaInfoMap* new_meta_info = node->GetMetaInfoMap(); 206 bookmark_manager_private::MetaInfoFields changes; 207 208 // Identify changed/removed fields: 209 for (BookmarkNode::MetaInfoMap::const_iterator it = prev_meta_info_.begin(); 210 it != prev_meta_info_.end(); 211 ++it) { 212 if (!new_meta_info) { 213 changes.additional_properties[it->first] = ""; 214 } else { 215 BookmarkNode::MetaInfoMap::const_iterator new_meta_field = 216 new_meta_info->find(it->first); 217 if (new_meta_field == new_meta_info->end()) { 218 changes.additional_properties[it->first] = ""; 219 } else if (it->second != new_meta_field->second) { 220 changes.additional_properties[it->first] = new_meta_field->second; 221 } 222 } 223 } 224 225 // Identify added fields: 226 if (new_meta_info) { 227 for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin(); 228 it != new_meta_info->end(); 229 ++it) { 230 BookmarkNode::MetaInfoMap::const_iterator prev_meta_field = 231 prev_meta_info_.find(it->first); 232 if (prev_meta_field == prev_meta_info_.end()) 233 changes.additional_properties[it->first] = it->second; 234 } 235 } 236 237 prev_meta_info_.clear(); 238 DispatchEvent(bookmark_manager_private::OnMetaInfoChanged::kEventName, 239 bookmark_manager_private::OnMetaInfoChanged::Create( 240 base::Int64ToString(node->id()), changes)); 241} 242 243BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI( 244 content::BrowserContext* browser_context) 245 : browser_context_(browser_context) { 246 EventRouter* event_router = EventRouter::Get(browser_context); 247 event_router->RegisterObserver( 248 this, bookmark_manager_private::OnMetaInfoChanged::kEventName); 249} 250 251BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {} 252 253void BookmarkManagerPrivateAPI::Shutdown() { 254 EventRouter::Get(browser_context_)->UnregisterObserver(this); 255} 256 257static base::LazyInstance< 258 BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI> > g_factory = 259 LAZY_INSTANCE_INITIALIZER; 260 261// static 262BrowserContextKeyedAPIFactory<BookmarkManagerPrivateAPI>* 263BookmarkManagerPrivateAPI::GetFactoryInstance() { 264 return g_factory.Pointer(); 265} 266 267void BookmarkManagerPrivateAPI::OnListenerAdded( 268 const EventListenerInfo& details) { 269 EventRouter::Get(browser_context_)->UnregisterObserver(this); 270 event_router_.reset(new BookmarkManagerPrivateEventRouter( 271 browser_context_, 272 BookmarkModelFactory::GetForProfile( 273 Profile::FromBrowserContext(browser_context_)))); 274} 275 276BookmarkManagerPrivateDragEventRouter::BookmarkManagerPrivateDragEventRouter( 277 Profile* profile, 278 content::WebContents* web_contents) 279 : profile_(profile), web_contents_(web_contents) { 280 BookmarkTabHelper* bookmark_tab_helper = 281 BookmarkTabHelper::FromWebContents(web_contents_); 282 bookmark_tab_helper->set_bookmark_drag_delegate(this); 283} 284 285BookmarkManagerPrivateDragEventRouter:: 286 ~BookmarkManagerPrivateDragEventRouter() { 287 BookmarkTabHelper* bookmark_tab_helper = 288 BookmarkTabHelper::FromWebContents(web_contents_); 289 if (bookmark_tab_helper->bookmark_drag_delegate() == this) 290 bookmark_tab_helper->set_bookmark_drag_delegate(NULL); 291} 292 293void BookmarkManagerPrivateDragEventRouter::DispatchEvent( 294 const std::string& event_name, 295 scoped_ptr<base::ListValue> args) { 296 EventRouter* event_router = EventRouter::Get(profile_); 297 if (!event_router) 298 return; 299 300 scoped_ptr<Event> event(new Event(event_name, args.Pass())); 301 event_router->BroadcastEvent(event.Pass()); 302} 303 304void BookmarkManagerPrivateDragEventRouter::OnDragEnter( 305 const BookmarkNodeData& data) { 306 if (data.size() == 0) 307 return; 308 DispatchEvent(bookmark_manager_private::OnDragEnter::kEventName, 309 bookmark_manager_private::OnDragEnter::Create( 310 *CreateApiBookmarkNodeData(profile_, data))); 311} 312 313void BookmarkManagerPrivateDragEventRouter::OnDragOver( 314 const BookmarkNodeData& data) { 315 // Intentionally empty since these events happens too often and floods the 316 // message queue. We do not need this event for the bookmark manager anyway. 317} 318 319void BookmarkManagerPrivateDragEventRouter::OnDragLeave( 320 const BookmarkNodeData& data) { 321 if (data.size() == 0) 322 return; 323 DispatchEvent(bookmark_manager_private::OnDragLeave::kEventName, 324 bookmark_manager_private::OnDragLeave::Create( 325 *CreateApiBookmarkNodeData(profile_, data))); 326} 327 328void BookmarkManagerPrivateDragEventRouter::OnDrop( 329 const BookmarkNodeData& data) { 330 if (data.size() == 0) 331 return; 332 DispatchEvent(bookmark_manager_private::OnDrop::kEventName, 333 bookmark_manager_private::OnDrop::Create( 334 *CreateApiBookmarkNodeData(profile_, data))); 335 336 // Make a copy that is owned by this instance. 337 ClearBookmarkNodeData(); 338 bookmark_drag_data_ = data; 339} 340 341const BookmarkNodeData* 342BookmarkManagerPrivateDragEventRouter::GetBookmarkNodeData() { 343 if (bookmark_drag_data_.is_valid()) 344 return &bookmark_drag_data_; 345 return NULL; 346} 347 348void BookmarkManagerPrivateDragEventRouter::ClearBookmarkNodeData() { 349 bookmark_drag_data_.Clear(); 350} 351 352bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut, 353 const std::vector<std::string>& id_list) { 354 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 355 std::vector<const BookmarkNode*> nodes; 356 EXTENSION_FUNCTION_VALIDATE(GetNodesFromVector(model, id_list, &nodes)); 357 bookmark_utils::CopyToClipboard(model, nodes, cut); 358 return true; 359} 360 361bool BookmarkManagerPrivateCopyFunction::RunOnReady() { 362 scoped_ptr<Copy::Params> params(Copy::Params::Create(*args_)); 363 EXTENSION_FUNCTION_VALIDATE(params); 364 return CopyOrCut(false, params->id_list); 365} 366 367bool BookmarkManagerPrivateCutFunction::RunOnReady() { 368 if (!EditBookmarksEnabled()) 369 return false; 370 371 scoped_ptr<Cut::Params> params(Cut::Params::Create(*args_)); 372 EXTENSION_FUNCTION_VALIDATE(params); 373 return CopyOrCut(true, params->id_list); 374} 375 376bool BookmarkManagerPrivatePasteFunction::RunOnReady() { 377 if (!EditBookmarksEnabled()) 378 return false; 379 380 scoped_ptr<Paste::Params> params(Paste::Params::Create(*args_)); 381 EXTENSION_FUNCTION_VALIDATE(params); 382 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 383 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); 384 if (!parent_node) { 385 error_ = bookmark_keys::kNoParentError; 386 return false; 387 } 388 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); 389 if (!can_paste) 390 return false; 391 392 // We want to use the highest index of the selected nodes as a destination. 393 std::vector<const BookmarkNode*> nodes; 394 // No need to test return value, if we got an empty list, we insert at end. 395 if (params->selected_id_list) 396 GetNodesFromVector(model, *params->selected_id_list, &nodes); 397 int highest_index = -1; // -1 means insert at end of list. 398 for (size_t i = 0; i < nodes.size(); ++i) { 399 // + 1 so that we insert after the selection. 400 int index = parent_node->GetIndexOf(nodes[i]) + 1; 401 if (index > highest_index) 402 highest_index = index; 403 } 404 405 bookmark_utils::PasteFromClipboard(model, parent_node, highest_index); 406 return true; 407} 408 409bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() { 410 if (!EditBookmarksEnabled()) 411 return false; 412 413 scoped_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_)); 414 EXTENSION_FUNCTION_VALIDATE(params); 415 416 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 417 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); 418 if (!parent_node) { 419 error_ = bookmark_keys::kNoParentError; 420 return false; 421 } 422 bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); 423 SetResult(new base::FundamentalValue(can_paste)); 424 return true; 425} 426 427bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() { 428 if (!EditBookmarksEnabled()) 429 return false; 430 431 scoped_ptr<SortChildren::Params> params(SortChildren::Params::Create(*args_)); 432 EXTENSION_FUNCTION_VALIDATE(params); 433 434 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 435 const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); 436 if (!parent_node) { 437 error_ = bookmark_keys::kNoParentError; 438 return false; 439 } 440 model->SortChildren(parent_node); 441 return true; 442} 443 444bool BookmarkManagerPrivateGetStringsFunction::RunAsync() { 445 base::DictionaryValue* localized_strings = new base::DictionaryValue(); 446 447 localized_strings->SetString("title", 448 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE)); 449 localized_strings->SetString("search_button", 450 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON)); 451 localized_strings->SetString("organize_menu", 452 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU)); 453 localized_strings->SetString("show_in_folder", 454 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); 455 localized_strings->SetString("sort", 456 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SORT)); 457 localized_strings->SetString("import_menu", 458 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_IMPORT_MENU)); 459 localized_strings->SetString("export_menu", 460 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_EXPORT_MENU)); 461 localized_strings->SetString("rename_folder", 462 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_RENAME_FOLDER)); 463 localized_strings->SetString("edit", 464 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_EDIT)); 465 localized_strings->SetString("should_open_all", 466 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL)); 467 localized_strings->SetString("open_incognito", 468 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_INCOGNITO)); 469 localized_strings->SetString("open_in_new_tab", 470 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB)); 471 localized_strings->SetString("open_in_new_window", 472 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW)); 473 localized_strings->SetString("add_new_bookmark", 474 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK)); 475 localized_strings->SetString("new_folder", 476 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_NEW_FOLDER)); 477 localized_strings->SetString("open_all", 478 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL)); 479 localized_strings->SetString("open_all_new_window", 480 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW)); 481 localized_strings->SetString("open_all_incognito", 482 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO)); 483 localized_strings->SetString("remove", 484 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_REMOVE)); 485 localized_strings->SetString("copy", 486 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_COPY)); 487 localized_strings->SetString("cut", 488 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_CUT)); 489 localized_strings->SetString("paste", 490 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PASTE)); 491 localized_strings->SetString("delete", 492 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_DELETE)); 493 localized_strings->SetString("undo_delete", 494 l10n_util::GetStringUTF16(IDS_UNDO_DELETE)); 495 localized_strings->SetString("new_folder_name", 496 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME)); 497 localized_strings->SetString("name_input_placeholder", 498 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER)); 499 localized_strings->SetString("url_input_placeholder", 500 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER)); 501 localized_strings->SetString("invalid_url", 502 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_INVALID_URL)); 503 localized_strings->SetString("recent", 504 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_RECENT)); 505 localized_strings->SetString("search", 506 l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH)); 507 localized_strings->SetString("save", 508 l10n_util::GetStringUTF16(IDS_SAVE)); 509 localized_strings->SetString("cancel", 510 l10n_util::GetStringUTF16(IDS_CANCEL)); 511 512 webui::SetFontAndTextDirection(localized_strings); 513 514 SetResult(localized_strings); 515 516 // This is needed because unlike the rest of these functions, this class 517 // inherits from AsyncFunction directly, rather than BookmarkFunction. 518 SendResponse(true); 519 520 return true; 521} 522 523bool BookmarkManagerPrivateStartDragFunction::RunOnReady() { 524 if (!EditBookmarksEnabled()) 525 return false; 526 527 scoped_ptr<StartDrag::Params> params(StartDrag::Params::Create(*args_)); 528 EXTENSION_FUNCTION_VALIDATE(params); 529 530 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 531 std::vector<const BookmarkNode*> nodes; 532 EXTENSION_FUNCTION_VALIDATE( 533 GetNodesFromVector(model, params->id_list, &nodes)); 534 535 WebContents* web_contents = 536 WebContents::FromRenderViewHost(render_view_host_); 537 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) { 538 WebContents* web_contents = 539 dispatcher()->delegate()->GetAssociatedWebContents(); 540 CHECK(web_contents); 541 542 ui::DragDropTypes::DragEventSource source = 543 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE; 544 if (params->is_from_touch) 545 source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH; 546 547 chrome::DragBookmarks( 548 GetProfile(), nodes, web_contents->GetNativeView(), source); 549 550 return true; 551 } else { 552 NOTREACHED(); 553 return false; 554 } 555} 556 557bool BookmarkManagerPrivateDropFunction::RunOnReady() { 558 if (!EditBookmarksEnabled()) 559 return false; 560 561 scoped_ptr<Drop::Params> params(Drop::Params::Create(*args_)); 562 EXTENSION_FUNCTION_VALIDATE(params); 563 564 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 565 566 const BookmarkNode* drop_parent = GetNodeFromString(model, params->parent_id); 567 if (!drop_parent) { 568 error_ = bookmark_keys::kNoParentError; 569 return false; 570 } 571 572 int drop_index; 573 if (params->index) 574 drop_index = *params->index; 575 else 576 drop_index = drop_parent->child_count(); 577 578 WebContents* web_contents = 579 WebContents::FromRenderViewHost(render_view_host_); 580 if (GetViewType(web_contents) == VIEW_TYPE_TAB_CONTENTS) { 581 WebContents* web_contents = 582 dispatcher()->delegate()->GetAssociatedWebContents(); 583 CHECK(web_contents); 584 ExtensionWebUI* web_ui = 585 static_cast<ExtensionWebUI*>(web_contents->GetWebUI()->GetController()); 586 CHECK(web_ui); 587 BookmarkManagerPrivateDragEventRouter* router = 588 web_ui->bookmark_manager_private_drag_event_router(); 589 590 DCHECK(router); 591 const BookmarkNodeData* drag_data = router->GetBookmarkNodeData(); 592 if (drag_data == NULL) { 593 NOTREACHED() <<"Somehow we're dropping null bookmark data"; 594 return false; 595 } 596 chrome::DropBookmarks(GetProfile(), *drag_data, drop_parent, drop_index); 597 598 router->ClearBookmarkNodeData(); 599 return true; 600 } else { 601 NOTREACHED(); 602 return false; 603 } 604} 605 606bool BookmarkManagerPrivateGetSubtreeFunction::RunOnReady() { 607 scoped_ptr<GetSubtree::Params> params(GetSubtree::Params::Create(*args_)); 608 EXTENSION_FUNCTION_VALIDATE(params); 609 610 const BookmarkNode* node = NULL; 611 612 if (params->id == "") { 613 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 614 node = model->root_node(); 615 } else { 616 node = GetBookmarkNodeFromId(params->id); 617 if (!node) 618 return false; 619 } 620 621 std::vector<linked_ptr<api::bookmarks::BookmarkTreeNode> > nodes; 622 if (params->folders_only) 623 bookmark_api_helpers::AddNodeFoldersOnly(node, &nodes, true); 624 else 625 bookmark_api_helpers::AddNode(node, &nodes, true); 626 results_ = GetSubtree::Results::Create(nodes); 627 return true; 628} 629 630bool BookmarkManagerPrivateCanEditFunction::RunOnReady() { 631 PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); 632 SetResult(new base::FundamentalValue( 633 prefs->GetBoolean(prefs::kEditBookmarksEnabled))); 634 return true; 635} 636 637bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() { 638 RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER); 639 return true; 640} 641 642bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() { 643 scoped_ptr<CreateWithMetaInfo::Params> params( 644 CreateWithMetaInfo::Params::Create(*args_)); 645 EXTENSION_FUNCTION_VALIDATE(params); 646 647 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 648 const BookmarkNode* node = CreateBookmarkNode( 649 model, params->bookmark, ¶ms->meta_info.additional_properties); 650 if (!node) 651 return false; 652 653 scoped_ptr<api::bookmarks::BookmarkTreeNode> result_node( 654 bookmark_api_helpers::GetBookmarkTreeNode(node, false, false)); 655 results_ = CreateWithMetaInfo::Results::Create(*result_node); 656 657 return true; 658} 659 660bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() { 661 scoped_ptr<GetMetaInfo::Params> params(GetMetaInfo::Params::Create(*args_)); 662 EXTENSION_FUNCTION_VALIDATE(params); 663 664 const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 665 if (!node) 666 return false; 667 668 if (params->key) { 669 std::string value; 670 if (node->GetMetaInfo(*params->key, &value)) { 671 GetMetaInfo::Results::Value result; 672 result.as_string.reset(new std::string(value)); 673 results_ = GetMetaInfo::Results::Create(result); 674 } 675 } else { 676 GetMetaInfo::Results::Value result; 677 result.as_meta_info_fields.reset( 678 new bookmark_manager_private::MetaInfoFields); 679 680 const BookmarkNode::MetaInfoMap* meta_info = node->GetMetaInfoMap(); 681 if (meta_info) 682 result.as_meta_info_fields->additional_properties = *meta_info; 683 results_ = GetMetaInfo::Results::Create(result); 684 } 685 686 return true; 687} 688 689bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() { 690 scoped_ptr<SetMetaInfo::Params> params(SetMetaInfo::Params::Create(*args_)); 691 EXTENSION_FUNCTION_VALIDATE(params); 692 693 const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 694 if (!node) 695 return false; 696 697 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 698 model->SetNodeMetaInfo(node, params->key, params->value); 699 return true; 700} 701 702bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() { 703 scoped_ptr<UpdateMetaInfo::Params> params( 704 UpdateMetaInfo::Params::Create(*args_)); 705 EXTENSION_FUNCTION_VALIDATE(params); 706 707 const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 708 if (!node) 709 return false; 710 711 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 712 BookmarkNode::MetaInfoMap new_meta_info( 713 params->meta_info_changes.additional_properties); 714 if (node->GetMetaInfoMap()) { 715 new_meta_info.insert(node->GetMetaInfoMap()->begin(), 716 node->GetMetaInfoMap()->end()); 717 } 718 model->SetNodeMetaInfoMap(node, new_meta_info); 719 720 return true; 721} 722 723bool BookmarkManagerPrivateCanOpenNewWindowsFunction::RunOnReady() { 724 bool can_open_new_windows = true; 725 SetResult(new base::FundamentalValue(can_open_new_windows)); 726 return true; 727} 728 729bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() { 730 scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_)); 731 EXTENSION_FUNCTION_VALIDATE(params); 732 733 BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 734#if !defined(OS_ANDROID) 735 bookmarks::ScopedGroupBookmarkActions group_deletes(model); 736#endif 737 int64 id; 738 for (size_t i = 0; i < params->id_list.size(); ++i) { 739 if (!GetBookmarkIdAsInt64(params->id_list[i], &id)) 740 return false; 741 if (!bookmark_api_helpers::RemoveNode(model, id, true, &error_)) 742 return false; 743 } 744 745 return true; 746} 747 748bool BookmarkManagerPrivateUndoFunction::RunOnReady() { 749#if !defined(OS_ANDROID) 750 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()-> 751 Undo(); 752#endif 753 754 return true; 755} 756 757bool BookmarkManagerPrivateRedoFunction::RunOnReady() { 758#if !defined(OS_ANDROID) 759 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager()-> 760 Redo(); 761#endif 762 763 return true; 764} 765 766bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() { 767#if !defined(OS_ANDROID) 768 UndoManager* undo_manager = 769 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager(); 770 771 UndoInfo::Results::Result result; 772 result.enabled = undo_manager->undo_count() > 0; 773 result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel()); 774 775 results_ = UndoInfo::Results::Create(result); 776#endif // !defined(OS_ANDROID) 777 778 return true; 779} 780 781bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() { 782#if !defined(OS_ANDROID) 783 UndoManager* undo_manager = 784 BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager(); 785 786 RedoInfo::Results::Result result; 787 result.enabled = undo_manager->redo_count() > 0; 788 result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel()); 789 790 results_ = RedoInfo::Results::Create(result); 791#endif // !defined(OS_ANDROID) 792 793 return true; 794} 795 796} // namespace extensions 797