| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/bookmarks/browser/bookmark_utils.h" | 5 #include "components/bookmarks/browser/bookmark_utils.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 MakeTitleUnique(model, | 306 MakeTitleUnique(model, |
| 307 parent, | 307 parent, |
| 308 bookmark_data.elements[0].url, | 308 bookmark_data.elements[0].url, |
| 309 &bookmark_data.elements[0].title); | 309 &bookmark_data.elements[0].title); |
| 310 } | 310 } |
| 311 | 311 |
| 312 CloneBookmarkNode(model, bookmark_data.elements, parent, index, true); | 312 CloneBookmarkNode(model, bookmark_data.elements, parent, index, true); |
| 313 } | 313 } |
| 314 | 314 |
| 315 bool CanPasteFromClipboard(BookmarkModel* model, const BookmarkNode* node) { | 315 bool CanPasteFromClipboard(BookmarkModel* model, const BookmarkNode* node) { |
| 316 if (!node || !model->client()->CanBeEditedByUser(node)) | 316 if (!node || !model->CanBeEditedByUser(node)) |
| 317 return false; | 317 return false; |
| 318 return (BookmarkNodeData::ClipboardContainsBookmarks() || | 318 return (BookmarkNodeData::ClipboardContainsBookmarks() || |
| 319 GetUrlFromClipboard().is_valid()); | 319 GetUrlFromClipboard().is_valid()); |
| 320 } | 320 } |
| 321 | 321 |
| 322 std::vector<const BookmarkNode*> GetMostRecentlyModifiedUserFolders( | 322 std::vector<const BookmarkNode*> GetMostRecentlyModifiedUserFolders( |
| 323 BookmarkModel* model, | 323 BookmarkModel* model, |
| 324 size_t max_count) { | 324 size_t max_count) { |
| 325 std::vector<const BookmarkNode*> nodes; | 325 std::vector<const BookmarkNode*> nodes; |
| 326 ui::TreeNodeIterator<const BookmarkNode> iterator( | 326 ui::TreeNodeIterator<const BookmarkNode> iterator( |
| 327 model->root_node(), base::Bind(&PruneInvisibleFolders)); | 327 model->root_node(), base::Bind(&PruneInvisibleFolders)); |
| 328 | 328 |
| 329 while (iterator.has_next()) { | 329 while (iterator.has_next()) { |
| 330 const BookmarkNode* parent = iterator.Next(); | 330 const BookmarkNode* parent = iterator.Next(); |
| 331 if (!model->client()->CanBeEditedByUser(parent)) | 331 if (!model->CanBeEditedByUser(parent)) |
| 332 continue; | 332 continue; |
| 333 if (parent->is_folder() && parent->date_folder_modified() > Time()) { | 333 if (parent->is_folder() && parent->date_folder_modified() > Time()) { |
| 334 if (max_count == 0) { | 334 if (max_count == 0) { |
| 335 nodes.push_back(parent); | 335 nodes.push_back(parent); |
| 336 } else { | 336 } else { |
| 337 std::vector<const BookmarkNode*>::iterator i = | 337 std::vector<const BookmarkNode*>::iterator i = |
| 338 std::upper_bound(nodes.begin(), nodes.end(), parent, | 338 std::upper_bound(nodes.begin(), nodes.end(), parent, |
| 339 &MoreRecentlyModified); | 339 &MoreRecentlyModified); |
| 340 if (nodes.size() < max_count || i != nodes.end()) { | 340 if (nodes.size() < max_count || i != nodes.end()) { |
| 341 nodes.insert(i, parent); | 341 nodes.insert(i, parent); |
| 342 while (nodes.size() > max_count) | 342 while (nodes.size() > max_count) |
| 343 nodes.pop_back(); | 343 nodes.pop_back(); |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 } // else case, the root node, which we don't care about or imported nodes | 346 } // else case, the root node, which we don't care about or imported nodes |
| 347 // (which have a time of 0). | 347 // (which have a time of 0). |
| 348 } | 348 } |
| 349 | 349 |
| 350 if (nodes.size() < max_count) { | 350 if (nodes.size() < max_count) { |
| 351 // Add the permanent nodes if there is space. The permanent nodes are the | 351 // Add the permanent nodes if there is space. The permanent nodes are the |
| 352 // only children of the root_node. | 352 // only children of the root_node. |
| 353 const BookmarkNode* root_node = model->root_node(); | 353 const BookmarkNode* root_node = model->root_node(); |
| 354 | 354 |
| 355 for (int i = 0; i < root_node->child_count(); ++i) { | 355 for (int i = 0; i < root_node->child_count(); ++i) { |
| 356 const BookmarkNode* node = root_node->GetChild(i); | 356 const BookmarkNode* node = root_node->GetChild(i); |
| 357 if (node->IsVisible() && model->client()->CanBeEditedByUser(node) && | 357 if (node->IsVisible() && model->CanBeEditedByUser(node) && |
| 358 std::find(nodes.begin(), nodes.end(), node) == nodes.end()) { | 358 std::find(nodes.begin(), nodes.end(), node) == nodes.end()) { |
| 359 nodes.push_back(node); | 359 nodes.push_back(node); |
| 360 | 360 |
| 361 if (nodes.size() == max_count) | 361 if (nodes.size() == max_count) |
| 362 break; | 362 break; |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 } | 365 } |
| 366 return nodes; | 366 return nodes; |
| 367 } | 367 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 continue; | 474 continue; |
| 475 model->Remove(node); | 475 model->Remove(node); |
| 476 } | 476 } |
| 477 } | 477 } |
| 478 | 478 |
| 479 void AddIfNotBookmarked(BookmarkModel* model, | 479 void AddIfNotBookmarked(BookmarkModel* model, |
| 480 const GURL& url, | 480 const GURL& url, |
| 481 const base::string16& title) { | 481 const base::string16& title) { |
| 482 if (IsBookmarkedByUser(model, url)) | 482 if (IsBookmarkedByUser(model, url)) |
| 483 return; // Nothing to do, a user bookmark with that url already exists. | 483 return; // Nothing to do, a user bookmark with that url already exists. |
| 484 model->client()->RecordAction(base::UserMetricsAction("BookmarkAdded")); | 484 model->RecordAction(base::UserMetricsAction("BookmarkAdded")); |
| 485 const BookmarkNode* parent = model->GetParentForNewNodes(); | 485 const BookmarkNode* parent = model->GetParentForNewNodes(); |
| 486 model->AddURL(parent, parent->child_count(), title, url); | 486 model->AddURL(parent, parent->child_count(), title, url); |
| 487 } | 487 } |
| 488 | 488 |
| 489 void RemoveAllBookmarks(BookmarkModel* model, const GURL& url) { | 489 void RemoveAllBookmarks(BookmarkModel* model, const GURL& url) { |
| 490 std::vector<const BookmarkNode*> bookmarks; | 490 std::vector<const BookmarkNode*> bookmarks; |
| 491 model->GetNodesByURL(url, &bookmarks); | 491 model->GetNodesByURL(url, &bookmarks); |
| 492 | 492 |
| 493 // Remove all the user bookmarks. | 493 // Remove all the user bookmarks. |
| 494 for (size_t i = 0; i < bookmarks.size(); ++i) { | 494 for (size_t i = 0; i < bookmarks.size(); ++i) { |
| 495 const BookmarkNode* node = bookmarks[i]; | 495 const BookmarkNode* node = bookmarks[i]; |
| 496 int index = node->parent()->GetIndexOf(node); | 496 int index = node->parent()->GetIndexOf(node); |
| 497 if (index > -1 && model->client()->CanBeEditedByUser(node)) | 497 if (index > -1 && model->CanBeEditedByUser(node)) |
| 498 model->Remove(node); | 498 model->Remove(node); |
| 499 } | 499 } |
| 500 } | 500 } |
| 501 | 501 |
| 502 base::string16 CleanUpUrlForMatching( | 502 base::string16 CleanUpUrlForMatching( |
| 503 const GURL& gurl, | 503 const GURL& gurl, |
| 504 const std::string& languages, | 504 const std::string& languages, |
| 505 base::OffsetAdjuster::Adjustments* adjustments) { | 505 base::OffsetAdjuster::Adjustments* adjustments) { |
| 506 base::OffsetAdjuster::Adjustments tmp_adjustments; | 506 base::OffsetAdjuster::Adjustments tmp_adjustments; |
| 507 return base::i18n::ToLower(net::FormatUrlWithAdjustments( | 507 return base::i18n::ToLower(net::FormatUrlWithAdjustments( |
| 508 GURL(TruncateUrl(gurl.spec())), languages, | 508 GURL(TruncateUrl(gurl.spec())), languages, |
| 509 net::kFormatUrlOmitUsernamePassword, | 509 net::kFormatUrlOmitUsernamePassword, |
| 510 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS, | 510 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS, |
| 511 NULL, NULL, adjustments ? adjustments : &tmp_adjustments)); | 511 NULL, NULL, adjustments ? adjustments : &tmp_adjustments)); |
| 512 } | 512 } |
| 513 | 513 |
| 514 base::string16 CleanUpTitleForMatching(const base::string16& title) { | 514 base::string16 CleanUpTitleForMatching(const base::string16& title) { |
| 515 return base::i18n::ToLower(title.substr(0u, kCleanedUpTitleMaxLength)); | 515 return base::i18n::ToLower(title.substr(0u, kCleanedUpTitleMaxLength)); |
| 516 } | 516 } |
| 517 | 517 |
| 518 bool CanAllBeEditedByUser(BookmarkClient* client, | 518 bool CanAllBeEditedByUser(BookmarkModel* model, |
| 519 const std::vector<const BookmarkNode*>& nodes) { | 519 const std::vector<const BookmarkNode*>& nodes) { |
| 520 for (size_t i = 0; i < nodes.size(); ++i) { | 520 for (size_t i = 0; i < nodes.size(); ++i) { |
| 521 if (!client->CanBeEditedByUser(nodes[i])) | 521 if (!model->CanBeEditedByUser(nodes[i])) |
| 522 return false; | 522 return false; |
| 523 } | 523 } |
| 524 return true; | 524 return true; |
| 525 } | 525 } |
| 526 | 526 |
| 527 bool IsBookmarkedByUser(BookmarkModel* model, const GURL& url) { | 527 bool IsBookmarkedByUser(BookmarkModel* model, const GURL& url) { |
| 528 std::vector<const BookmarkNode*> nodes; | 528 std::vector<const BookmarkNode*> nodes; |
| 529 model->GetNodesByURL(url, &nodes); | 529 model->GetNodesByURL(url, &nodes); |
| 530 for (size_t i = 0; i < nodes.size(); ++i) { | 530 for (size_t i = 0; i < nodes.size(); ++i) { |
| 531 if (model->client()->CanBeEditedByUser(nodes[i])) | 531 if (model->CanBeEditedByUser(nodes[i])) |
| 532 return true; | 532 return true; |
| 533 } | 533 } |
| 534 return false; | 534 return false; |
| 535 } | 535 } |
| 536 | 536 |
| 537 const BookmarkNode* GetBookmarkNodeByID(const BookmarkModel* model, int64 id) { | 537 const BookmarkNode* GetBookmarkNodeByID(const BookmarkModel* model, int64 id) { |
| 538 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. | 538 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. |
| 539 return GetNodeByID(model->root_node(), id); | 539 return GetNodeByID(model->root_node(), id); |
| 540 } | 540 } |
| 541 | 541 |
| 542 bool IsDescendantOf(const BookmarkNode* node, const BookmarkNode* root) { | 542 bool IsDescendantOf(const BookmarkNode* node, const BookmarkNode* root) { |
| 543 return node && node->HasAncestor(root); | 543 return node && node->HasAncestor(root); |
| 544 } | 544 } |
| 545 | 545 |
| 546 bool HasDescendantsOf(const std::vector<const BookmarkNode*>& list, | 546 bool HasDescendantsOf(const std::vector<const BookmarkNode*>& list, |
| 547 const BookmarkNode* root) { | 547 const BookmarkNode* root) { |
| 548 for (const BookmarkNode* node : list) { | 548 for (const BookmarkNode* node : list) { |
| 549 if (IsDescendantOf(node, root)) | 549 if (IsDescendantOf(node, root)) |
| 550 return true; | 550 return true; |
| 551 } | 551 } |
| 552 return false; | 552 return false; |
| 553 } | 553 } |
| 554 | 554 |
| 555 } // namespace bookmarks | 555 } // namespace bookmarks |
| OLD | NEW |