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