Home | History | Annotate | Download | only in bookmarks
      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/bookmarks/bookmark_api_helpers.h"
      6 
      7 #include <math.h>  // For floor()
      8 #include <vector>
      9 
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
     13 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
     14 #include "chrome/common/extensions/api/bookmarks.h"
     15 #include "components/bookmarks/browser/bookmark_model.h"
     16 #include "components/bookmarks/browser/bookmark_utils.h"
     17 
     18 namespace extensions {
     19 
     20 namespace keys = bookmark_api_constants;
     21 using api::bookmarks::BookmarkTreeNode;
     22 
     23 namespace bookmark_api_helpers {
     24 
     25 namespace {
     26 
     27 void AddNodeHelper(ChromeBookmarkClient* client,
     28                    const BookmarkNode* node,
     29                    std::vector<linked_ptr<BookmarkTreeNode> >* nodes,
     30                    bool recurse,
     31                    bool only_folders) {
     32   if (node->IsVisible()) {
     33     linked_ptr<BookmarkTreeNode> new_node(GetBookmarkTreeNode(client,
     34                                                               node,
     35                                                               recurse,
     36                                                               only_folders));
     37     nodes->push_back(new_node);
     38   }
     39 }
     40 
     41 }  // namespace
     42 
     43 BookmarkTreeNode* GetBookmarkTreeNode(ChromeBookmarkClient* client,
     44                                       const BookmarkNode* node,
     45                                       bool recurse,
     46                                       bool only_folders) {
     47   BookmarkTreeNode* bookmark_tree_node = new BookmarkTreeNode;
     48 
     49   bookmark_tree_node->id = base::Int64ToString(node->id());
     50 
     51   const BookmarkNode* parent = node->parent();
     52   if (parent) {
     53     bookmark_tree_node->parent_id.reset(new std::string(
     54         base::Int64ToString(parent->id())));
     55     bookmark_tree_node->index.reset(new int(parent->GetIndexOf(node)));
     56   }
     57 
     58   if (!node->is_folder()) {
     59     bookmark_tree_node->url.reset(new std::string(node->url().spec()));
     60   } else {
     61     // Javascript Date wants milliseconds since the epoch, ToDoubleT is seconds.
     62     base::Time t = node->date_folder_modified();
     63     if (!t.is_null()) {
     64       bookmark_tree_node->date_group_modified.reset(
     65           new double(floor(t.ToDoubleT() * 1000)));
     66     }
     67   }
     68 
     69   bookmark_tree_node->title = base::UTF16ToUTF8(node->GetTitle());
     70   if (!node->date_added().is_null()) {
     71     // Javascript Date wants milliseconds since the epoch, ToDoubleT is seconds.
     72     bookmark_tree_node->date_added.reset(
     73         new double(floor(node->date_added().ToDoubleT() * 1000)));
     74   }
     75 
     76   if (client->IsDescendantOfManagedNode(node))
     77     bookmark_tree_node->unmodifiable = BookmarkTreeNode::UNMODIFIABLE_MANAGED;
     78 
     79   if (recurse && node->is_folder()) {
     80     std::vector<linked_ptr<BookmarkTreeNode> > children;
     81     for (int i = 0; i < node->child_count(); ++i) {
     82       const BookmarkNode* child = node->GetChild(i);
     83       if (child->IsVisible() && (!only_folders || child->is_folder())) {
     84         linked_ptr<BookmarkTreeNode> child_node(
     85             GetBookmarkTreeNode(client, child, true, only_folders));
     86         children.push_back(child_node);
     87       }
     88     }
     89     bookmark_tree_node->children.reset(
     90         new std::vector<linked_ptr<BookmarkTreeNode> >(children));
     91   }
     92   return bookmark_tree_node;
     93 }
     94 
     95 void AddNode(ChromeBookmarkClient* client,
     96              const BookmarkNode* node,
     97              std::vector<linked_ptr<BookmarkTreeNode> >* nodes,
     98              bool recurse) {
     99   return AddNodeHelper(client, node, nodes, recurse, false);
    100 }
    101 
    102 void AddNodeFoldersOnly(ChromeBookmarkClient* client,
    103                         const BookmarkNode* node,
    104                         std::vector<linked_ptr<BookmarkTreeNode> >* nodes,
    105                         bool recurse) {
    106   return AddNodeHelper(client, node, nodes, recurse, true);
    107 }
    108 
    109 bool RemoveNode(BookmarkModel* model,
    110                 ChromeBookmarkClient* client,
    111                 int64 id,
    112                 bool recursive,
    113                 std::string* error) {
    114   const BookmarkNode* node = GetBookmarkNodeByID(model, id);
    115   if (!node) {
    116     *error = keys::kNoNodeError;
    117     return false;
    118   }
    119   if (model->is_permanent_node(node)) {
    120     *error = keys::kModifySpecialError;
    121     return false;
    122   }
    123   if (client->IsDescendantOfManagedNode(node)) {
    124     *error = keys::kModifyManagedError;
    125     return false;
    126   }
    127   if (node->is_folder() && !node->empty() && !recursive) {
    128     *error = keys::kFolderNotEmptyError;
    129     return false;
    130   }
    131 
    132   const BookmarkNode* parent = node->parent();
    133   model->Remove(parent, parent->GetIndexOf(node));
    134   return true;
    135 }
    136 
    137 void GetMetaInfo(const BookmarkNode& node,
    138                  base::DictionaryValue* id_to_meta_info_map) {
    139   if (!node.IsVisible())
    140     return;
    141 
    142   const BookmarkNode::MetaInfoMap* meta_info = node.GetMetaInfoMap();
    143   base::DictionaryValue* value = new base::DictionaryValue();
    144   if (meta_info) {
    145     BookmarkNode::MetaInfoMap::const_iterator itr;
    146     for (itr = meta_info->begin(); itr != meta_info->end(); ++itr) {
    147       value->SetStringWithoutPathExpansion(itr->first, itr->second);
    148     }
    149   }
    150   id_to_meta_info_map->Set(base::Int64ToString(node.id()), value);
    151 
    152   if (node.is_folder()) {
    153     for (int i = 0; i < node.child_count(); ++i) {
    154       GetMetaInfo(*(node.GetChild(i)), id_to_meta_info_map);
    155     }
    156   }
    157 }
    158 
    159 }  // namespace bookmark_api_helpers
    160 }  // namespace extensions
    161