| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2009 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/cookies_tree_model.h" |
| 6 |
| 7 #include <algorithm> |
| 8 #include <functional> |
| 9 #include <vector> |
| 10 |
| 11 #include "app/l10n_util.h" |
| 12 #include "app/resource_bundle.h" |
| 13 #include "app/table_model_observer.h" |
| 14 #include "app/tree_node_model.h" |
| 15 #include "base/linked_ptr.h" |
| 16 #include "base/string_util.h" |
| 17 #include "chrome/browser/net/chrome_url_request_context.h" |
| 18 #include "chrome/browser/profile.h" |
| 19 #include "grit/app_resources.h" |
| 20 #include "grit/generated_resources.h" |
| 21 #include "grit/theme_resources.h" |
| 22 #include "net/base/cookie_monster.h" |
| 23 #include "net/url_request/url_request_context.h" |
| 24 #include "third_party/skia/include/core/SkBitmap.h" |
| 25 |
| 26 |
| 27 /////////////////////////////////////////////////////////////////////////////// |
| 28 // CookieTreeNode, public: |
| 29 |
| 30 void CookieTreeNode::DeleteStoredObjects() { |
| 31 std::for_each(children().begin(), |
| 32 children().end(), |
| 33 std::mem_fun(&CookieTreeNode::DeleteStoredObjects)); |
| 34 } |
| 35 |
| 36 CookiesTreeModel* CookieTreeNode::GetModel() const { |
| 37 if (GetParent()) |
| 38 return GetParent()->GetModel(); |
| 39 else |
| 40 return NULL; |
| 41 } |
| 42 |
| 43 /////////////////////////////////////////////////////////////////////////////// |
| 44 // CookieTreeCookieNode, public: |
| 45 |
| 46 CookieTreeCookieNode::CookieTreeCookieNode( |
| 47 net::CookieMonster::CookieListPair* cookie) |
| 48 : CookieTreeNode(UTF8ToWide(cookie->second.Name())), |
| 49 cookie_(cookie) { |
| 50 } |
| 51 |
| 52 void CookieTreeCookieNode::DeleteStoredObjects() { |
| 53 GetModel()->DeleteCookie(*cookie_); |
| 54 } |
| 55 |
| 56 namespace { |
| 57 // comparison functor, for use in CookieTreeRootNode |
| 58 class OriginNodeComparator { |
| 59 public: |
| 60 bool operator() (const CookieTreeNode* lhs, |
| 61 const CookieTreeNode* rhs) { |
| 62 return (lhs->GetTitle() < rhs->GetTitle()); |
| 63 } |
| 64 }; |
| 65 |
| 66 } // namespace |
| 67 |
| 68 /////////////////////////////////////////////////////////////////////////////// |
| 69 // CookieTreeRootNode, public: |
| 70 CookieTreeOriginNode* CookieTreeRootNode::GetOrCreateOriginNode( |
| 71 const std::wstring& origin) { |
| 72 // Strip the trailing dot if it exists. |
| 73 std::wstring rewritten_origin = origin; |
| 74 if (origin.length() >= 1 && origin[0] == '.') |
| 75 rewritten_origin = origin.substr(1); |
| 76 |
| 77 CookieTreeOriginNode rewritten_origin_node(rewritten_origin); |
| 78 |
| 79 // First see if there is an existing match. |
| 80 std::vector<CookieTreeNode*>::iterator origin_node_iterator = |
| 81 lower_bound(children().begin(), |
| 82 children().end(), |
| 83 &rewritten_origin_node, |
| 84 OriginNodeComparator()); |
| 85 |
| 86 if (origin_node_iterator != children().end() && rewritten_origin == |
| 87 (*origin_node_iterator)->GetTitle()) |
| 88 return static_cast<CookieTreeOriginNode*>(*origin_node_iterator); |
| 89 // Node doesn't exist, create a new one and insert it into the (ordered) |
| 90 // children. |
| 91 CookieTreeOriginNode* retval = new CookieTreeOriginNode(rewritten_origin); |
| 92 DCHECK(model_); |
| 93 model_->Add(this, (origin_node_iterator - children().begin()), retval); |
| 94 return retval; |
| 95 } |
| 96 |
| 97 /////////////////////////////////////////////////////////////////////////////// |
| 98 // CookieTreeOriginNode, public: |
| 99 |
| 100 CookieTreeCookiesNode* CookieTreeOriginNode::GetOrCreateCookiesNode() { |
| 101 if (cookies_child_) |
| 102 return cookies_child_; |
| 103 // need to make a Cookies node, add it to the tree, and return it |
| 104 CookieTreeCookiesNode* retval = new CookieTreeCookiesNode; |
| 105 GetModel()->Add(this, 0, retval); |
| 106 cookies_child_ = retval; |
| 107 return retval; |
| 108 } |
| 109 |
| 110 /////////////////////////////////////////////////////////////////////////////// |
| 111 // CookieTreeCookiesNode, public: |
| 112 |
| 113 CookieTreeCookiesNode::CookieTreeCookiesNode() |
| 114 : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_COOKIES)) {} |
| 115 |
| 116 |
| 117 void CookieTreeCookiesNode::AddCookieNode( |
| 118 CookieTreeCookieNode* new_child) { |
| 119 std::vector<CookieTreeNode*>::iterator cookie_iterator = |
| 120 lower_bound(children().begin(), |
| 121 children().end(), |
| 122 new_child, |
| 123 CookieTreeCookieNode::CookieNodeComparator()); |
| 124 GetModel()->Add(this, (cookie_iterator - children().begin()), new_child); |
| 125 } |
| 126 |
| 127 /////////////////////////////////////////////////////////////////////////////// |
| 128 // CookieTreeCookieNode, private |
| 129 |
| 130 bool CookieTreeCookieNode::CookieNodeComparator::operator() ( |
| 131 const CookieTreeNode* lhs, const CookieTreeNode* rhs) { |
| 132 return (static_cast<const CookieTreeCookieNode*>(lhs)-> |
| 133 cookie_->second.Name() < |
| 134 static_cast<const CookieTreeCookieNode*>(rhs)-> |
| 135 cookie_->second.Name()); |
| 136 } |
| 137 |
| 138 /////////////////////////////////////////////////////////////////////////////// |
| 139 // CookiesTreeModel, public: |
| 140 |
| 141 CookiesTreeModel::CookiesTreeModel(Profile* profile) |
| 142 : ALLOW_THIS_IN_INITIALIZER_LIST(TreeNodeModel<CookieTreeNode>( |
| 143 new CookieTreeRootNode(this))), |
| 144 profile_(profile) { |
| 145 LoadCookies(); |
| 146 } |
| 147 |
| 148 /////////////////////////////////////////////////////////////////////////////// |
| 149 // CookiesTreeModel, TreeModel methods (public): |
| 150 |
| 151 // TreeModel methods: |
| 152 // Returns the set of icons for the nodes in the tree. You only need override |
| 153 // this if you don't want to use the default folder icons. |
| 154 void CookiesTreeModel::GetIcons(std::vector<SkBitmap>* icons) { |
| 155 icons->push_back(*ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 156 IDR_DEFAULT_FAVICON)); |
| 157 icons->push_back(*ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 158 IDR_COOKIE_ICON)); |
| 159 } |
| 160 |
| 161 // Returns the index of the icon to use for |node|. Return -1 to use the |
| 162 // default icon. The index is relative to the list of icons returned from |
| 163 // GetIcons. |
| 164 int CookiesTreeModel::GetIconIndex(TreeModelNode* node) { |
| 165 CookieTreeNode* ct_node = static_cast<CookieTreeNode*>(node); |
| 166 switch (ct_node->GetDetailedInfo().node_type) { |
| 167 case CookieTreeNode::DetailedInfo::TYPE_ORIGIN: |
| 168 return ORIGIN; |
| 169 break; |
| 170 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: |
| 171 return COOKIE; |
| 172 break; |
| 173 default: |
| 174 return -1; |
| 175 } |
| 176 } |
| 177 |
| 178 void CookiesTreeModel::LoadCookies() { |
| 179 // mmargh mmargh mmargh! |
| 180 |
| 181 // Since we are running on the UI thread don't call GetURLRequestContext(). |
| 182 net::CookieMonster* cookie_monster = |
| 183 profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(); |
| 184 |
| 185 all_cookies_ = cookie_monster->GetAllCookies(); |
| 186 CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); |
| 187 for (CookieList::iterator it = all_cookies_.begin(); |
| 188 it != all_cookies_.end(); |
| 189 ++it) { |
| 190 // Get the origin cookie |
| 191 CookieTreeOriginNode* origin = |
| 192 root->GetOrCreateOriginNode(UTF8ToWide(it->first)); |
| 193 CookieTreeCookiesNode* cookies_node = origin->GetOrCreateCookiesNode(); |
| 194 CookieTreeCookieNode* new_cookie = new CookieTreeCookieNode(&*it); |
| 195 cookies_node->AddCookieNode(new_cookie); |
| 196 } |
| 197 } |
| 198 |
| 199 void CookiesTreeModel::DeleteCookie( |
| 200 const net::CookieMonster::CookieListPair& cookie) { |
| 201 // notify CookieMonster that we should delete this cookie |
| 202 // Since we are running on the UI thread don't call GetURLRequestContext(). |
| 203 net::CookieMonster* monster = |
| 204 profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(); |
| 205 // We have stored a copy of all the cookies in the model, and our model is |
| 206 // never re-calculated. Thus, we just need to delete the nodes from our |
| 207 // model, and tell CookieMonster to delete the cookies. We can keep the |
| 208 // vector storing the cookies in-tact and not delete from there (that would |
| 209 // invalidate our pointers), and the fact that it contains semi out-of-date |
| 210 // data is not problematic as we don't re-build the model based on that. |
| 211 monster->DeleteCookie(cookie.first, cookie.second, true); |
| 212 } |
| 213 |
| 214 void CookiesTreeModel::DeleteAllCookies() { |
| 215 CookieTreeNode* root = GetRoot(); |
| 216 root->DeleteStoredObjects(); |
| 217 int num_children = root->GetChildCount(); |
| 218 for (int i = num_children - 1; i >= 0; --i) { |
| 219 delete Remove(root, i); |
| 220 } |
| 221 LoadCookies(); |
| 222 NotifyObserverTreeNodeChanged(root); |
| 223 } |
| 224 |
| 225 void CookiesTreeModel::DeleteCookieNode(CookieTreeCookieNode* cookie_node) { |
| 226 cookie_node->DeleteStoredObjects(); |
| 227 // find the parent and index |
| 228 CookieTreeNode* parent_node = cookie_node->GetParent(); |
| 229 int cookie_node_index = parent_node->IndexOfChild(cookie_node); |
| 230 delete Remove(parent_node, cookie_node_index); |
| 231 } |
| OLD | NEW |