summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/cookies_tree_model.cc117
-rw-r--r--chrome/browser/cookies_tree_model.h101
-rw-r--r--chrome/browser/gtk/options/cookies_view.cc130
-rw-r--r--chrome/browser/gtk/options/cookies_view.h23
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_context.cc48
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_context.h12
-rw-r--r--chrome/browser/views/options/cookies_view.cc163
-rw-r--r--chrome/browser/views/options/cookies_view.h57
8 files changed, 585 insertions, 66 deletions
diff --git a/chrome/browser/cookies_tree_model.cc b/chrome/browser/cookies_tree_model.cc
index 71932e8..7944028 100644
--- a/chrome/browser/cookies_tree_model.cc
+++ b/chrome/browser/cookies_tree_model.cc
@@ -14,6 +14,7 @@
#include "app/tree_node_model.h"
#include "base/linked_ptr.h"
#include "base/string_util.h"
+#include "chrome/browser/in_process_webkit/webkit_context.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/profile.h"
#include "grit/app_resources.h"
@@ -114,6 +115,22 @@ class OriginNodeComparator {
} // namespace
///////////////////////////////////////////////////////////////////////////////
+// CookieTreeLocalStorageNode, public:
+
+CookieTreeLocalStorageNode::CookieTreeLocalStorageNode(
+ BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info)
+ : CookieTreeNode(UTF8ToWide(
+ !local_storage_info->origin.empty() ?
+ local_storage_info->origin :
+ local_storage_info->database_identifier)),
+ local_storage_info_(local_storage_info) {
+}
+
+void CookieTreeLocalStorageNode::DeleteStoredObjects() {
+ GetModel()->DeleteLocalStorage(local_storage_info_->file_path);
+}
+
+///////////////////////////////////////////////////////////////////////////////
// CookieTreeRootNode, public:
CookieTreeOriginNode* CookieTreeRootNode::GetOrCreateOriginNode(
const std::wstring& origin) {
@@ -155,6 +172,17 @@ CookieTreeCookiesNode* CookieTreeOriginNode::GetOrCreateCookiesNode() {
return retval;
}
+CookieTreeLocalStoragesNode*
+ CookieTreeOriginNode::GetOrCreateLocalStoragesNode() {
+ if (local_storages_child_)
+ return local_storages_child_;
+ // need to make a LocalStorages node, add it to the tree, and return it
+ CookieTreeLocalStoragesNode* retval = new CookieTreeLocalStoragesNode;
+ GetModel()->Add(this, cookies_child_ ? 1 : 0, retval);
+ local_storages_child_ = retval;
+ return retval;
+}
+
///////////////////////////////////////////////////////////////////////////////
// CookieTreeCookiesNode, public:
@@ -173,14 +201,47 @@ void CookieTreeCookiesNode::AddCookieNode(
}
///////////////////////////////////////////////////////////////////////////////
+// CookieTreeLocalStoragesNode, public:
+
+CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode()
+ : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE)) {
+}
+
+void CookieTreeLocalStoragesNode::AddLocalStorageNode(
+ CookieTreeLocalStorageNode* new_child) {
+ std::vector<CookieTreeNode*>::iterator local_storage_iterator =
+ lower_bound(children().begin(),
+ children().end(),
+ new_child,
+ CookieTreeLocalStorageNode::CookieNodeComparator());
+ GetModel()->Add(this,
+ (local_storage_iterator - children().begin()),
+ new_child);
+}
+
+///////////////////////////////////////////////////////////////////////////////
// CookieTreeCookieNode, private
bool CookieTreeCookieNode::CookieNodeComparator::operator() (
const CookieTreeNode* lhs, const CookieTreeNode* rhs) {
- return (static_cast<const CookieTreeCookieNode*>(lhs)->
- cookie_->second.Name() <
- static_cast<const CookieTreeCookieNode*>(rhs)->
- cookie_->second.Name());
+ const CookieTreeCookieNode* left =
+ static_cast<const CookieTreeCookieNode*>(lhs);
+ const CookieTreeCookieNode* right =
+ static_cast<const CookieTreeCookieNode*>(rhs);
+ return (left->cookie_->second.Name() < right->cookie_->second.Name());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// CookieTreeLocalStorageNode, private
+
+bool CookieTreeLocalStorageNode::CookieNodeComparator::operator() (
+ const CookieTreeNode* lhs, const CookieTreeNode* rhs) {
+ const CookieTreeLocalStorageNode* left =
+ static_cast<const CookieTreeLocalStorageNode*>(lhs);
+ const CookieTreeLocalStorageNode* right =
+ static_cast<const CookieTreeLocalStorageNode*>(rhs);
+ return (left->local_storage_info_->origin <
+ right->local_storage_info_->origin);
}
///////////////////////////////////////////////////////////////////////////////
@@ -191,6 +252,13 @@ CookiesTreeModel::CookiesTreeModel(Profile* profile)
new CookieTreeRootNode(this))),
profile_(profile) {
LoadCookies();
+ local_storage_model_ = new BrowsingDataLocalStorageHelper(profile_);
+ local_storage_model_->StartFetching(NewCallback(
+ this, &CookiesTreeModel::OnStorageModelInfoLoaded));
+}
+
+CookiesTreeModel::~CookiesTreeModel() {
+ local_storage_model_->CancelNotification();
}
///////////////////////////////////////////////////////////////////////////////
@@ -218,6 +286,8 @@ int CookiesTreeModel::GetIconIndex(TreeModelNode* node) {
case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
return COOKIE;
break;
+ case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE:
+ // TODO(bulach): add an icon for local storage.
default:
return -1;
}
@@ -283,11 +353,50 @@ void CookiesTreeModel::DeleteCookieNode(CookieTreeNode* cookie_node) {
delete Remove(parent_node, cookie_node_index);
}
+void CookiesTreeModel::DeleteLocalStorage(const FilePath& file_path) {
+ local_storage_model_->DeleteLocalStorageFile(file_path);
+}
+
+void CookiesTreeModel::DeleteAllLocalStorage() {
+ local_storage_model_->DeleteAllLocalStorageFiles();
+}
+
void CookiesTreeModel::UpdateSearchResults(const std::wstring& filter) {
CookieTreeNode* root = GetRoot();
int num_children = root->GetChildCount();
for (int i = num_children - 1; i >= 0; --i)
delete Remove(root, i);
LoadCookiesWithFilter(filter);
+ PopulateLocalStorageInfoWithFilter(filter);
+ NotifyObserverTreeNodeChanged(root);
+}
+
+void CookiesTreeModel::OnStorageModelInfoLoaded(
+ const LocalStorageInfoList& local_storage_info) {
+ local_storage_info_list_ = local_storage_info;
+ PopulateLocalStorageInfoWithFilter(L"");
+}
+
+void CookiesTreeModel::PopulateLocalStorageInfoWithFilter(
+ const std::wstring& filter) {
+ CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot());
+ for (LocalStorageInfoList::iterator local_storage_info =
+ local_storage_info_list_.begin();
+ local_storage_info != local_storage_info_list_.end();
+ ++local_storage_info) {
+ std::string origin =
+ !local_storage_info->host.empty() ?
+ local_storage_info->host :
+ local_storage_info->database_identifier;
+ if (!filter.size() ||
+ (UTF8ToWide(origin).find(filter) != std::wstring::npos)) {
+ CookieTreeOriginNode* origin_node = root->GetOrCreateOriginNode(
+ UTF8ToWide(local_storage_info->host));
+ CookieTreeLocalStoragesNode* local_storages_node =
+ origin_node->GetOrCreateLocalStoragesNode();
+ local_storages_node->AddLocalStorageNode(
+ new CookieTreeLocalStorageNode(&(*local_storage_info)));
+ }
+ }
NotifyObserverTreeNodeChanged(root);
}
diff --git a/chrome/browser/cookies_tree_model.h b/chrome/browser/cookies_tree_model.h
index 11b7f8a..45c7585 100644
--- a/chrome/browser/cookies_tree_model.h
+++ b/chrome/browser/cookies_tree_model.h
@@ -10,9 +10,12 @@
#include "app/tree_node_model.h"
#include "base/scoped_ptr.h"
+#include "chrome/browser/browsing_data_local_storage_helper.h"
#include "net/base/cookie_monster.h"
class CookiesTreeModel;
+class CookieTreeLocalStorageNode;
+class CookieTreeLocalStoragesNode;
class CookieTreeCookieNode;
class CookieTreeCookiesNode;
class CookieTreeOriginNode;
@@ -33,18 +36,27 @@ class CookieTreeNode : public TreeNode<CookieTreeNode> {
TYPE_ROOT, // This is used for CookieTreeRootNode nodes.
TYPE_ORIGIN, // This is used for CookieTreeOriginNode nodes.
TYPE_COOKIES, // This is used for CookieTreeCookiesNode nodes.
- TYPE_COOKIE // This is used for CookieTreeCookieNode nodes.
+ TYPE_COOKIE, // This is used for CookieTreeCookieNode nodes.
+ TYPE_LOCAL_STORAGES, // This is used for CookieTreeLocalStoragesNode.
+ TYPE_LOCAL_STORAGE, // This is used for CookieTreeLocalStorageNode.
};
DetailedInfo(const std::wstring& origin, NodeType node_type,
- const net::CookieMonster::CookieListPair* cookie)
+ const net::CookieMonster::CookieListPair* cookie,
+ const BrowsingDataLocalStorageHelper::LocalStorageInfo*
+ local_storage_info)
: origin(origin),
node_type(node_type),
- cookie(cookie) {}
+ cookie(cookie),
+ local_storage_info(local_storage_info) {
+ if (node_type == TYPE_LOCAL_STORAGE)
+ DCHECK(local_storage_info);
+ }
std::wstring origin;
NodeType node_type;
const net::CookieMonster::CookieListPair* cookie;
+ const BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info;
};
CookieTreeNode() {}
@@ -79,7 +91,7 @@ class CookieTreeRootNode : public CookieTreeNode {
// CookieTreeNode methods:
virtual CookiesTreeModel* GetModel() const { return model_; }
virtual DetailedInfo GetDetailedInfo() const {
- return DetailedInfo(std::wstring(), DetailedInfo::TYPE_ROOT, NULL);
+ return DetailedInfo(std::wstring(), DetailedInfo::TYPE_ROOT, NULL, NULL);
}
private:
@@ -92,16 +104,19 @@ class CookieTreeRootNode : public CookieTreeNode {
class CookieTreeOriginNode : public CookieTreeNode {
public:
explicit CookieTreeOriginNode(const std::wstring& origin)
- : CookieTreeNode(origin), cookies_child_(NULL) {}
+ : CookieTreeNode(origin), cookies_child_(NULL),
+ local_storages_child_(NULL) {}
virtual ~CookieTreeOriginNode() {}
// CookieTreeNode methods:
virtual DetailedInfo GetDetailedInfo() const {
- return DetailedInfo(GetTitle(), DetailedInfo::TYPE_ORIGIN, NULL);
+ return DetailedInfo(GetTitle(), DetailedInfo::TYPE_ORIGIN, NULL, NULL);
}
// CookieTreeOriginNode methods:
CookieTreeCookiesNode* GetOrCreateCookiesNode();
+ CookieTreeLocalStoragesNode* GetOrCreateLocalStoragesNode();
+
private:
// A pointer to the COOKIES node. Eventually we will also have database,
@@ -111,6 +126,7 @@ class CookieTreeOriginNode : public CookieTreeNode {
// DATABASES etc node seems less preferable than storing an extra pointer per
// origin.
CookieTreeCookiesNode* cookies_child_;
+ CookieTreeLocalStoragesNode* local_storages_child_;
DISALLOW_COPY_AND_ASSIGN(CookieTreeOriginNode);
};
@@ -124,7 +140,7 @@ class CookieTreeCookiesNode : public CookieTreeNode {
// CookieTreeNode methods:
virtual DetailedInfo GetDetailedInfo() const {
return DetailedInfo(GetParent()->GetTitle(), DetailedInfo::TYPE_COOKIES,
- NULL);
+ NULL, NULL);
}
// CookieTreeCookiesNode methods:
@@ -147,7 +163,7 @@ class CookieTreeCookieNode : public CookieTreeNode {
virtual void DeleteStoredObjects();
virtual DetailedInfo GetDetailedInfo() const {
return DetailedInfo(GetParent()->GetParent()->GetTitle(),
- DetailedInfo::TYPE_COOKIE, cookie_);
+ DetailedInfo::TYPE_COOKIE, cookie_, NULL);
}
private:
@@ -165,11 +181,64 @@ class CookieTreeCookieNode : public CookieTreeNode {
DISALLOW_COPY_AND_ASSIGN(CookieTreeCookieNode);
};
+// CookieTreeLocalStoragesNode -------------------------------------------------
+class CookieTreeLocalStoragesNode : public CookieTreeNode {
+ public:
+ CookieTreeLocalStoragesNode();
+ virtual ~CookieTreeLocalStoragesNode() {}
+
+ // CookieTreeNode methods:
+ virtual DetailedInfo GetDetailedInfo() const {
+ return DetailedInfo(GetParent()->GetTitle(),
+ DetailedInfo::TYPE_LOCAL_STORAGES,
+ NULL,
+ NULL);
+ }
+
+ // CookieTreeStoragesNode methods:
+ void AddLocalStorageNode(CookieTreeLocalStorageNode* child);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStoragesNode);
+};
+
+class CookieTreeLocalStorageNode : public CookieTreeNode {
+ public:
+ friend class CookieTreeLocalStoragesNode;
+
+ // Does not take ownership of local_storage_info, and local_storage_info
+ // should remain valid at least as long as the CookieTreeStorageNode is valid.
+ explicit CookieTreeLocalStorageNode(
+ BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info);
+ virtual ~CookieTreeLocalStorageNode() {}
+
+ // CookieTreeStorageNode methods:
+ virtual void DeleteStoredObjects();
+ virtual DetailedInfo GetDetailedInfo() const {
+ return DetailedInfo(GetParent()->GetParent()->GetTitle(),
+ DetailedInfo::TYPE_LOCAL_STORAGE, NULL,
+ local_storage_info_);
+ }
+
+ private:
+ // Comparator functor, takes CookieTreeNode so that we can use it in
+ // lower_bound using children()'s iterators, which are CookieTreeNode*.
+ class CookieNodeComparator {
+ public:
+ bool operator() (const CookieTreeNode* lhs, const CookieTreeNode* rhs);
+ };
+
+ // local_storage_info_ is not owned by the node, and is expected to remain
+ // valid as long as the CookieTreeLocalStorageNode is valid.
+ BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStorageNode);
+};
class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> {
public:
explicit CookiesTreeModel(Profile* profile);
- virtual ~CookiesTreeModel() {}
+ virtual ~CookiesTreeModel();
// TreeModel methods:
// Returns the set of icons for the nodes in the tree. You only need override
@@ -185,6 +254,8 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> {
void DeleteCookie(const net::CookieMonster::CookieListPair& cookie);
void DeleteAllCookies();
void DeleteCookieNode(CookieTreeNode* cookie_node);
+ void DeleteLocalStorage(const FilePath& file_path);
+ void DeleteAllLocalStorage();
// Filter the origins to only display matched results.
void UpdateSearchResults(const std::wstring& filter);
@@ -192,18 +263,28 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> {
private:
enum CookieIconIndex {
ORIGIN = 0,
- COOKIE = 1
+ COOKIE = 1,
+ LOCAL_STORAGE = 2,
};
typedef net::CookieMonster::CookieList CookieList;
typedef std::vector<net::CookieMonster::CookieListPair*> CookiePtrList;
+ typedef std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo>
+ LocalStorageInfoList;
void LoadCookies();
void LoadCookiesWithFilter(const std::wstring& filter);
+ void OnStorageModelInfoLoaded(const LocalStorageInfoList& local_storage_info);
+
+ void PopulateLocalStorageInfoWithFilter(const std::wstring& filter);
+
// The profile from which this model sources cookies.
Profile* profile_;
CookieList all_cookies_;
+ scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_model_;
+ LocalStorageInfoList local_storage_info_list_;
+
DISALLOW_COPY_AND_ASSIGN(CookiesTreeModel);
};
diff --git a/chrome/browser/gtk/options/cookies_view.cc b/chrome/browser/gtk/options/cookies_view.cc
index fb9c8c6..d63a59d 100644
--- a/chrome/browser/gtk/options/cookies_view.cc
+++ b/chrome/browser/gtk/options/cookies_view.cc
@@ -35,8 +35,8 @@ enum {
// The currently open cookie manager, if any.
CookiesView* instance_ = NULL;
-void InitCookieDetailStyle(GtkWidget* entry, GtkStyle* label_style,
- GtkStyle* dialog_style) {
+void InitBrowserDetailStyle(GtkWidget* entry, GtkStyle* label_style,
+ GtkStyle* dialog_style) {
gtk_widget_modify_fg(entry, GTK_STATE_NORMAL,
&label_style->fg[GTK_STATE_NORMAL]);
gtk_widget_modify_fg(entry, GTK_STATE_INSENSITIVE,
@@ -193,31 +193,54 @@ void CookiesView::Init() {
G_CALLBACK(OnSelectionChanged), this);
// Cookie details.
- GtkWidget* details_frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(details_frame), GTK_SHADOW_ETCHED_IN);
- gtk_box_pack_start(GTK_BOX(cookie_list_vbox), details_frame,
+ GtkWidget* cookie_details_frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(cookie_details_frame),
+ GTK_SHADOW_ETCHED_IN);
+ gtk_box_pack_start(GTK_BOX(cookie_list_vbox), cookie_details_frame,
FALSE, FALSE, 0);
cookie_details_table_ = gtk_table_new(7, 2, FALSE);
- gtk_container_add(GTK_CONTAINER(details_frame), cookie_details_table_);
+ gtk_container_add(GTK_CONTAINER(cookie_details_frame), cookie_details_table_);
gtk_table_set_col_spacing(GTK_TABLE(cookie_details_table_), 0,
gtk_util::kLabelSpacing);
int row = 0;
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_NAME_LABEL,
- &cookie_name_entry_);
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_CONTENT_LABEL,
- &cookie_content_entry_);
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_DOMAIN_LABEL,
- &cookie_domain_entry_);
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_PATH_LABEL,
- &cookie_path_entry_);
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_SENDFOR_LABEL,
- &cookie_send_for_entry_);
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_CREATED_LABEL,
- &cookie_created_entry_);
- InitCookieDetailRow(row++, IDS_COOKIES_COOKIE_EXPIRES_LABEL,
- &cookie_expires_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_NAME_LABEL,
+ cookie_details_table_, &cookie_name_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_CONTENT_LABEL,
+ cookie_details_table_, &cookie_content_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_DOMAIN_LABEL,
+ cookie_details_table_, &cookie_domain_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_PATH_LABEL,
+ cookie_details_table_, &cookie_path_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_SENDFOR_LABEL,
+ cookie_details_table_, &cookie_send_for_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_CREATED_LABEL,
+ cookie_details_table_, &cookie_created_entry_);
+ InitDetailRow(row++, IDS_COOKIES_COOKIE_EXPIRES_LABEL,
+ cookie_details_table_, &cookie_expires_entry_);
+
+ // Local storage details.
+ GtkWidget* local_storage_details_frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(local_storage_details_frame),
+ GTK_SHADOW_ETCHED_IN);
+ gtk_box_pack_start(GTK_BOX(cookie_list_vbox), local_storage_details_frame,
+ FALSE, FALSE, 0);
+ local_storage_details_table_ = gtk_table_new(3, 2, FALSE);
+ gtk_container_add(GTK_CONTAINER(local_storage_details_frame),
+ local_storage_details_table_);
+ gtk_table_set_col_spacing(GTK_TABLE(local_storage_details_table_), 0,
+ gtk_util::kLabelSpacing);
+
+ row = 0;
+ InitDetailRow(row++, IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL,
+ local_storage_details_table_, &local_storage_origin_entry_);
+ InitDetailRow(row++, IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL,
+ local_storage_details_table_, &local_storage_size_entry_);
+ InitDetailRow(row++, IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL,
+ local_storage_details_table_,
+ &local_storage_last_modified_entry_);
+ UpdateVisibleDetailedInfo(cookie_details_table_);
// Populate the view.
cookies_tree_adapter_->Init();
SetInitialTreeState();
@@ -231,30 +254,38 @@ void CookiesView::InitStylesAndShow() {
GtkStyle* label_style = gtk_widget_get_style(description_label_);
GtkStyle* dialog_style = gtk_widget_get_style(dialog_);
- InitCookieDetailStyle(cookie_name_entry_, label_style, dialog_style);
- InitCookieDetailStyle(cookie_content_entry_, label_style, dialog_style);
- InitCookieDetailStyle(cookie_domain_entry_, label_style, dialog_style);
- InitCookieDetailStyle(cookie_path_entry_, label_style, dialog_style);
- InitCookieDetailStyle(cookie_send_for_entry_, label_style, dialog_style);
- InitCookieDetailStyle(cookie_created_entry_, label_style, dialog_style);
- InitCookieDetailStyle(cookie_expires_entry_, label_style, dialog_style);
+ // Cookie details.
+ InitBrowserDetailStyle(cookie_name_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(cookie_content_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(cookie_domain_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(cookie_path_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(cookie_send_for_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(cookie_created_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(cookie_expires_entry_, label_style, dialog_style);
+
+ // Local storage details.
+ InitBrowserDetailStyle(local_storage_origin_entry_, label_style,
+ dialog_style);
+ InitBrowserDetailStyle(local_storage_size_entry_, label_style, dialog_style);
+ InitBrowserDetailStyle(local_storage_last_modified_entry_, label_style,
+ dialog_style);
gtk_widget_show_all(dialog_);
}
-void CookiesView::InitCookieDetailRow(int row, int label_id,
- GtkWidget** entry) {
+void CookiesView::InitDetailRow(int row, int label_id,
+ GtkWidget* details_table, GtkWidget** entry) {
GtkWidget* name_label = gtk_label_new(
l10n_util::GetStringUTF8(label_id).c_str());
gtk_misc_set_alignment(GTK_MISC(name_label), 1, 0.5);
- gtk_table_attach(GTK_TABLE(cookie_details_table_), name_label,
+ gtk_table_attach(GTK_TABLE(details_table), name_label,
0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 0);
*entry = gtk_entry_new();
gtk_entry_set_editable(GTK_ENTRY(*entry), FALSE);
gtk_entry_set_has_frame(GTK_ENTRY(*entry), FALSE);
- gtk_table_attach_defaults(GTK_TABLE(cookie_details_table_), *entry,
+ gtk_table_attach_defaults(GTK_TABLE(details_table), *entry,
1, 2, row, row + 1);
}
@@ -279,9 +310,15 @@ void CookiesView::EnableControls() {
static_cast<CookieTreeNode*>(
cookies_tree_adapter_->GetNode(&iter))->GetDetailedInfo();
if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
+ UpdateVisibleDetailedInfo(cookie_details_table_);
PopulateCookieDetails(detailed_info.cookie->first,
detailed_info.cookie->second);
+ } else if (detailed_info.node_type ==
+ CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) {
+ UpdateVisibleDetailedInfo(local_storage_details_table_);
+ PopulateLocalStorageDetails(*detailed_info.local_storage_info);
} else {
+ UpdateVisibleDetailedInfo(cookie_details_table_);
ClearCookieDetails();
}
} else {
@@ -299,6 +336,12 @@ void CookiesView::SetCookieDetailsSensitivity(gboolean enabled) {
gtk_widget_set_sensitive(cookie_expires_entry_, enabled);
}
+void CookiesView::SetLocalStorageDetailsSensitivity(gboolean enabled) {
+ gtk_widget_set_sensitive(local_storage_origin_entry_, enabled);
+ gtk_widget_set_sensitive(local_storage_size_entry_, enabled);
+ gtk_widget_set_sensitive(local_storage_last_modified_entry_, enabled);
+}
+
void CookiesView::PopulateCookieDetails(
const std::string& domain,
const net::CookieMonster::CanonicalCookie& cookie) {
@@ -326,6 +369,22 @@ void CookiesView::PopulateCookieDetails(
SetCookieDetailsSensitivity(TRUE);
}
+void CookiesView::PopulateLocalStorageDetails(
+ const BrowsingDataLocalStorageHelper::LocalStorageInfo&
+ local_storage_info) {
+ gtk_entry_set_text(GTK_ENTRY(local_storage_origin_entry_),
+ local_storage_info.origin.c_str());
+ gtk_entry_set_text(GTK_ENTRY(local_storage_size_entry_),
+ WideToUTF8(FormatBytes(
+ local_storage_info.size,
+ GetByteDisplayUnits(local_storage_info.size),
+ true)).c_str());
+ gtk_entry_set_text(GTK_ENTRY(local_storage_last_modified_entry_),
+ WideToUTF8(base::TimeFormatFriendlyDateAndTime(
+ local_storage_info.last_modified)).c_str());
+ SetLocalStorageDetailsSensitivity(TRUE);
+}
+
void CookiesView::ClearCookieDetails() {
std::string no_cookie =
l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_NONESELECTED);
@@ -437,6 +496,15 @@ void CookiesView::UpdateFilterResults() {
}
}
+void CookiesView::UpdateVisibleDetailedInfo(GtkWidget* table) {
+ // Toggle the parent (the table frame) visibility.
+ gtk_widget_show(gtk_widget_get_parent(table));
+ GtkWidget* other = local_storage_details_table_;
+ if (table == local_storage_details_table_)
+ other = cookie_details_table_;
+ gtk_widget_hide(gtk_widget_get_parent(other));
+}
+
// static
void CookiesView::OnFilterEntryActivated(GtkEntry* entry, CookiesView* window) {
window->filter_update_factory_.RevokeAll();
diff --git a/chrome/browser/gtk/options/cookies_view.h b/chrome/browser/gtk/options/cookies_view.h
index 260e3db..8dff1a1 100644
--- a/chrome/browser/gtk/options/cookies_view.h
+++ b/chrome/browser/gtk/options/cookies_view.h
@@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
+#include "chrome/browser/browsing_data_local_storage_helper.h"
#include "chrome/common/gtk_tree.h"
#include "net/base/cookie_monster.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
@@ -46,8 +47,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
// Initialize the widget styles and display the dialog.
void InitStylesAndShow();
- // Helper for initializing cookie details table.
- void InitCookieDetailRow(int row, int label_id, GtkWidget** display_label);
+ // Helper for initializing cookie / local storage details table.
+ void InitDetailRow(int row, int label_id,
+ GtkWidget* details_table, GtkWidget** display_label);
// Set the initial selection and tree expanded state.
void SetInitialTreeState();
@@ -58,10 +60,18 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
// Set sensitivity of cookie details.
void SetCookieDetailsSensitivity(gboolean enabled);
+ // Set sensitivity of local storage details.
+ void SetLocalStorageDetailsSensitivity(gboolean enabled);
+
// Show the details of the currently selected cookie.
void PopulateCookieDetails(const std::string& domain,
const net::CookieMonster::CanonicalCookie& cookie);
+ // Show the details of the currently selected local storage.
+ void PopulateLocalStorageDetails(
+ const BrowsingDataLocalStorageHelper::LocalStorageInfo&
+ local_storage_info);
+
// Reset the cookie details display.
void ClearCookieDetails();
@@ -90,6 +100,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
// Filter the list against the text in |filter_entry_|.
void UpdateFilterResults();
+ // Sets which of the detailed info table is visible.
+ void UpdateVisibleDetailedInfo(GtkWidget* table);
+
// Callbacks for user actions filtering the list.
static void OnFilterEntryActivated(GtkEntry* entry, CookiesView* window);
static void OnFilterEntryChanged(GtkEditable* editable, CookiesView* window);
@@ -120,6 +133,12 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate {
GtkWidget* cookie_created_entry_;
GtkWidget* cookie_expires_entry_;
+ // The local storage details widgets.
+ GtkWidget* local_storage_details_table_;
+ GtkWidget* local_storage_origin_entry_;
+ GtkWidget* local_storage_size_entry_;
+ GtkWidget* local_storage_last_modified_entry_;
+
// The profile.
Profile* profile_;
diff --git a/chrome/browser/in_process_webkit/dom_storage_context.cc b/chrome/browser/in_process_webkit/dom_storage_context.cc
index 3997c5f..c19b6cf 100644
--- a/chrome/browser/in_process_webkit/dom_storage_context.cc
+++ b/chrome/browser/in_process_webkit/dom_storage_context.cc
@@ -11,13 +11,22 @@
#include "chrome/browser/in_process_webkit/dom_storage_namespace.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
#include "chrome/common/dom_storage_common.h"
+#include "webkit/glue/glue_util.h"
-static const char* kLocalStorageDirectory = "Local Storage";
+const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
+ FILE_PATH_LITERAL("Local Storage");
+
+const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
+ FILE_PATH_LITERAL(".localstorage");
+
+static const FilePath::CharType kLocalStorageOldPath[] =
+ FILE_PATH_LITERAL("localStorage");
// TODO(jorlow): Remove after Chrome 4 ships.
static void MigrateLocalStorageDirectory(const FilePath& data_path) {
- FilePath new_path = data_path.AppendASCII(kLocalStorageDirectory);
- FilePath old_path = data_path.AppendASCII("localStorage");
+ FilePath new_path = data_path.Append(
+ DOMStorageContext::kLocalStorageDirectory);
+ FilePath old_path = data_path.Append(kLocalStorageOldPath);
if (!file_util::DirectoryExists(new_path) &&
file_util::DirectoryExists(old_path)) {
file_util::Move(old_path, new_path);
@@ -148,7 +157,7 @@ void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
PurgeMemory();
file_util::FileEnumerator file_enumerator(
- webkit_context_->data_path().AppendASCII(kLocalStorageDirectory), false,
+ webkit_context_->data_path().Append(kLocalStorageDirectory), false,
file_util::FileEnumerator::FILES);
for (FilePath path = file_enumerator.Next(); !path.value().empty();
path = file_enumerator.Next()) {
@@ -159,12 +168,41 @@ void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
}
}
+void DOMStorageContext::DeleteLocalStorageFile(const FilePath& file_path) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+
+ // Make sure that we don't delete a database that's currently being accessed
+ // by unloading all of the databases temporarily.
+ // TODO(bulach): both this method and DeleteDataModifiedSince could purge
+ // only the memory used by the specific file instead of all memory at once.
+ // See http://code.google.com/p/chromium/issues/detail?id=32000
+ PurgeMemory();
+ file_util::Delete(file_path, false);
+}
+
+void DOMStorageContext::DeleteAllLocalStorageFiles() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+
+ // Make sure that we don't delete a database that's currently being accessed
+ // by unloading all of the databases temporarily.
+ PurgeMemory();
+
+ file_util::FileEnumerator file_enumerator(
+ webkit_context_->data_path().Append(kLocalStorageDirectory), false,
+ file_util::FileEnumerator::FILES);
+ for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
+ file_path = file_enumerator.Next()) {
+ if (file_path.Extension() == kLocalStorageExtension)
+ file_util::Delete(file_path, false);
+ }
+}
+
DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
FilePath data_path = webkit_context_->data_path();
FilePath dir_path;
if (!data_path.empty()) {
MigrateLocalStorageDirectory(data_path);
- dir_path = data_path.AppendASCII(kLocalStorageDirectory);
+ dir_path = data_path.Append(kLocalStorageDirectory);
}
DOMStorageNamespace* new_namespace =
DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
diff --git a/chrome/browser/in_process_webkit/dom_storage_context.h b/chrome/browser/in_process_webkit/dom_storage_context.h
index fb68f4c9..4981c07 100644
--- a/chrome/browser/in_process_webkit/dom_storage_context.h
+++ b/chrome/browser/in_process_webkit/dom_storage_context.h
@@ -66,6 +66,18 @@ class DOMStorageContext {
// date that's supplied.
void DeleteDataModifiedSince(const base::Time& cutoff);
+ // Deletes a single local storage file.
+ void DeleteLocalStorageFile(const FilePath& file_path);
+
+ // Deletes all local storage files.
+ void DeleteAllLocalStorageFiles();
+
+ // The local storage directory.
+ static const FilePath::CharType kLocalStorageDirectory[];
+
+ // The local storage file extension.
+ static const FilePath::CharType kLocalStorageExtension[];
+
private:
// Get the local storage instance. The object is owned by this class.
DOMStorageNamespace* CreateLocalStorage();
diff --git a/chrome/browser/views/options/cookies_view.cc b/chrome/browser/views/options/cookies_view.cc
index 7e5f0b4..68dd2df 100644
--- a/chrome/browser/views/options/cookies_view.cc
+++ b/chrome/browser/views/options/cookies_view.cc
@@ -31,7 +31,6 @@ static const int kCookieInfoViewBorderSize = 1;
static const int kCookieInfoViewInsetSize = 3;
static const int kSearchFilterDelayMs = 500;
-
///////////////////////////////////////////////////////////////////////////////
// CookiesTreeView
// Overridden to handle Delete key presses
@@ -49,20 +48,19 @@ class CookiesTreeView : public views::TreeView {
};
CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) {
- SetModel(cookies_model);
- SetRootShown(false);
- SetEditable(false);
+ SetModel(cookies_model);
+ SetRootShown(false);
+ SetEditable(false);
}
void CookiesTreeView::RemoveSelectedItems() {
TreeModelNode* selected_node = GetSelectedNode();
if (selected_node) {
static_cast<CookiesTreeModel*>(model())->DeleteCookieNode(
- static_cast<CookieTreeCookieNode*>(GetSelectedNode()));
+ static_cast<CookieTreeNode*>(GetSelectedNode()));
}
}
-
///////////////////////////////////////////////////////////////////////////////
// CookieInfoView, public:
@@ -253,6 +251,123 @@ void CookieInfoView::Init() {
}
///////////////////////////////////////////////////////////////////////////////
+// LocalStorageInfoView, public:
+
+LocalStorageInfoView::LocalStorageInfoView()
+ : origin_label_(NULL),
+ origin_value_field_(NULL),
+ size_label_(NULL),
+ size_value_field_(NULL),
+ last_modified_label_(NULL),
+ last_modified_value_field_(NULL) {
+}
+
+LocalStorageInfoView::~LocalStorageInfoView() {
+}
+
+void LocalStorageInfoView::SetLocalStorageInfo(
+ const BrowsingDataLocalStorageHelper::LocalStorageInfo&
+ local_storage_info) {
+ origin_value_field_->SetText(UTF8ToWide(local_storage_info.origin));
+ size_value_field_->SetText(
+ FormatBytes(local_storage_info.size,
+ GetByteDisplayUnits(local_storage_info.size),
+ true));
+ last_modified_value_field_->SetText(
+ base::TimeFormatFriendlyDateAndTime(local_storage_info.last_modified));
+ EnableLocalStorageDisplay(true);
+}
+
+void LocalStorageInfoView::EnableLocalStorageDisplay(bool enabled) {
+ origin_value_field_->SetEnabled(enabled);
+ size_value_field_->SetEnabled(enabled);
+ last_modified_value_field_->SetEnabled(enabled);
+}
+
+void LocalStorageInfoView::ClearLocalStorageDisplay() {
+ std::wstring no_cookie_string =
+ l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED);
+ origin_value_field_->SetText(no_cookie_string);
+ size_value_field_->SetText(no_cookie_string);
+ last_modified_value_field_->SetText(no_cookie_string);
+ EnableLocalStorageDisplay(false);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LocalStorageInfoView, views::View overrides:
+
+void LocalStorageInfoView::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (is_add && child == this)
+ Init();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LocalStorageInfoView, private:
+
+void LocalStorageInfoView::Init() {
+ SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW);
+ views::Border* border = views::Border::CreateSolidBorder(
+ kCookieInfoViewBorderSize, border_color);
+ set_border(border);
+
+ origin_label_ = new views::Label(
+ l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL));
+ origin_value_field_ = new views::Textfield;
+ size_label_ = new views::Label(
+ l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL));
+ size_value_field_ = new views::Textfield;
+ last_modified_label_ = new views::Label(
+ l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL));
+ last_modified_value_field_ = new views::Textfield;
+
+ using views::GridLayout;
+ using views::ColumnSet;
+
+ GridLayout* layout = new GridLayout(this);
+ layout->SetInsets(kCookieInfoViewInsetSize,
+ kCookieInfoViewInsetSize,
+ kCookieInfoViewInsetSize,
+ kCookieInfoViewInsetSize);
+ SetLayoutManager(layout);
+
+ int three_column_layout_id = 0;
+ ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id);
+ column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, three_column_layout_id);
+ layout->AddView(origin_label_);
+ layout->AddView(origin_value_field_);
+ layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing);
+ layout->StartRow(0, three_column_layout_id);
+ layout->AddView(size_label_);
+ layout->AddView(size_value_field_);
+ layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing);
+ layout->StartRow(0, three_column_layout_id);
+ layout->AddView(last_modified_label_);
+ layout->AddView(last_modified_value_field_);
+
+ // Color these borderless text areas the same as the containing dialog.
+ SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE);
+ // Now that the Textfields are in the view hierarchy, we can initialize them.
+ origin_value_field_->SetReadOnly(true);
+ origin_value_field_->RemoveBorder();
+ origin_value_field_->SetBackgroundColor(text_area_background);
+ size_value_field_->SetReadOnly(true);
+ size_value_field_->RemoveBorder();
+ size_value_field_->SetBackgroundColor(text_area_background);
+ last_modified_value_field_->SetReadOnly(true);
+ last_modified_value_field_->RemoveBorder();
+ last_modified_value_field_->SetBackgroundColor(text_area_background);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
// CookiesView, public:
// static
@@ -371,10 +486,17 @@ void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) {
static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())->
GetDetailedInfo();
if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
- info_view_->SetCookie(detailed_info.cookie->first,
- detailed_info.cookie->second);
+ UpdateVisibleDetailedInfo(cookie_info_view_);
+ cookie_info_view_->SetCookie(detailed_info.cookie->first,
+ detailed_info.cookie->second);
+ } else if (detailed_info.node_type ==
+ CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) {
+ UpdateVisibleDetailedInfo(local_storage_info_view_);
+ local_storage_info_view_->SetLocalStorageInfo(
+ *detailed_info.local_storage_info);
} else {
- info_view_->ClearCookieDisplay();
+ UpdateVisibleDetailedInfo(cookie_info_view_);
+ cookie_info_view_->ClearCookieDisplay();
}
}
@@ -393,7 +515,8 @@ CookiesView::CookiesView(Profile* profile)
clear_search_button_(NULL),
description_label_(NULL),
cookies_tree_(NULL),
- info_view_(NULL),
+ cookie_info_view_(NULL),
+ local_storage_info_view_(NULL),
remove_button_(NULL),
remove_all_button_(NULL),
profile_(profile),
@@ -421,7 +544,8 @@ void CookiesView::Init() {
l10n_util::GetString(IDS_COOKIES_INFO_LABEL));
description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
cookies_tree_model_.reset(new CookiesTreeModel(profile_));
- info_view_ = new CookieInfoView;
+ cookie_info_view_ = new CookieInfoView;
+ local_storage_info_view_ = new LocalStorageInfoView;
cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get());
remove_button_ = new views::NativeButton(
this, l10n_util::GetString(IDS_COOKIES_REMOVE_LABEL));
@@ -469,7 +593,10 @@ void CookiesView::Init() {
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(0, single_column_layout_id);
- layout->AddView(info_view_);
+ layout->AddView(cookie_info_view_, 1, 2);
+
+ layout->StartRow(0, single_column_layout_id);
+ layout->AddView(local_storage_info_view_);
// Add the Remove/Remove All buttons to the ClientView
View* parent = GetParent();
@@ -477,6 +604,8 @@ void CookiesView::Init() {
parent->AddChildView(remove_all_button_);
if (!cookies_tree_model_.get()->GetRoot()->GetChildCount())
UpdateForEmptyState();
+ else
+ UpdateVisibleDetailedInfo(cookie_info_view_);
}
void CookiesView::ResetSearchQuery() {
@@ -486,7 +615,15 @@ void CookiesView::ResetSearchQuery() {
}
void CookiesView::UpdateForEmptyState() {
- info_view_->ClearCookieDisplay();
+ cookie_info_view_->ClearCookieDisplay();
remove_button_->SetEnabled(false);
remove_all_button_->SetEnabled(false);
+ UpdateVisibleDetailedInfo(cookie_info_view_);
+}
+
+void CookiesView::UpdateVisibleDetailedInfo(views::View* view) {
+ view->SetVisible(true);
+ views::View* other = local_storage_info_view_;
+ if (view == local_storage_info_view_) other = cookie_info_view_;
+ other->SetVisible(false);
}
diff --git a/chrome/browser/views/options/cookies_view.h b/chrome/browser/views/options/cookies_view.h
index d7c1b23..91d6cf4a 100644
--- a/chrome/browser/views/options/cookies_view.h
+++ b/chrome/browser/views/options/cookies_view.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/task.h"
+#include "chrome/browser/browsing_data_local_storage_helper.h"
#include "net/base/cookie_monster.h"
#include "views/controls/button/button.h"
#include "views/controls/tree/tree_view.h"
@@ -24,9 +25,11 @@ class NativeButton;
} // namespace views
+class BrowsingDataLocalStorageHelper;
class CookieInfoView;
class CookiesTreeModel;
class CookiesTreeView;
+class LocalStorageInfoView;
class Profile;
class Timer;
@@ -96,13 +99,23 @@ class CookiesView : public views::View,
// Update the UI when there are no cookies.
void UpdateForEmptyState();
+ // Update the UI when a cookie is selected.
+ void UpdateForCookieState();
+
+ // Update the UI when a local storage is selected.
+ void UpdateForLocalStorageState();
+
+ // Updates view to be visible inside detailed_info_view_;
+ void UpdateVisibleDetailedInfo(views::View* view);
+
// Assorted dialog controls
views::Label* search_label_;
views::Textfield* search_field_;
views::NativeButton* clear_search_button_;
views::Label* description_label_;
CookiesTreeView* cookies_tree_;
- CookieInfoView* info_view_;
+ CookieInfoView* cookie_info_view_;
+ LocalStorageInfoView* local_storage_info_view_;
views::NativeButton* remove_button_;
views::NativeButton* remove_all_button_;
@@ -172,4 +185,46 @@ class CookieInfoView : public views::View {
DISALLOW_COPY_AND_ASSIGN(CookieInfoView);
};
+///////////////////////////////////////////////////////////////////////////////
+// LocalStorageInfoView
+//
+// Responsible for displaying a tabular grid of Local Storage information.
+class LocalStorageInfoView : public views::View {
+ public:
+ LocalStorageInfoView();
+ virtual ~LocalStorageInfoView();
+
+ // Update the display from the specified Local Storage info.
+ void SetLocalStorageInfo(
+ const BrowsingDataLocalStorageHelper::LocalStorageInfo&
+ local_storage_info);
+
+ // Clears the cookie display to indicate that no or multiple local storages
+ // are selected.
+ void ClearLocalStorageDisplay();
+
+ // Enables or disables the local storate property text fields.
+ void EnableLocalStorageDisplay(bool enabled);
+
+ protected:
+ // views::View overrides:
+ virtual void ViewHierarchyChanged(
+ bool is_add, views::View* parent, views::View* child);
+
+ private:
+ // Set up the view layout
+ void Init();
+
+ // Individual property labels
+ views::Label* origin_label_;
+ views::Textfield* origin_value_field_;
+ views::Label* size_label_;
+ views::Textfield* size_value_field_;
+ views::Label* last_modified_label_;
+ views::Textfield* last_modified_value_field_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalStorageInfoView);
+};
+
+
#endif // CHROME_BROWSER_VIEWS_OPTIONS_COOKIES_VIEW_H_