1// Copyright (c) 2011 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/ui/webui/options/cookies_view_handler.h"
6
7#include "base/utf_string_conversions.h"
8#include "base/values.h"
9#include "chrome/browser/browsing_data_appcache_helper.h"
10#include "chrome/browser/browsing_data_database_helper.h"
11#include "chrome/browser/browsing_data_indexed_db_helper.h"
12#include "chrome/browser/browsing_data_local_storage_helper.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/browser/ui/webui/cookies_tree_model_util.h"
15#include "grit/generated_resources.h"
16#include "ui/base/l10n/l10n_util.h"
17
18CookiesViewHandler::CookiesViewHandler() : batch_update_(false) {
19}
20
21CookiesViewHandler::~CookiesViewHandler() {
22}
23
24void CookiesViewHandler::GetLocalizedValues(
25    DictionaryValue* localized_strings) {
26  DCHECK(localized_strings);
27
28  static OptionsStringResource resources[] = {
29    { "label_cookie_name", IDS_COOKIES_COOKIE_NAME_LABEL },
30    { "label_cookie_content", IDS_COOKIES_COOKIE_CONTENT_LABEL },
31    { "label_cookie_domain", IDS_COOKIES_COOKIE_DOMAIN_LABEL },
32    { "label_cookie_path", IDS_COOKIES_COOKIE_PATH_LABEL },
33    { "label_cookie_send_for", IDS_COOKIES_COOKIE_SENDFOR_LABEL },
34    { "label_cookie_accessible_to_script",
35      IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_LABEL },
36    { "label_cookie_created", IDS_COOKIES_COOKIE_CREATED_LABEL },
37    { "label_cookie_expires", IDS_COOKIES_COOKIE_EXPIRES_LABEL },
38    { "label_webdb_desc", IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL },
39    { "label_local_storage_size",
40      IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL },
41    { "label_local_storage_last_modified",
42      IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL },
43    { "label_local_storage_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL },
44    { "label_indexed_db_size", IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL },
45    { "label_indexed_db_last_modified",
46      IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL },
47    { "label_indexed_db_origin", IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL },
48    { "label_app_cache_manifest",
49      IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL },
50    { "label_cookie_last_accessed", IDS_COOKIES_LAST_ACCESSED_LABEL },
51    { "cookie_domain", IDS_COOKIES_DOMAIN_COLUMN_HEADER },
52    { "cookie_local_data", IDS_COOKIES_DATA_COLUMN_HEADER },
53    { "cookie_singular", IDS_COOKIES_SINGLE_COOKIE },
54    { "cookie_plural", IDS_COOKIES_PLURAL_COOKIES },
55    { "cookie_database_storage", IDS_COOKIES_DATABASE_STORAGE },
56    { "cookie_indexed_db", IDS_COOKIES_INDEXED_DB },
57    { "cookie_local_storage", IDS_COOKIES_LOCAL_STORAGE },
58    { "cookie_session_storage", IDS_COOKIES_SESSION_STORAGE },
59    { "remove_cookie", IDS_COOKIES_REMOVE_LABEL },
60    { "remove_all_cookie", IDS_COOKIES_REMOVE_ALL_LABEL },
61  };
62
63  RegisterStrings(localized_strings, resources, arraysize(resources));
64  RegisterTitle(localized_strings, "cookiesViewPage",
65                IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE);
66}
67
68void CookiesViewHandler::RegisterMessages() {
69  web_ui_->RegisterMessageCallback("updateCookieSearchResults",
70      NewCallback(this, &CookiesViewHandler::UpdateSearchResults));
71  web_ui_->RegisterMessageCallback("removeAllCookies",
72      NewCallback(this, &CookiesViewHandler::RemoveAll));
73  web_ui_->RegisterMessageCallback("removeCookie",
74      NewCallback(this, &CookiesViewHandler::Remove));
75  web_ui_->RegisterMessageCallback("loadCookie",
76      NewCallback(this, &CookiesViewHandler::LoadChildren));
77}
78
79void CookiesViewHandler::TreeNodesAdded(ui::TreeModel* model,
80                                        ui::TreeModelNode* parent,
81                                        int start,
82                                        int count) {
83  // Skip if there is a batch update in progress.
84  if (batch_update_)
85    return;
86
87  CookieTreeNode* parent_node = cookies_tree_model_->AsNode(parent);
88
89  ListValue* children = new ListValue;
90  cookies_tree_model_util::GetChildNodeList(parent_node, start, count,
91                                            children);
92
93  ListValue args;
94  args.Append(parent == cookies_tree_model_->GetRoot() ?
95      Value::CreateNullValue() :
96      Value::CreateStringValue(
97          cookies_tree_model_util::GetTreeNodeId(parent_node)));
98  args.Append(Value::CreateIntegerValue(start));
99  args.Append(children);
100  web_ui_->CallJavascriptFunction("CookiesView.onTreeItemAdded", args);
101}
102
103void CookiesViewHandler::TreeNodesRemoved(ui::TreeModel* model,
104                                          ui::TreeModelNode* parent,
105                                          int start,
106                                          int count) {
107  // Skip if there is a batch update in progress.
108  if (batch_update_)
109    return;
110
111  ListValue args;
112  args.Append(parent == cookies_tree_model_->GetRoot() ?
113      Value::CreateNullValue() :
114      Value::CreateStringValue(cookies_tree_model_util::GetTreeNodeId(
115          cookies_tree_model_->AsNode(parent))));
116  args.Append(Value::CreateIntegerValue(start));
117  args.Append(Value::CreateIntegerValue(count));
118  web_ui_->CallJavascriptFunction("CookiesView.onTreeItemRemoved", args);
119}
120
121void CookiesViewHandler::TreeModelBeginBatch(CookiesTreeModel* model) {
122  DCHECK(!batch_update_);  // There should be no nested batch begin.
123  batch_update_ = true;
124}
125
126void CookiesViewHandler::TreeModelEndBatch(CookiesTreeModel* model) {
127  DCHECK(batch_update_);
128  batch_update_ = false;
129
130  SendChildren(cookies_tree_model_->GetRoot());
131}
132
133void CookiesViewHandler::EnsureCookiesTreeModelCreated() {
134  if (!cookies_tree_model_.get()) {
135    Profile* profile = web_ui_->GetProfile();
136    cookies_tree_model_.reset(new CookiesTreeModel(
137        profile->GetRequestContext()->DONTUSEME_GetCookieStore()->
138            GetCookieMonster(),
139        new BrowsingDataDatabaseHelper(profile),
140        new BrowsingDataLocalStorageHelper(profile),
141        NULL,
142        new BrowsingDataAppCacheHelper(profile),
143        BrowsingDataIndexedDBHelper::Create(profile),
144        false));
145    cookies_tree_model_->AddCookiesTreeObserver(this);
146  }
147}
148
149void CookiesViewHandler::UpdateSearchResults(const ListValue* args) {
150  std::string query;
151  if (!args->GetString(0, &query)){
152    return;
153  }
154
155  EnsureCookiesTreeModelCreated();
156
157  cookies_tree_model_->UpdateSearchResults(UTF8ToWide(query));
158}
159
160void CookiesViewHandler::RemoveAll(const ListValue* args) {
161  EnsureCookiesTreeModelCreated();
162  cookies_tree_model_->DeleteAllStoredObjects();
163}
164
165void CookiesViewHandler::Remove(const ListValue* args) {
166  std::string node_path;
167  if (!args->GetString(0, &node_path)){
168    return;
169  }
170
171  EnsureCookiesTreeModelCreated();
172
173  CookieTreeNode* node = cookies_tree_model_util::GetTreeNodeFromPath(
174      cookies_tree_model_->GetRoot(), node_path);
175  if (node)
176    cookies_tree_model_->DeleteCookieNode(node);
177}
178
179void CookiesViewHandler::LoadChildren(const ListValue* args) {
180  std::string node_path;
181  if (!args->GetString(0, &node_path)){
182    return;
183  }
184
185  EnsureCookiesTreeModelCreated();
186
187  CookieTreeNode* node = cookies_tree_model_util::GetTreeNodeFromPath(
188      cookies_tree_model_->GetRoot(), node_path);
189  if (node)
190    SendChildren(node);
191}
192
193void CookiesViewHandler::SendChildren(CookieTreeNode* parent) {
194  ListValue* children = new ListValue;
195  cookies_tree_model_util::GetChildNodeList(parent, 0, parent->child_count(),
196      children);
197
198  ListValue args;
199  args.Append(parent == cookies_tree_model_->GetRoot() ?
200      Value::CreateNullValue() :
201      Value::CreateStringValue(cookies_tree_model_util::GetTreeNodeId(parent)));
202  args.Append(children);
203
204  web_ui_->CallJavascriptFunction("CookiesView.loadChildren", args);
205}
206