Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/bookmarks/bookmark_extension_api.h" | 5 #include "chrome/browser/bookmarks/bookmark_extension_api.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/i18n/file_util_icu.h" | 9 #include "base/i18n/file_util_icu.h" |
| 10 #include "base/i18n/time_formatting.h" | 10 #include "base/i18n/time_formatting.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 27 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 28 #include "chrome/browser/extensions/extensions_quota_service.h" | 28 #include "chrome/browser/extensions/extensions_quota_service.h" |
| 29 #include "chrome/browser/importer/importer_data_types.h" | 29 #include "chrome/browser/importer/importer_data_types.h" |
| 30 #include "chrome/browser/importer/importer_host.h" | 30 #include "chrome/browser/importer/importer_host.h" |
| 31 #include "chrome/browser/prefs/pref_service.h" | 31 #include "chrome/browser/prefs/pref_service.h" |
| 32 #include "chrome/browser/profiles/profile.h" | 32 #include "chrome/browser/profiles/profile.h" |
| 33 #include "chrome/browser/ui/browser_list.h" | 33 #include "chrome/browser/ui/browser_list.h" |
| 34 #include "chrome/browser/ui/chrome_select_file_policy.h" | 34 #include "chrome/browser/ui/chrome_select_file_policy.h" |
| 35 #include "chrome/common/chrome_notification_types.h" | 35 #include "chrome/common/chrome_notification_types.h" |
| 36 #include "chrome/common/chrome_paths.h" | 36 #include "chrome/common/chrome_paths.h" |
| 37 #include "chrome/common/extensions/api/bookmarks.h" | |
| 37 #include "chrome/common/pref_names.h" | 38 #include "chrome/common/pref_names.h" |
| 38 #include "content/public/browser/notification_service.h" | 39 #include "content/public/browser/notification_service.h" |
| 39 #include "grit/generated_resources.h" | 40 #include "grit/generated_resources.h" |
| 40 #include "ui/base/l10n/l10n_util.h" | 41 #include "ui/base/l10n/l10n_util.h" |
| 41 | 42 |
| 42 namespace keys = bookmark_extension_api_constants; | 43 namespace keys = bookmark_extension_api_constants; |
| 43 | 44 |
| 45 namespace Create = extensions::api::bookmarks::Create; | |
| 46 namespace Get = extensions::api::bookmarks::Get; | |
| 47 namespace GetChildren = extensions::api::bookmarks::GetChildren; | |
| 48 namespace GetRecent = extensions::api::bookmarks::GetRecent; | |
| 49 namespace GetSubTree = extensions::api::bookmarks::GetSubTree; | |
| 50 namespace GetTree = extensions::api::bookmarks::GetTree; | |
| 51 namespace Move = extensions::api::bookmarks::Move; | |
| 52 namespace Remove = extensions::api::bookmarks::Remove; | |
| 53 namespace Search = extensions::api::bookmarks::Search; | |
| 54 namespace Update = extensions::api::bookmarks::Update; | |
| 55 | |
| 44 using base::TimeDelta; | 56 using base::TimeDelta; |
| 45 using content::BrowserThread; | 57 using content::BrowserThread; |
| 46 using content::WebContents; | 58 using content::WebContents; |
| 59 using extensions::api::bookmarks::BookmarkTreeNode; | |
| 47 | 60 |
| 48 typedef QuotaLimitHeuristic::Bucket Bucket; | 61 typedef QuotaLimitHeuristic::Bucket Bucket; |
| 49 typedef QuotaLimitHeuristic::Config Config; | 62 typedef QuotaLimitHeuristic::Config Config; |
| 50 typedef QuotaLimitHeuristic::BucketList BucketList; | 63 typedef QuotaLimitHeuristic::BucketList BucketList; |
| 51 typedef ExtensionsQuotaService::TimedLimit TimedLimit; | 64 typedef ExtensionsQuotaService::TimedLimit TimedLimit; |
| 52 typedef ExtensionsQuotaService::SustainedLimit SustainedLimit; | 65 typedef ExtensionsQuotaService::SustainedLimit SustainedLimit; |
| 53 typedef QuotaLimitHeuristic::BucketMapper BucketMapper; | 66 typedef QuotaLimitHeuristic::BucketMapper BucketMapper; |
| 54 | 67 |
| 55 namespace { | 68 namespace { |
| 56 | 69 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 base::JSONWriter::Write(&args, &json_args); | 198 base::JSONWriter::Write(&args, &json_args); |
| 186 DispatchEvent(model->profile(), keys::kOnBookmarkMoved, json_args); | 199 DispatchEvent(model->profile(), keys::kOnBookmarkMoved, json_args); |
| 187 } | 200 } |
| 188 | 201 |
| 189 void BookmarkExtensionEventRouter::BookmarkNodeAdded(BookmarkModel* model, | 202 void BookmarkExtensionEventRouter::BookmarkNodeAdded(BookmarkModel* model, |
| 190 const BookmarkNode* parent, | 203 const BookmarkNode* parent, |
| 191 int index) { | 204 int index) { |
| 192 ListValue args; | 205 ListValue args; |
| 193 const BookmarkNode* node = parent->GetChild(index); | 206 const BookmarkNode* node = parent->GetChild(index); |
| 194 args.Append(new StringValue(base::Int64ToString(node->id()))); | 207 args.Append(new StringValue(base::Int64ToString(node->id()))); |
| 195 DictionaryValue* obj = | 208 BookmarkTreeNode* obj = |
| 196 bookmark_extension_helpers::GetNodeDictionary(node, false, false); | 209 bookmark_extension_helpers::GetBookmarkTreeNode(node, false, false); |
| 197 args.Append(obj); | 210 args.Append(obj->ToValue().get()); |
| 198 | 211 |
| 199 std::string json_args; | 212 std::string json_args; |
| 200 base::JSONWriter::Write(&args, &json_args); | 213 base::JSONWriter::Write(&args, &json_args); |
| 201 DispatchEvent(model->profile(), keys::kOnBookmarkCreated, json_args); | 214 DispatchEvent(model->profile(), keys::kOnBookmarkCreated, json_args); |
| 202 } | 215 } |
| 203 | 216 |
| 204 void BookmarkExtensionEventRouter::BookmarkNodeRemoved( | 217 void BookmarkExtensionEventRouter::BookmarkNodeRemoved( |
| 205 BookmarkModel* model, | 218 BookmarkModel* model, |
| 206 const BookmarkNode* parent, | 219 const BookmarkNode* parent, |
| 207 int index, | 220 int index, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 BookmarkModel* model) { | 294 BookmarkModel* model) { |
| 282 ListValue args; | 295 ListValue args; |
| 283 std::string json_args; | 296 std::string json_args; |
| 284 base::JSONWriter::Write(&args, &json_args); | 297 base::JSONWriter::Write(&args, &json_args); |
| 285 DispatchEvent(model->profile(), | 298 DispatchEvent(model->profile(), |
| 286 keys::kOnBookmarkImportEnded, | 299 keys::kOnBookmarkImportEnded, |
| 287 json_args); | 300 json_args); |
| 288 } | 301 } |
| 289 | 302 |
| 290 bool GetBookmarksFunction::RunImpl() { | 303 bool GetBookmarksFunction::RunImpl() { |
| 304 scoped_ptr<Get::Params> params(Get::Params::Create(*args_)); | |
| 305 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
| 306 | |
| 307 std::vector<linked_ptr<BookmarkTreeNode> > nodes; | |
| 291 BookmarkModel* model = profile()->GetBookmarkModel(); | 308 BookmarkModel* model = profile()->GetBookmarkModel(); |
| 292 scoped_ptr<ListValue> json(new ListValue()); | 309 if (params->id_or_id_list_type == Get::Params::ID_OR_ID_LIST_ARRAY) { |
|
Aaron Boodman
2012/07/23 23:37:57
I see this pattern a lot. Can we teach the JSON Sc
mitchellwrosen
2012/07/24 17:13:39
If I understand correctly: the end result would be
Matt Tytel
2012/07/24 22:24:28
Json schema compiler drive-by:
Yea this looks impl
| |
| 293 Value* arg0; | 310 std::vector<std::string>* ids = params->id_or_id_list_array.get(); |
| 294 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &arg0)); | 311 size_t count = ids->size(); |
| 295 if (arg0->IsType(Value::TYPE_LIST)) { | |
| 296 const ListValue* ids = static_cast<const ListValue*>(arg0); | |
| 297 size_t count = ids->GetSize(); | |
| 298 EXTENSION_FUNCTION_VALIDATE(count > 0); | 312 EXTENSION_FUNCTION_VALIDATE(count > 0); |
| 299 for (size_t i = 0; i < count; ++i) { | 313 for (size_t i = 0; i < count; ++i) { |
| 300 int64 id; | 314 int64 id; |
| 301 std::string id_string; | 315 if (!GetBookmarkIdAsInt64(ids->at(i), &id)) |
| 302 EXTENSION_FUNCTION_VALIDATE(ids->GetString(i, &id_string)); | |
| 303 if (!GetBookmarkIdAsInt64(id_string, &id)) | |
| 304 return false; | 316 return false; |
| 305 const BookmarkNode* node = model->GetNodeByID(id); | 317 const BookmarkNode* node = model->GetNodeByID(id); |
| 306 if (!node) { | 318 if (!node) { |
| 307 error_ = keys::kNoNodeError; | 319 error_ = keys::kNoNodeError; |
| 308 return false; | 320 return false; |
| 309 } else { | 321 } else { |
| 310 bookmark_extension_helpers::AddNode(node, json.get(), false); | 322 bookmark_extension_helpers::AddNode(node, &nodes, false); |
| 311 } | 323 } |
| 312 } | 324 } |
| 313 } else { | 325 } else { |
| 314 int64 id; | 326 int64 id; |
| 315 std::string id_string; | 327 if (!GetBookmarkIdAsInt64(*params->id_or_id_list_string, &id)) |
| 316 EXTENSION_FUNCTION_VALIDATE(arg0->GetAsString(&id_string)); | |
| 317 if (!GetBookmarkIdAsInt64(id_string, &id)) | |
| 318 return false; | 328 return false; |
| 319 const BookmarkNode* node = model->GetNodeByID(id); | 329 const BookmarkNode* node = model->GetNodeByID(id); |
| 320 if (!node) { | 330 if (!node) { |
| 321 error_ = keys::kNoNodeError; | 331 error_ = keys::kNoNodeError; |
| 322 return false; | 332 return false; |
| 323 } | 333 } |
| 324 bookmark_extension_helpers::AddNode(node, json.get(), false); | 334 bookmark_extension_helpers::AddNode(node, &nodes, false); |
| 325 } | 335 } |
| 326 | 336 |
| 327 result_.reset(json.release()); | 337 result_.reset(Get::Result::Create(nodes)); |
| 328 return true; | 338 return true; |
| 329 } | 339 } |
| 330 | 340 |
| 331 bool GetBookmarkChildrenFunction::RunImpl() { | 341 bool GetBookmarkChildrenFunction::RunImpl() { |
| 332 BookmarkModel* model = profile()->GetBookmarkModel(); | 342 scoped_ptr<GetChildren::Params> params(GetChildren::Params::Create(*args_)); |
| 343 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
| 344 | |
| 333 int64 id; | 345 int64 id; |
| 334 std::string id_string; | 346 if (!GetBookmarkIdAsInt64(params->id, &id)) |
| 335 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id_string)); | |
| 336 if (!GetBookmarkIdAsInt64(id_string, &id)) | |
| 337 return false; | 347 return false; |
| 338 scoped_ptr<ListValue> json(new ListValue()); | 348 |
| 339 const BookmarkNode* node = model->GetNodeByID(id); | 349 std::vector<linked_ptr<BookmarkTreeNode> > nodes; |
| 350 const BookmarkNode* node = profile()->GetBookmarkModel()->GetNodeByID(id); | |
| 340 if (!node) { | 351 if (!node) { |
| 341 error_ = keys::kNoNodeError; | 352 error_ = keys::kNoNodeError; |
| 342 return false; | 353 return false; |
| 343 } | 354 } |
| 344 int child_count = node->child_count(); | 355 int child_count = node->child_count(); |
| 345 for (int i = 0; i < child_count; ++i) { | 356 for (int i = 0; i < child_count; ++i) { |
| 346 const BookmarkNode* child = node->GetChild(i); | 357 const BookmarkNode* child = node->GetChild(i); |
| 347 bookmark_extension_helpers::AddNode(child, json.get(), false); | 358 bookmark_extension_helpers::AddNode(child, &nodes, false); |
| 348 } | 359 } |
| 349 | 360 |
| 350 result_.reset(json.release()); | 361 result_.reset(GetChildren::Result::Create(nodes)); |
| 351 return true; | 362 return true; |
| 352 } | 363 } |
| 353 | 364 |
| 354 bool GetBookmarkRecentFunction::RunImpl() { | 365 bool GetBookmarkRecentFunction::RunImpl() { |
| 355 int number_of_items; | 366 scoped_ptr<GetRecent::Params> params(GetRecent::Params::Create(*args_)); |
| 356 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &number_of_items)); | 367 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 357 if (number_of_items < 1) | 368 if (params->number_of_items < 1) |
| 358 return false; | 369 return false; |
| 359 | 370 |
| 360 BookmarkModel* model = profile()->GetBookmarkModel(); | |
| 361 ListValue* json = new ListValue(); | |
| 362 std::vector<const BookmarkNode*> nodes; | 371 std::vector<const BookmarkNode*> nodes; |
| 363 bookmark_utils::GetMostRecentlyAddedEntries(model, number_of_items, &nodes); | 372 bookmark_utils::GetMostRecentlyAddedEntries(profile()->GetBookmarkModel(), |
| 373 params->number_of_items, | |
| 374 &nodes); | |
| 375 | |
| 376 std::vector<linked_ptr<BookmarkTreeNode> > tree_nodes; | |
| 364 std::vector<const BookmarkNode*>::iterator i = nodes.begin(); | 377 std::vector<const BookmarkNode*>::iterator i = nodes.begin(); |
| 365 for (; i != nodes.end(); ++i) { | 378 for (; i != nodes.end(); ++i) { |
| 366 const BookmarkNode* node = *i; | 379 const BookmarkNode* node = *i; |
| 367 bookmark_extension_helpers::AddNode(node, json, false); | 380 bookmark_extension_helpers::AddNode(node, &tree_nodes, false); |
| 368 } | 381 } |
| 369 result_.reset(json); | 382 result_.reset(GetRecent::Result::Create(tree_nodes)); |
| 370 return true; | 383 return true; |
| 371 } | 384 } |
| 372 | 385 |
| 373 bool GetBookmarkTreeFunction::RunImpl() { | 386 bool GetBookmarkTreeFunction::RunImpl() { |
| 374 BookmarkModel* model = profile()->GetBookmarkModel(); | 387 std::vector<linked_ptr<BookmarkTreeNode> > nodes; |
| 375 scoped_ptr<ListValue> json(new ListValue()); | 388 const BookmarkNode* node = profile()->GetBookmarkModel()->root_node(); |
| 376 const BookmarkNode* node = model->root_node(); | 389 bookmark_extension_helpers::AddNode(node, &nodes, true); |
| 377 bookmark_extension_helpers::AddNode(node, json.get(), true); | 390 result_.reset(GetTree::Result::Create(nodes)); |
| 378 result_.reset(json.release()); | |
| 379 return true; | 391 return true; |
| 380 } | 392 } |
| 381 | 393 |
| 382 bool GetBookmarkSubTreeFunction::RunImpl() { | 394 bool GetBookmarkSubTreeFunction::RunImpl() { |
| 383 BookmarkModel* model = profile()->GetBookmarkModel(); | 395 scoped_ptr<GetSubTree::Params> params(GetSubTree::Params::Create(*args_)); |
| 384 scoped_ptr<ListValue> json(new ListValue()); | 396 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 385 Value* arg0; | 397 |
| 386 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &arg0)); | |
| 387 int64 id; | 398 int64 id; |
| 388 std::string id_string; | 399 if (!GetBookmarkIdAsInt64(params->id, &id)) |
| 389 EXTENSION_FUNCTION_VALIDATE(arg0->GetAsString(&id_string)); | |
| 390 if (!GetBookmarkIdAsInt64(id_string, &id)) | |
| 391 return false; | 400 return false; |
| 392 const BookmarkNode* node = model->GetNodeByID(id); | 401 |
| 402 const BookmarkNode* node = profile()->GetBookmarkModel()->GetNodeByID(id); | |
| 393 if (!node) { | 403 if (!node) { |
| 394 error_ = keys::kNoNodeError; | 404 error_ = keys::kNoNodeError; |
| 395 return false; | 405 return false; |
| 396 } | 406 } |
| 397 bookmark_extension_helpers::AddNode(node, json.get(), true); | 407 |
| 398 result_.reset(json.release()); | 408 std::vector<linked_ptr<BookmarkTreeNode> > nodes; |
| 409 bookmark_extension_helpers::AddNode(node, &nodes, true); | |
| 410 result_.reset(GetSubTree::Result::Create(nodes)); | |
| 399 return true; | 411 return true; |
| 400 } | 412 } |
| 401 | 413 |
| 402 bool SearchBookmarksFunction::RunImpl() { | 414 bool SearchBookmarksFunction::RunImpl() { |
| 403 string16 query; | 415 scoped_ptr<Search::Params> params(Search::Params::Create(*args_)); |
| 404 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &query)); | 416 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 405 | 417 |
| 406 BookmarkModel* model = profile()->GetBookmarkModel(); | |
| 407 ListValue* json = new ListValue(); | |
| 408 std::string lang = profile()->GetPrefs()->GetString(prefs::kAcceptLanguages); | 418 std::string lang = profile()->GetPrefs()->GetString(prefs::kAcceptLanguages); |
| 409 std::vector<const BookmarkNode*> nodes; | 419 std::vector<const BookmarkNode*> nodes; |
| 410 bookmark_utils::GetBookmarksContainingText(model, query, | 420 bookmark_utils::GetBookmarksContainingText(profile()->GetBookmarkModel(), |
| 421 UTF8ToUTF16(params->query), | |
| 411 std::numeric_limits<int>::max(), | 422 std::numeric_limits<int>::max(), |
| 412 lang, &nodes); | 423 lang, |
| 413 std::vector<const BookmarkNode*>::iterator i = nodes.begin(); | 424 &nodes); |
| 414 for (; i != nodes.end(); ++i) { | 425 |
| 415 const BookmarkNode* node = *i; | 426 std::vector<linked_ptr<BookmarkTreeNode> > tree_nodes; |
| 416 bookmark_extension_helpers::AddNode(node, json, false); | 427 for (std::vector<const BookmarkNode*>::iterator node_iter = nodes.begin(); |
| 428 node_iter != nodes.end(); ++node_iter) { | |
| 429 bookmark_extension_helpers::AddNode(*node_iter, &tree_nodes, false); | |
| 417 } | 430 } |
| 418 | 431 |
| 419 result_.reset(json); | 432 result_.reset(Search::Result::Create(tree_nodes)); |
| 420 return true; | 433 return true; |
| 421 } | 434 } |
| 422 | 435 |
| 423 // static | 436 // static |
| 424 bool RemoveBookmarkFunction::ExtractIds(const ListValue* args, | 437 bool RemoveBookmarkFunction::ExtractIds(const ListValue* args, |
| 425 std::list<int64>* ids, | 438 std::list<int64>* ids, |
| 426 bool* invalid_id) { | 439 bool* invalid_id) { |
| 427 std::string id_string; | 440 std::string id_string; |
| 428 if (!args->GetString(0, &id_string)) | 441 if (!args->GetString(0, &id_string)) |
| 429 return false; | 442 return false; |
| 430 int64 id; | 443 int64 id; |
| 431 if (base::StringToInt64(id_string, &id)) | 444 if (base::StringToInt64(id_string, &id)) |
| 432 ids->push_back(id); | 445 ids->push_back(id); |
| 433 else | 446 else |
| 434 *invalid_id = true; | 447 *invalid_id = true; |
| 435 return true; | 448 return true; |
| 436 } | 449 } |
| 437 | 450 |
| 438 bool RemoveBookmarkFunction::RunImpl() { | 451 bool RemoveBookmarkFunction::RunImpl() { |
| 439 if (!EditBookmarksEnabled()) | 452 if (!EditBookmarksEnabled()) |
| 440 return false; | 453 return false; |
| 441 std::list<int64> ids; | 454 |
| 442 bool invalid_id = false; | 455 scoped_ptr<Remove::Params> params(Remove::Params::Create(*args_)); |
| 443 EXTENSION_FUNCTION_VALIDATE(ExtractIds(args_.get(), &ids, &invalid_id)); | 456 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 444 if (invalid_id) { | 457 |
| 458 int64 id; | |
| 459 if (!base::StringToInt64(params->id, &id)) { | |
|
Aaron Boodman
2012/07/23 23:37:57
Could add a feature to JSON Schema Compiler to kno
mitchellwrosen
2012/07/24 17:13:39
Sounds good. Separate CL though right?
| |
| 445 error_ = keys::kInvalidIdError; | 460 error_ = keys::kInvalidIdError; |
| 446 return false; | 461 return false; |
| 447 } | 462 } |
| 463 | |
| 448 bool recursive = false; | 464 bool recursive = false; |
| 449 if (name() == RemoveTreeBookmarkFunction::function_name()) | 465 if (name() == RemoveTreeBookmarkFunction::function_name()) |
| 450 recursive = true; | 466 recursive = true; |
| 451 | 467 |
| 452 BookmarkModel* model = profile()->GetBookmarkModel(); | 468 BookmarkModel* model = profile()->GetBookmarkModel(); |
| 453 size_t count = ids.size(); | 469 if (!bookmark_extension_helpers::RemoveNode(model, id, recursive, &error_)) |
| 454 EXTENSION_FUNCTION_VALIDATE(count > 0); | 470 return false; |
| 455 for (std::list<int64>::iterator it = ids.begin(); it != ids.end(); ++it) { | 471 |
| 456 if (!bookmark_extension_helpers::RemoveNode(model, *it, recursive, &error_)) | |
| 457 return false; | |
| 458 } | |
| 459 return true; | 472 return true; |
| 460 } | 473 } |
| 461 | 474 |
| 462 bool CreateBookmarkFunction::RunImpl() { | 475 bool CreateBookmarkFunction::RunImpl() { |
| 463 if (!EditBookmarksEnabled()) | 476 if (!EditBookmarksEnabled()) |
| 464 return false; | 477 return false; |
| 465 DictionaryValue* json; | 478 |
| 466 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json)); | 479 scoped_ptr<Create::Params> params(Create::Params::Create(*args_)); |
| 467 EXTENSION_FUNCTION_VALIDATE(json != NULL); | 480 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 468 | 481 |
| 469 BookmarkModel* model = profile()->GetBookmarkModel(); | 482 BookmarkModel* model = profile()->GetBookmarkModel(); |
| 470 int64 parentId; | 483 int64 parentId; |
| 471 if (!json->HasKey(keys::kParentIdKey)) { | 484 |
| 485 if (!params->bookmark.parent_id.get()) { | |
| 472 // Optional, default to "other bookmarks". | 486 // Optional, default to "other bookmarks". |
| 473 parentId = model->other_node()->id(); | 487 parentId = model->other_node()->id(); |
| 474 } else { | 488 } else { |
| 475 std::string parentId_string; | 489 if (!GetBookmarkIdAsInt64(*params->bookmark.parent_id, &parentId)) |
| 476 EXTENSION_FUNCTION_VALIDATE(json->GetString(keys::kParentIdKey, | |
| 477 &parentId_string)); | |
| 478 if (!GetBookmarkIdAsInt64(parentId_string, &parentId)) | |
| 479 return false; | 490 return false; |
| 480 } | 491 } |
| 481 const BookmarkNode* parent = model->GetNodeByID(parentId); | 492 const BookmarkNode* parent = model->GetNodeByID(parentId); |
| 482 if (!parent) { | 493 if (!parent) { |
| 483 error_ = keys::kNoParentError; | 494 error_ = keys::kNoParentError; |
| 484 return false; | 495 return false; |
| 485 } | 496 } |
| 486 if (parent->is_root()) { // Can't create children of the root. | 497 if (parent->is_root()) { // Can't create children of the root. |
| 487 error_ = keys::kModifySpecialError; | 498 error_ = keys::kModifySpecialError; |
| 488 return false; | 499 return false; |
| 489 } | 500 } |
| 490 | 501 |
| 491 int index; | 502 int index; |
| 492 if (!json->HasKey(keys::kIndexKey)) { // Optional (defaults to end). | 503 if (!params->bookmark.index.get()) { // Optional (defaults to end). |
| 493 index = parent->child_count(); | 504 index = parent->child_count(); |
| 494 } else { | 505 } else { |
| 495 EXTENSION_FUNCTION_VALIDATE(json->GetInteger(keys::kIndexKey, &index)); | 506 index = *params->bookmark.index; |
| 496 if (index > parent->child_count() || index < 0) { | 507 if (index > parent->child_count() || index < 0) { |
| 497 error_ = keys::kInvalidIndexError; | 508 error_ = keys::kInvalidIndexError; |
| 498 return false; | 509 return false; |
| 499 } | 510 } |
| 500 } | 511 } |
| 501 | 512 |
| 502 string16 title; | 513 string16 title; // Optional. |
| 503 json->GetString(keys::kTitleKey, &title); // Optional. | 514 if (params->bookmark.title.get()) |
| 504 std::string url_string; | 515 title = UTF8ToUTF16(*params->bookmark.title.get()); |
| 505 json->GetString(keys::kUrlKey, &url_string); // Optional. | 516 |
| 517 std::string url_string; // Optional. | |
| 518 if (params->bookmark.url.get()) | |
| 519 url_string = *params->bookmark.url.get(); | |
| 520 | |
| 506 GURL url(url_string); | 521 GURL url(url_string); |
| 507 if (!url.is_empty() && !url.is_valid()) { | 522 if (!url.is_empty() && !url.is_valid()) { |
| 508 error_ = keys::kInvalidUrlError; | 523 error_ = keys::kInvalidUrlError; |
| 509 return false; | 524 return false; |
| 510 } | 525 } |
| 511 | 526 |
| 512 const BookmarkNode* node; | 527 const BookmarkNode* node; |
| 513 if (url_string.length()) | 528 if (url_string.length()) |
| 514 node = model->AddURL(parent, index, title, url); | 529 node = model->AddURL(parent, index, title, url); |
| 515 else | 530 else |
| 516 node = model->AddFolder(parent, index, title); | 531 node = model->AddFolder(parent, index, title); |
| 517 DCHECK(node); | 532 DCHECK(node); |
| 518 if (!node) { | 533 if (!node) { |
| 519 error_ = keys::kNoNodeError; | 534 error_ = keys::kNoNodeError; |
| 520 return false; | 535 return false; |
| 521 } | 536 } |
| 522 | 537 |
| 523 DictionaryValue* ret = | 538 scoped_ptr<BookmarkTreeNode> ret( |
| 524 bookmark_extension_helpers::GetNodeDictionary(node, false, false); | 539 bookmark_extension_helpers::GetBookmarkTreeNode(node, false, false)); |
| 525 result_.reset(ret); | 540 result_.reset(Create::Result::Create(*ret)); |
| 526 | 541 |
| 527 return true; | 542 return true; |
| 528 } | 543 } |
| 529 | 544 |
| 530 // static | 545 // static |
| 531 bool MoveBookmarkFunction::ExtractIds(const ListValue* args, | 546 bool MoveBookmarkFunction::ExtractIds(const ListValue* args, |
| 532 std::list<int64>* ids, | 547 std::list<int64>* ids, |
| 533 bool* invalid_id) { | 548 bool* invalid_id) { |
| 534 // For now, Move accepts ID parameters in the same way as an Update. | 549 // For now, Move accepts ID parameters in the same way as an Update. |
| 535 return UpdateBookmarkFunction::ExtractIds(args, ids, invalid_id); | 550 return UpdateBookmarkFunction::ExtractIds(args, ids, invalid_id); |
| 536 } | 551 } |
| 537 | 552 |
| 538 bool MoveBookmarkFunction::RunImpl() { | 553 bool MoveBookmarkFunction::RunImpl() { |
| 539 if (!EditBookmarksEnabled()) | 554 if (!EditBookmarksEnabled()) |
| 540 return false; | 555 return false; |
| 541 std::list<int64> ids; | 556 |
| 542 bool invalid_id = false; | 557 scoped_ptr<Move::Params> params(Move::Params::Create(*args_)); |
| 543 EXTENSION_FUNCTION_VALIDATE(ExtractIds(args_.get(), &ids, &invalid_id)); | 558 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 544 if (invalid_id) { | 559 |
| 560 int64 id; | |
| 561 if (!base::StringToInt64(params->id, &id)) { | |
| 545 error_ = keys::kInvalidIdError; | 562 error_ = keys::kInvalidIdError; |
| 546 return false; | 563 return false; |
| 547 } | 564 } |
| 548 EXTENSION_FUNCTION_VALIDATE(ids.size() == 1); | |
| 549 | |
| 550 DictionaryValue* destination; | |
| 551 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &destination)); | |
| 552 | 565 |
| 553 BookmarkModel* model = profile()->GetBookmarkModel(); | 566 BookmarkModel* model = profile()->GetBookmarkModel(); |
| 554 const BookmarkNode* node = model->GetNodeByID(ids.front()); | 567 const BookmarkNode* node = model->GetNodeByID(id); |
| 555 if (!node) { | 568 if (!node) { |
| 556 error_ = keys::kNoNodeError; | 569 error_ = keys::kNoNodeError; |
| 557 return false; | 570 return false; |
| 558 } | 571 } |
| 559 if (model->is_permanent_node(node)) { | 572 if (model->is_permanent_node(node)) { |
| 560 error_ = keys::kModifySpecialError; | 573 error_ = keys::kModifySpecialError; |
| 561 return false; | 574 return false; |
| 562 } | 575 } |
| 563 | 576 |
| 564 const BookmarkNode* parent = NULL; | 577 const BookmarkNode* parent = NULL; |
| 565 if (!destination->HasKey(keys::kParentIdKey)) { | 578 if (!params->destination.parent_id.get()) { |
| 566 // Optional, defaults to current parent. | 579 // Optional, defaults to current parent. |
| 567 parent = node->parent(); | 580 parent = node->parent(); |
| 568 } else { | 581 } else { |
| 569 std::string parentId_string; | |
| 570 EXTENSION_FUNCTION_VALIDATE(destination->GetString(keys::kParentIdKey, | |
| 571 &parentId_string)); | |
| 572 int64 parentId; | 582 int64 parentId; |
| 573 if (!GetBookmarkIdAsInt64(parentId_string, &parentId)) | 583 if (!GetBookmarkIdAsInt64(*params->destination.parent_id, &parentId)) |
| 574 return false; | 584 return false; |
| 575 | 585 |
| 576 parent = model->GetNodeByID(parentId); | 586 parent = model->GetNodeByID(parentId); |
| 577 } | 587 } |
| 578 if (!parent) { | 588 if (!parent) { |
| 579 error_ = keys::kNoParentError; | 589 error_ = keys::kNoParentError; |
| 580 // TODO(erikkay) return an error message. | 590 // TODO(erikkay) return an error message. |
| 581 return false; | 591 return false; |
| 582 } | 592 } |
| 583 if (parent == model->root_node()) { | 593 if (parent == model->root_node()) { |
| 584 error_ = keys::kModifySpecialError; | 594 error_ = keys::kModifySpecialError; |
| 585 return false; | 595 return false; |
| 586 } | 596 } |
| 587 | 597 |
| 588 int index; | 598 int index; |
| 589 if (destination->HasKey(keys::kIndexKey)) { // Optional (defaults to end). | 599 if (params->destination.index.get()) { // Optional (defaults to end). |
| 590 EXTENSION_FUNCTION_VALIDATE(destination->GetInteger(keys::kIndexKey, | 600 index = *params->destination.index; |
| 591 &index)); | |
| 592 if (index > parent->child_count() || index < 0) { | 601 if (index > parent->child_count() || index < 0) { |
| 593 error_ = keys::kInvalidIndexError; | 602 error_ = keys::kInvalidIndexError; |
| 594 return false; | 603 return false; |
| 595 } | 604 } |
| 596 } else { | 605 } else { |
| 597 index = parent->child_count(); | 606 index = parent->child_count(); |
| 598 } | 607 } |
| 599 | 608 |
| 600 model->Move(node, parent, index); | 609 model->Move(node, parent, index); |
| 601 | 610 |
| 602 DictionaryValue* ret = | 611 scoped_ptr<BookmarkTreeNode> tree_node( |
| 603 bookmark_extension_helpers::GetNodeDictionary(node, false, false); | 612 bookmark_extension_helpers::GetBookmarkTreeNode(node, false, false)); |
| 604 result_.reset(ret); | 613 result_.reset(Move::Result::Create(*tree_node)); |
| 605 | 614 |
| 606 return true; | 615 return true; |
| 607 } | 616 } |
| 608 | 617 |
| 609 // static | 618 // static |
| 610 bool UpdateBookmarkFunction::ExtractIds(const ListValue* args, | 619 bool UpdateBookmarkFunction::ExtractIds(const ListValue* args, |
| 611 std::list<int64>* ids, | 620 std::list<int64>* ids, |
| 612 bool* invalid_id) { | 621 bool* invalid_id) { |
| 613 // For now, Update accepts ID parameters in the same way as an Remove. | 622 // For now, Update accepts ID parameters in the same way as an Remove. |
| 614 return RemoveBookmarkFunction::ExtractIds(args, ids, invalid_id); | 623 return RemoveBookmarkFunction::ExtractIds(args, ids, invalid_id); |
| 615 } | 624 } |
| 616 | 625 |
| 617 bool UpdateBookmarkFunction::RunImpl() { | 626 bool UpdateBookmarkFunction::RunImpl() { |
| 618 if (!EditBookmarksEnabled()) | 627 if (!EditBookmarksEnabled()) |
| 619 return false; | 628 return false; |
| 620 std::list<int64> ids; | 629 |
| 621 bool invalid_id = false; | 630 scoped_ptr<Update::Params> params(Update::Params::Create(*args_)); |
| 622 EXTENSION_FUNCTION_VALIDATE(ExtractIds(args_.get(), &ids, &invalid_id)); | 631 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 623 if (invalid_id) { | 632 |
| 633 int64 id; | |
| 634 if (!base::StringToInt64(params->id, &id)) { | |
| 624 error_ = keys::kInvalidIdError; | 635 error_ = keys::kInvalidIdError; |
| 625 return false; | 636 return false; |
| 626 } | 637 } |
| 627 EXTENSION_FUNCTION_VALIDATE(ids.size() == 1); | |
| 628 | 638 |
| 629 DictionaryValue* updates; | 639 BookmarkModel* model = profile()->GetBookmarkModel(); |
| 630 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &updates)); | |
| 631 | 640 |
| 632 // Optional but we need to distinguish non present from an empty title. | 641 // Optional but we need to distinguish non present from an empty title. |
| 633 string16 title; | 642 string16 title; |
| 634 const bool has_title = updates->GetString(keys::kTitleKey, &title); | 643 bool has_title = false; |
| 644 if (params->changes.title.get()) { | |
| 645 title = UTF8ToUTF16(*params->changes.title); | |
| 646 has_title = true; | |
| 647 } | |
| 635 | 648 |
| 636 // Optional. | 649 // Optional. |
| 637 std::string url_string; | 650 std::string url_string; |
| 638 updates->GetString(keys::kUrlKey, &url_string); | 651 if (params->changes.url.get()) |
| 652 url_string = *params->changes.url; | |
| 639 GURL url(url_string); | 653 GURL url(url_string); |
| 640 if (!url_string.empty() && !url.is_valid()) { | 654 if (!url_string.empty() && !url.is_valid()) { |
| 641 error_ = keys::kInvalidUrlError; | 655 error_ = keys::kInvalidUrlError; |
| 642 return false; | 656 return false; |
| 643 } | 657 } |
| 644 | 658 |
| 645 BookmarkModel* model = profile()->GetBookmarkModel(); | 659 const BookmarkNode* node = model->GetNodeByID(id); |
| 646 const BookmarkNode* node = model->GetNodeByID(ids.front()); | |
| 647 if (!node) { | 660 if (!node) { |
| 648 error_ = keys::kNoNodeError; | 661 error_ = keys::kNoNodeError; |
| 649 return false; | 662 return false; |
| 650 } | 663 } |
| 651 if (model->is_permanent_node(node)) { | 664 if (model->is_permanent_node(node)) { |
| 652 error_ = keys::kModifySpecialError; | 665 error_ = keys::kModifySpecialError; |
| 653 return false; | 666 return false; |
| 654 } | 667 } |
| 655 if (has_title) | 668 if (has_title) |
| 656 model->SetTitle(node, title); | 669 model->SetTitle(node, title); |
| 657 if (!url.is_empty()) | 670 if (!url.is_empty()) |
| 658 model->SetURL(node, url); | 671 model->SetURL(node, url); |
| 659 | 672 |
| 660 DictionaryValue* ret = | 673 scoped_ptr<BookmarkTreeNode> tree_node( |
| 661 bookmark_extension_helpers::GetNodeDictionary(node, false, false); | 674 bookmark_extension_helpers::GetBookmarkTreeNode(node, false, false)); |
| 662 result_.reset(ret); | 675 result_.reset(Update::Result::Create(*tree_node)); |
| 663 | 676 |
| 664 return true; | 677 return true; |
| 665 } | 678 } |
| 666 | 679 |
| 667 // Mapper superclass for BookmarkFunctions. | 680 // Mapper superclass for BookmarkFunctions. |
| 668 template <typename BucketIdType> | 681 template <typename BucketIdType> |
| 669 class BookmarkBucketMapper : public BucketMapper { | 682 class BookmarkBucketMapper : public BucketMapper { |
| 670 public: | 683 public: |
| 671 virtual ~BookmarkBucketMapper() { STLDeleteValues(&buckets_); } | 684 virtual ~BookmarkBucketMapper() { STLDeleteValues(&buckets_); } |
| 672 protected: | 685 protected: |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 int index, | 958 int index, |
| 946 void* params) { | 959 void* params) { |
| 947 #if !defined(OS_ANDROID) | 960 #if !defined(OS_ANDROID) |
| 948 // Android does not have support for the standard exporter. | 961 // Android does not have support for the standard exporter. |
| 949 // TODO(jgreenwald): remove ifdef once extensions are no longer built on | 962 // TODO(jgreenwald): remove ifdef once extensions are no longer built on |
| 950 // Android. | 963 // Android. |
| 951 bookmark_html_writer::WriteBookmarks(profile(), path, NULL); | 964 bookmark_html_writer::WriteBookmarks(profile(), path, NULL); |
| 952 #endif | 965 #endif |
| 953 Release(); // Balanced in BookmarksIOFunction::SelectFile() | 966 Release(); // Balanced in BookmarksIOFunction::SelectFile() |
| 954 } | 967 } |
| OLD | NEW |