diff options
25 files changed, 892 insertions, 262 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 9c1b927..781fffc 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -5358,6 +5358,9 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL" desc="The Database Description label"> Description: </message> + <message name="IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME" desc="The the name displayed for a Database with an empty name attribute."> + <unnamed> + </message> <message name="IDS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL" desc="The Local Storage Origin label"> Origin: </message> @@ -5412,6 +5415,9 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_COOKIES_LOCAL_STORAGE" desc="Label for local storage (name of a HTML standard)"> Local Storage </message> + <message name="IDS_COOKIES_LAST_ACCESSED_LABEL" desc="The last access date label"> + Last accessed: + </message> <!-- New Tab --> <message name="IDS_NEW_TAB_TITLE" diff --git a/chrome/browser/browsing_data_appcache_helper.cc b/chrome/browser/browsing_data_appcache_helper.cc new file mode 100644 index 0000000..c0d7ced --- /dev/null +++ b/chrome/browser/browsing_data_appcache_helper.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/browsing_data_appcache_helper.h" + +BrowsingDataAppCacheHelper::BrowsingDataAppCacheHelper(Profile* profile) + : is_fetching_(false) { +} + +void BrowsingDataAppCacheHelper::StartFetching(Callback0::Type* callback) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(!is_fetching_); + DCHECK(callback); + is_fetching_ = true; + info_list_.clear(); + completion_callback_.reset(callback); + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, NewRunnableMethod( + this, &BrowsingDataAppCacheHelper::StartFetchingInIOThread)); +} + +void BrowsingDataAppCacheHelper::CancelNotification() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + completion_callback_.reset(); +} + +void BrowsingDataAppCacheHelper::DeleteAppCache(int64 group_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, NewRunnableMethod( + this, &BrowsingDataAppCacheHelper::DeleteAppCacheInIOThread, + group_id)); +} + +void BrowsingDataAppCacheHelper::StartFetchingInIOThread() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + +#ifndef NDEBUG + // TODO(michaeln): get real data from the appcache service + info_list_.push_back( + AppCacheInfo(GURL("http://bogus/manifest"), + 1 * 1024 * 1024, base::Time::Now(), base::Time::Now(), 1)); + info_list_.push_back( + AppCacheInfo(GURL("https://bogus/manifest"), + 2 * 1024 * 1024, base::Time::Now(), base::Time::Now(), 2)); + info_list_.push_back( + AppCacheInfo(GURL("http://bogus:8080/manifest"), + 3 * 1024 * 1024, base::Time::Now(), base::Time::Now(), 3)); +#endif + + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, NewRunnableMethod( + this, &BrowsingDataAppCacheHelper::OnFetchComplete)); +} + +void BrowsingDataAppCacheHelper::OnFetchComplete() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(is_fetching_); + is_fetching_ = false; + if (completion_callback_ != NULL) { + completion_callback_->Run(); + completion_callback_.reset(); + } +} + +void BrowsingDataAppCacheHelper::DeleteAppCacheInIOThread( + int64 group_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + // TODO(michaeln): plumb to the appcache service +} diff --git a/chrome/browser/browsing_data_appcache_helper.h b/chrome/browser/browsing_data_appcache_helper.h new file mode 100644 index 0000000..8c28d40 --- /dev/null +++ b/chrome/browser/browsing_data_appcache_helper.h @@ -0,0 +1,72 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BROWSING_DATA_APPCACHE_HELPER_H_ +#define CHROME_BROWSER_BROWSING_DATA_APPCACHE_HELPER_H_ + +#include <string> +#include <vector> + +#include "base/scoped_ptr.h" +#include "base/task.h" +#include "chrome/common/appcache/chrome_appcache_service.h" + +class Profile; + +// This class fetches appcache information on behalf of a caller +// on the UI thread. +class BrowsingDataAppCacheHelper + : public base::RefCountedThreadSafe<BrowsingDataAppCacheHelper> { + public: + // Contains detailed information about an appcache. + struct AppCacheInfo { + AppCacheInfo() {} + AppCacheInfo(const GURL& manifest_url, + int64 size, + base::Time creation_time, + base::Time last_access_time, + int64 group_id) + : manifest_url(manifest_url), + size(size), + creation_time(creation_time), + last_access_time(last_access_time), + group_id(group_id) { + } + + GURL manifest_url; + int64 size; + base::Time creation_time; + base::Time last_access_time; + int64 group_id; + }; + + explicit BrowsingDataAppCacheHelper(Profile* profile); + + virtual void StartFetching(Callback0::Type* completion_callback); + virtual void CancelNotification(); + virtual void DeleteAppCache(int64 group_id); + + const std::vector<AppCacheInfo>& info_list() const { + DCHECK(!is_fetching_); + return info_list_; + } + + private: + friend class base::RefCountedThreadSafe<BrowsingDataAppCacheHelper>; + friend class MockBrowsingDataAppCacheHelper; + + virtual ~BrowsingDataAppCacheHelper() {} + + void StartFetchingInIOThread(); + void OnFetchComplete(); + void DeleteAppCacheInIOThread(int64 group_id); + + bool is_fetching_; + std::vector<AppCacheInfo> info_list_; + scoped_ptr<Callback0::Type> completion_callback_; + + DISALLOW_COPY_AND_ASSIGN(BrowsingDataAppCacheHelper); +}; + +#endif // CHROME_BROWSER_BROWSING_DATA_APPCACHE_HELPER_H_ diff --git a/chrome/browser/browsing_data_database_helper.cc b/chrome/browser/browsing_data_database_helper.cc index 2898a77..5350938 100644 --- a/chrome/browser/browsing_data_database_helper.cc +++ b/chrome/browser/browsing_data_database_helper.cc @@ -86,8 +86,10 @@ void BrowsingDataDatabaseHelper::NotifyInUIThread() { DCHECK(is_fetching_); // Note: completion_callback_ mutates only in the UI thread, so it's safe to // test it here. - if (completion_callback_ != NULL) + if (completion_callback_ != NULL) { completion_callback_->Run(database_info_); + completion_callback_.reset(); + } is_fetching_ = false; database_info_.clear(); } diff --git a/chrome/browser/browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data_local_storage_helper.cc index c952648..dfb2da0 100644 --- a/chrome/browser/browsing_data_local_storage_helper.cc +++ b/chrome/browser/browsing_data_local_storage_helper.cc @@ -96,8 +96,10 @@ void BrowsingDataLocalStorageHelper::NotifyInUIThread() { DCHECK(is_fetching_); // Note: completion_callback_ mutates only in the UI thread, so it's safe to // test it here. - if (completion_callback_ != NULL) + if (completion_callback_ != NULL) { completion_callback_->Run(local_storage_info_); + completion_callback_.reset(); + } is_fetching_ = false; } diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc index 562a609..435c3d7 100644 --- a/chrome/browser/browsing_data_remover.cc +++ b/chrome/browser/browsing_data_remover.cc @@ -143,6 +143,8 @@ void BrowsingDataRemover::Remove(int remove_mask) { net::TransportSecurityState* ts_state = profile_->GetTransportSecurityState(); ts_state->DeleteSince(delete_begin_); + + // TODO(michaeln): clear appcaches created in the date range } if (remove_mask & REMOVE_PASSWORDS) { diff --git a/chrome/browser/cocoa/cookies_window_controller.mm b/chrome/browser/cocoa/cookies_window_controller.mm index 70fddc7..b9fbc59 100644 --- a/chrome/browser/cocoa/cookies_window_controller.mm +++ b/chrome/browser/cocoa/cookies_window_controller.mm @@ -391,7 +391,7 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { // clobbered, we rebuild the icon cache for safety (though they do not change). - (void)loadTreeModelFromProfile { treeModel_.reset(new CookiesTreeModel(profile_, databaseHelper_, - storageHelper_)); + storageHelper_, nil)); modelObserver_.reset(new CookiesTreeModelObserverBridge(self)); treeModel_->AddObserver(modelObserver_.get()); diff --git a/chrome/browser/cocoa/cookies_window_controller_unittest.mm b/chrome/browser/cocoa/cookies_window_controller_unittest.mm index deff1ee..69757cf 100644 --- a/chrome/browser/cocoa/cookies_window_controller_unittest.mm +++ b/chrome/browser/cocoa/cookies_window_controller_unittest.mm @@ -135,7 +135,7 @@ TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeCookie) { net::CookieMonster* cm = browser_helper_.profile()->GetCookieMonster(); cm->SetCookie(GURL("http://foo.com"), "A=B"); CookiesTreeModel model(browser_helper_.profile(), database_helper_, - local_storage_helper_); + local_storage_helper_, nil); // Root --> foo.com --> Cookies --> A. Create node for 'A'. TreeModelNode* node = model.GetRoot()->GetChild(0)->GetChild(0)->GetChild(0); @@ -157,7 +157,7 @@ TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeRecursive) { net::CookieMonster* cm = browser_helper_.profile()->GetCookieMonster(); cm->SetCookie(GURL("http://foo.com"), "A=B"); CookiesTreeModel model(browser_helper_.profile(), database_helper_, - local_storage_helper_); + local_storage_helper_, nil); // Root --> foo.com --> Cookies --> A. Create node for 'foo.com'. CookieTreeNode* node = model.GetRoot()->GetChild(0); diff --git a/chrome/browser/cookies_tree_model.cc b/chrome/browser/cookies_tree_model.cc index 99cc0ad..c911b00 100644 --- a/chrome/browser/cookies_tree_model.cc +++ b/chrome/browser/cookies_tree_model.cc @@ -76,12 +76,12 @@ class OriginNodeComparator { // google.com, ad.google.com, www.google.com, // microsoft.com, ad.microsoft.com. CanonicalizeHost transforms the origins // into a form like google.com.www so that string comparisons work. - return (CanonicalizeHost(lhs->GetTitle()) < - CanonicalizeHost(rhs->GetTitle())); + return (CanonicalizeHost(lhs->GetTitleAsString16()) < + CanonicalizeHost(rhs->GetTitleAsString16())); } private: - static std::string CanonicalizeHost(const std::wstring& host_w) { + static std::string CanonicalizeHost(const string16& host16) { // The canonicalized representation makes the registry controlled domain // come first, and then adds subdomains in reverse order, e.g. // 1.mail.google.com would become google.com.mail.1, and then a standard @@ -89,7 +89,7 @@ class OriginNodeComparator { // first. Leading dots are ignored, ".google.com" is the same as // "google.com". - std::string host = WideToUTF8(host_w); + std::string host = UTF16ToUTF8(host16); std::string retval = net::RegistryControlledDomainService:: GetDomainAndRegistry(host); if (!retval.length()) // Is an IP address or other special origin. @@ -126,13 +126,27 @@ class OriginNodeComparator { } // namespace /////////////////////////////////////////////////////////////////////////////// +// CookieTreeAppCacheNode, public: + +CookieTreeAppCacheNode::CookieTreeAppCacheNode( + const BrowsingDataAppCacheHelper::AppCacheInfo* appcache_info) + : CookieTreeNode(UTF8ToWide(appcache_info->manifest_url.spec())), + appcache_info_(appcache_info) { +} + +void CookieTreeAppCacheNode::DeleteStoredObjects() { + DCHECK(GetModel()->appcache_helper_); + GetModel()->appcache_helper_->DeleteAppCache(appcache_info_->group_id); +} + +/////////////////////////////////////////////////////////////////////////////// // CookieTreeDatabaseNode, public: CookieTreeDatabaseNode::CookieTreeDatabaseNode( BrowsingDataDatabaseHelper::DatabaseInfo* database_info) - : CookieTreeNode(UTF8ToWide(database_info->database_name.empty() ? - database_info->origin_identifier : - database_info->database_name)), + : CookieTreeNode(database_info->database_name.empty() ? + l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) : + UTF8ToWide(database_info->database_name)), database_info_(database_info) { } @@ -162,7 +176,7 @@ void CookieTreeLocalStorageNode::DeleteStoredObjects() { // CookieTreeRootNode, public: CookieTreeOriginNode* CookieTreeRootNode::GetOrCreateOriginNode( const std::wstring& origin) { - // Strip the trailing dot if it exists. + // Strip the leading dot if it exists. std::wstring rewritten_origin = origin; if (origin.length() >= 1 && origin[0] == '.') rewritten_origin = origin.substr(1); @@ -193,55 +207,48 @@ CookieTreeOriginNode* CookieTreeRootNode::GetOrCreateOriginNode( CookieTreeCookiesNode* CookieTreeOriginNode::GetOrCreateCookiesNode() { if (cookies_child_) return cookies_child_; - // need to make a Cookies node, add it to the tree, and return it - CookieTreeCookiesNode* retval = new CookieTreeCookiesNode; - GetModel()->Add(this, 0, retval); - cookies_child_ = retval; - return retval; + cookies_child_ = new CookieTreeCookiesNode; + AddChildSortedByTitle(cookies_child_); + return cookies_child_; } -CookieTreeDatabasesNode* - CookieTreeOriginNode::GetOrCreateDatabasesNode() { +CookieTreeDatabasesNode* CookieTreeOriginNode::GetOrCreateDatabasesNode() { if (databases_child_) return databases_child_; - // Need to make a Database node, add it to the tree, and return it. - CookieTreeDatabasesNode* retval = new CookieTreeDatabasesNode; - GetModel()->Add(this, cookies_child_ ? 1 : 0, retval); - databases_child_ = retval; - return retval; + databases_child_ = new CookieTreeDatabasesNode; + AddChildSortedByTitle(databases_child_); + return databases_child_; } 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; - int index = 0; - if (cookies_child_) - ++index; - if (databases_child_) - ++index; - GetModel()->Add(this, index, retval); - local_storages_child_ = retval; - return retval; + local_storages_child_ = new CookieTreeLocalStoragesNode; + AddChildSortedByTitle(local_storages_child_); + return local_storages_child_; +} + +CookieTreeAppCachesNode* CookieTreeOriginNode::GetOrCreateAppCachesNode() { + if (appcaches_child_) + return appcaches_child_; + appcaches_child_ = new CookieTreeAppCachesNode; + AddChildSortedByTitle(appcaches_child_); + return appcaches_child_; } /////////////////////////////////////////////////////////////////////////////// // CookieTreeCookiesNode, public: CookieTreeCookiesNode::CookieTreeCookiesNode() - : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_COOKIES)) {} + : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_COOKIES)) { +} +/////////////////////////////////////////////////////////////////////////////// +// CookieTreeAppCachesNode, public: -void CookieTreeCookiesNode::AddCookieNode( - CookieTreeCookieNode* new_child) { - std::vector<CookieTreeNode*>::iterator cookie_iterator = - lower_bound(children().begin(), - children().end(), - new_child, - CookieTreeCookieNode::CookieNodeComparator()); - GetModel()->Add(this, (cookie_iterator - children().begin()), new_child); +CookieTreeAppCachesNode::CookieTreeAppCachesNode() + : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_APPLICATION_CACHES)) { } /////////////////////////////////////////////////////////////////////////////// @@ -251,18 +258,6 @@ CookieTreeDatabasesNode::CookieTreeDatabasesNode() : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_WEB_DATABASES)) { } -void CookieTreeDatabasesNode::AddDatabaseNode( - CookieTreeDatabaseNode* new_child) { - std::vector<CookieTreeNode*>::iterator database_iterator = - lower_bound(children().begin(), - children().end(), - new_child, - CookieTreeDatabaseNode::CookieNodeComparator()); - GetModel()->Add(this, - (database_iterator - children().begin()), - new_child); -} - /////////////////////////////////////////////////////////////////////////////// // CookieTreeLocalStoragesNode, public: @@ -270,54 +265,25 @@ 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) { - 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()); -} - /////////////////////////////////////////////////////////////////////////////// -// CookieTreeDatabaseNode, private +// CookieTreeNode, protected -bool CookieTreeDatabaseNode::CookieNodeComparator::operator() ( +bool CookieTreeNode::NodeTitleComparator::operator() ( const CookieTreeNode* lhs, const CookieTreeNode* rhs) { - const CookieTreeDatabaseNode* left = - static_cast<const CookieTreeDatabaseNode*>(lhs); - const CookieTreeDatabaseNode* right = - static_cast<const CookieTreeDatabaseNode*>(rhs); - return (left->database_info_->database_name < - right->database_info_->database_name); + const CookieTreeNode* left = + static_cast<const CookieTreeNode*>(lhs); + const CookieTreeNode* right = + static_cast<const CookieTreeNode*>(rhs); + return (left->GetTitleAsString16() < right->GetTitleAsString16()); } -/////////////////////////////////////////////////////////////////////////////// -// 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); +void CookieTreeNode::AddChildSortedByTitle(CookieTreeNode* new_child) { + std::vector<CookieTreeNode*>::iterator iter = + lower_bound(children().begin(), + children().end(), + new_child, + NodeTitleComparator()); + GetModel()->Add(this, iter - children().begin(), new_child); } /////////////////////////////////////////////////////////////////////////////// @@ -326,10 +292,12 @@ bool CookieTreeLocalStorageNode::CookieNodeComparator::operator() ( CookiesTreeModel::CookiesTreeModel( Profile* profile, BrowsingDataDatabaseHelper* database_helper, - BrowsingDataLocalStorageHelper* local_storage_helper) + BrowsingDataLocalStorageHelper* local_storage_helper, + BrowsingDataAppCacheHelper* appcache_helper) : ALLOW_THIS_IN_INITIALIZER_LIST(TreeNodeModel<CookieTreeNode>( new CookieTreeRootNode(this))), profile_(profile), + appcache_helper_(appcache_helper), database_helper_(database_helper), local_storage_helper_(local_storage_helper) { LoadCookies(); @@ -339,11 +307,20 @@ CookiesTreeModel::CookiesTreeModel( DCHECK(local_storage_helper_); local_storage_helper_->StartFetching(NewCallback( this, &CookiesTreeModel::OnStorageModelInfoLoaded)); + + // TODO(michaeln): when all of the ui impls have been updated, + // make this a required parameter. + if (appcache_helper_) { + appcache_helper_->StartFetching(NewCallback( + this, &CookiesTreeModel::OnAppCacheModelInfoLoaded)); + } } CookiesTreeModel::~CookiesTreeModel() { database_helper_->CancelNotification(); local_storage_helper_->CancelNotification(); + if (appcache_helper_) + appcache_helper_->CancelNotification(); } /////////////////////////////////////////////////////////////////////////////// @@ -377,9 +354,10 @@ int CookiesTreeModel::GetIconIndex(TreeModelNode* node) { return DATABASE; break; case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: - // The differences between local storage and HTML5 databases are semantic - // enough that the user will not likely care if they share an icon. - return DATABASE; + return DATABASE; // close enough + break; + case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: + return DATABASE; // ditto break; default: return -1; @@ -439,6 +417,32 @@ void CookiesTreeModel::UpdateSearchResults(const std::wstring& filter) { LoadCookiesWithFilter(filter); PopulateDatabaseInfoWithFilter(filter); PopulateLocalStorageInfoWithFilter(filter); + PopulateAppCacheInfoWithFilter(filter); + NotifyObserverTreeNodeChanged(root); +} + +void CookiesTreeModel::OnAppCacheModelInfoLoaded() { + PopulateAppCacheInfoWithFilter(std::wstring()); +} + +void CookiesTreeModel::PopulateAppCacheInfoWithFilter( + const std::wstring& filter) { + if (!appcache_helper_ || appcache_helper_->info_list().empty()) + return; + CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); + for (AppCacheInfoList::const_iterator info = + appcache_helper_->info_list().begin(); + info != appcache_helper_->info_list().end(); ++info) { + std::wstring host = UTF8ToWide(info->manifest_url.host()); + if (filter.empty() || (host.find(filter) != std::wstring::npos)) { + CookieTreeOriginNode* host_node = + root->GetOrCreateOriginNode(host); + CookieTreeAppCachesNode* appcaches_node = + host_node->GetOrCreateAppCachesNode(); + appcaches_node->AddAppCacheNode( + new CookieTreeAppCacheNode(&(*info))); + } + } NotifyObserverTreeNodeChanged(root); } @@ -450,6 +454,8 @@ void CookiesTreeModel::OnDatabaseModelInfoLoaded( void CookiesTreeModel::PopulateDatabaseInfoWithFilter( const std::wstring& filter) { + if (database_info_list_.empty()) + return; CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); for (DatabaseInfoList::iterator database_info = database_info_list_.begin(); database_info != database_info_list_.end(); @@ -477,6 +483,8 @@ void CookiesTreeModel::OnStorageModelInfoLoaded( void CookiesTreeModel::PopulateLocalStorageInfoWithFilter( const std::wstring& filter) { + if (local_storage_info_list_.empty()) + return; CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); for (LocalStorageInfoList::iterator local_storage_info = local_storage_info_list_.begin(); diff --git a/chrome/browser/cookies_tree_model.h b/chrome/browser/cookies_tree_model.h index 1d1d8bb..4ec687d 100644 --- a/chrome/browser/cookies_tree_model.h +++ b/chrome/browser/cookies_tree_model.h @@ -10,17 +10,20 @@ #include "app/tree_node_model.h" #include "base/scoped_ptr.h" +#include "chrome/browser/browsing_data_appcache_helper.h" #include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" #include "net/base/cookie_monster.h" class CookiesTreeModel; -class CookieTreeLocalStorageNode; -class CookieTreeLocalStoragesNode; -class CookieTreeDatabaseNode; -class CookieTreeDatabasesNode; +class CookieTreeAppCacheNode; +class CookieTreeAppCachesNode; class CookieTreeCookieNode; class CookieTreeCookiesNode; +class CookieTreeDatabaseNode; +class CookieTreeDatabasesNode; +class CookieTreeLocalStorageNode; +class CookieTreeLocalStoragesNode; class CookieTreeOriginNode; class Profile; @@ -44,22 +47,25 @@ class CookieTreeNode : public TreeNode<CookieTreeNode> { TYPE_DATABASE, // This is used for CookieTreeDatabaseNode. TYPE_LOCAL_STORAGES, // This is used for CookieTreeLocalStoragesNode. TYPE_LOCAL_STORAGE, // This is used for CookieTreeLocalStorageNode. + TYPE_APPCACHES, // This is used for CookieTreeAppCachesNode. + TYPE_APPCACHE, // This is used for CookieTreeAppCacheNode. }; DetailedInfo(const std::wstring& origin, NodeType node_type, const net::CookieMonster::CookieListPair* cookie, const BrowsingDataDatabaseHelper::DatabaseInfo* database_info, const BrowsingDataLocalStorageHelper::LocalStorageInfo* - local_storage_info) + local_storage_info, + const BrowsingDataAppCacheHelper::AppCacheInfo* appcache_info) : origin(origin), node_type(node_type), cookie(cookie), database_info(database_info), - local_storage_info(local_storage_info) { - if (node_type == TYPE_DATABASE) - DCHECK(database_info); - if (node_type == TYPE_LOCAL_STORAGE) - DCHECK(local_storage_info); + local_storage_info(local_storage_info), + appcache_info(appcache_info) { + DCHECK((node_type != TYPE_DATABASE) || database_info); + DCHECK((node_type != TYPE_LOCAL_STORAGE) || local_storage_info); + DCHECK((node_type != TYPE_APPCACHE) || appcache_info); } std::wstring origin; @@ -67,11 +73,13 @@ class CookieTreeNode : public TreeNode<CookieTreeNode> { const net::CookieMonster::CookieListPair* cookie; const BrowsingDataDatabaseHelper::DatabaseInfo* database_info; const BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info; + const BrowsingDataAppCacheHelper::AppCacheInfo* appcache_info; }; CookieTreeNode() {} explicit CookieTreeNode(const std::wstring& title) : TreeNode<CookieTreeNode>(title) {} + virtual ~CookieTreeNode() {} // Delete backend storage for this node, and any children nodes. (E.g. delete // the cookie from CookieMonster, clear the database, and so forth.) @@ -84,6 +92,14 @@ class CookieTreeNode : public TreeNode<CookieTreeNode> { // part of the view. virtual DetailedInfo GetDetailedInfo() const = 0; + protected: + class NodeTitleComparator { + public: + bool operator() (const CookieTreeNode* lhs, const CookieTreeNode* rhs); + }; + + void AddChildSortedByTitle(CookieTreeNode* new_child); + private: DISALLOW_COPY_AND_ASSIGN(CookieTreeNode); @@ -102,7 +118,7 @@ class CookieTreeRootNode : public CookieTreeNode { virtual CookiesTreeModel* GetModel() const { return model_; } virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(std::wstring(), DetailedInfo::TYPE_ROOT, NULL, NULL, - NULL); + NULL, NULL); } private: @@ -118,22 +134,23 @@ class CookieTreeOriginNode : public CookieTreeNode { : CookieTreeNode(origin), cookies_child_(NULL), databases_child_(NULL), - local_storages_child_(NULL) {} + local_storages_child_(NULL), + appcaches_child_(NULL) {} virtual ~CookieTreeOriginNode() {} // CookieTreeNode methods: virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetTitle(), DetailedInfo::TYPE_ORIGIN, NULL, NULL, - NULL); + NULL, NULL); } // CookieTreeOriginNode methods: CookieTreeCookiesNode* GetOrCreateCookiesNode(); CookieTreeDatabasesNode* GetOrCreateDatabasesNode(); CookieTreeLocalStoragesNode* GetOrCreateLocalStoragesNode(); + CookieTreeAppCachesNode* GetOrCreateAppCachesNode(); private: - // A pointer to the COOKIES node. Eventually we will also have database, // appcache, local storage, ..., and when we build up the tree we need to // quickly get a reference to the COOKIES node to add children. Checking each @@ -143,80 +160,97 @@ class CookieTreeOriginNode : public CookieTreeNode { CookieTreeCookiesNode* cookies_child_; CookieTreeDatabasesNode* databases_child_; CookieTreeLocalStoragesNode* local_storages_child_; + CookieTreeAppCachesNode* appcaches_child_; DISALLOW_COPY_AND_ASSIGN(CookieTreeOriginNode); }; -// CookieTreeCookiesNode ------------------------------------------------------ +// CookieTreeCookieNode ------------------------------------------------------ +class CookieTreeCookieNode : public CookieTreeNode { + public: + friend class CookieTreeCookiesNode; + + // Does not take ownership of cookie, and cookie should remain valid at least + // as long as the CookieTreeCookieNode is valid. + explicit CookieTreeCookieNode(net::CookieMonster::CookieListPair* cookie); + virtual ~CookieTreeCookieNode() {} + + // CookieTreeNode methods: + virtual void DeleteStoredObjects(); + virtual DetailedInfo GetDetailedInfo() const { + return DetailedInfo(GetParent()->GetParent()->GetTitle(), + DetailedInfo::TYPE_COOKIE, cookie_, NULL, NULL, NULL); + } + + private: + // Cookie_ is not owned by the node, and is expected to remain valid as long + // as the CookieTreeCookieNode is valid. + net::CookieMonster::CookieListPair* cookie_; + + DISALLOW_COPY_AND_ASSIGN(CookieTreeCookieNode); +}; + class CookieTreeCookiesNode : public CookieTreeNode { public: CookieTreeCookiesNode(); virtual ~CookieTreeCookiesNode() {} - // CookieTreeNode methods: virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetTitle(), DetailedInfo::TYPE_COOKIES, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); } - // CookieTreeCookiesNode methods: - void AddCookieNode(CookieTreeCookieNode* child); + void AddCookieNode(CookieTreeCookieNode* child) { + AddChildSortedByTitle(child); + } private: DISALLOW_COPY_AND_ASSIGN(CookieTreeCookiesNode); }; -class CookieTreeCookieNode : public CookieTreeNode { +// CookieTreeAppCacheNode ----------------------------------------------------- +class CookieTreeAppCacheNode : public CookieTreeNode { public: - friend class CookieTreeCookiesNode; + friend class CookieTreeAppCachesNode; - // Does not take ownership of cookie, and cookie should remain valid at least - // as long as the CookieTreeCookieNode is valid. - explicit CookieTreeCookieNode(net::CookieMonster::CookieListPair* cookie); - virtual ~CookieTreeCookieNode() {} + // Does not take ownership of appcache_info, and appcache_info should remain + // valid at least as long as the CookieTreeAppCacheNode is valid. + explicit CookieTreeAppCacheNode( + const BrowsingDataAppCacheHelper::AppCacheInfo* appcache_info); + virtual ~CookieTreeAppCacheNode() {} - // CookieTreeNode methods: virtual void DeleteStoredObjects(); virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetParent()->GetTitle(), - DetailedInfo::TYPE_COOKIE, cookie_, NULL, NULL); + DetailedInfo::TYPE_APPCACHE, + NULL, NULL, NULL, appcache_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); - }; - - // Cookie_ is not owned by the node, and is expected to remain valid as long - // as the CookieTreeCookieNode is valid. - net::CookieMonster::CookieListPair* cookie_; - - DISALLOW_COPY_AND_ASSIGN(CookieTreeCookieNode); + const BrowsingDataAppCacheHelper::AppCacheInfo* appcache_info_; + DISALLOW_COPY_AND_ASSIGN(CookieTreeAppCacheNode); }; -// CookieTreeDatabasesNode ----------------------------------------------------- -class CookieTreeDatabasesNode : public CookieTreeNode { +class CookieTreeAppCachesNode : public CookieTreeNode { public: - CookieTreeDatabasesNode(); - virtual ~CookieTreeDatabasesNode() {} + CookieTreeAppCachesNode(); + virtual ~CookieTreeAppCachesNode() {} - // CookieTreeNode methods: virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetTitle(), - DetailedInfo::TYPE_DATABASES, - NULL, NULL, NULL); + DetailedInfo::TYPE_APPCACHES, + NULL, NULL, NULL, NULL); } - // CookieTreeDatabases methods: - void AddDatabaseNode(CookieTreeDatabaseNode* child); + void AddAppCacheNode(CookieTreeAppCacheNode* child) { + AddChildSortedByTitle(child); + } private: - DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabasesNode); + DISALLOW_COPY_AND_ASSIGN(CookieTreeAppCachesNode); }; +// CookieTreeDatabaseNode ----------------------------------------------------- class CookieTreeDatabaseNode : public CookieTreeNode { public: friend class CookieTreeDatabasesNode; @@ -227,22 +261,14 @@ class CookieTreeDatabaseNode : public CookieTreeNode { BrowsingDataDatabaseHelper::DatabaseInfo* database_info); virtual ~CookieTreeDatabaseNode() {} - // CookieTreeStorageNode methods: virtual void DeleteStoredObjects(); virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetParent()->GetTitle(), DetailedInfo::TYPE_DATABASE, NULL, database_info_, - NULL); + NULL, NULL); } 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); - }; - // database_info_ is not owned by the node, and is expected to remain // valid as long as the CookieTreeDatabaseNode is valid. BrowsingDataDatabaseHelper::DatabaseInfo* database_info_; @@ -250,26 +276,27 @@ class CookieTreeDatabaseNode : public CookieTreeNode { DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabaseNode); }; -// CookieTreeLocalStoragesNode ------------------------------------------------- -class CookieTreeLocalStoragesNode : public CookieTreeNode { +class CookieTreeDatabasesNode : public CookieTreeNode { public: - CookieTreeLocalStoragesNode(); - virtual ~CookieTreeLocalStoragesNode() {} + CookieTreeDatabasesNode(); + virtual ~CookieTreeDatabasesNode() {} - // CookieTreeNode methods: virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetTitle(), - DetailedInfo::TYPE_LOCAL_STORAGES, - NULL, NULL, NULL); + DetailedInfo::TYPE_DATABASES, + NULL, NULL, NULL, NULL); } - // CookieTreeStoragesNode methods: - void AddLocalStorageNode(CookieTreeLocalStorageNode* child); + void AddDatabaseNode(CookieTreeDatabaseNode* child) { + AddChildSortedByTitle(child); + } private: - DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStoragesNode); + DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabasesNode); }; + +// CookieTreeLocalStorageNode ------------------------------------------------- class CookieTreeLocalStorageNode : public CookieTreeNode { public: friend class CookieTreeLocalStoragesNode; @@ -285,17 +312,10 @@ class CookieTreeLocalStorageNode : public CookieTreeNode { virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetParent()->GetTitle(), DetailedInfo::TYPE_LOCAL_STORAGE, NULL, NULL, - local_storage_info_); + local_storage_info_, NULL); } 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_; @@ -303,12 +323,32 @@ class CookieTreeLocalStorageNode : public CookieTreeNode { DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStorageNode); }; +class CookieTreeLocalStoragesNode : public CookieTreeNode { + public: + CookieTreeLocalStoragesNode(); + virtual ~CookieTreeLocalStoragesNode() {} + + virtual DetailedInfo GetDetailedInfo() const { + return DetailedInfo(GetParent()->GetTitle(), + DetailedInfo::TYPE_LOCAL_STORAGES, + NULL, NULL, NULL, NULL); + } + + void AddLocalStorageNode(CookieTreeLocalStorageNode* child) { + AddChildSortedByTitle(child); + } + + private: + DISALLOW_COPY_AND_ASSIGN(CookieTreeLocalStoragesNode); +}; + class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> { public: CookiesTreeModel( Profile* profile, - BrowsingDataDatabaseHelper* browsing_data_database_helper, - BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper); + BrowsingDataDatabaseHelper* database_helper, + BrowsingDataLocalStorageHelper* local_storage_helper, + BrowsingDataAppCacheHelper* appcache_helper); virtual ~CookiesTreeModel(); // TreeModel methods: @@ -332,11 +372,12 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> { enum CookieIconIndex { ORIGIN = 0, COOKIE = 1, - DATABASE = 2, - LOCAL_STORAGE = 3, + DATABASE = 2 }; typedef net::CookieMonster::CookieList CookieList; typedef std::vector<net::CookieMonster::CookieListPair*> CookiePtrList; + typedef std::vector<BrowsingDataAppCacheHelper::AppCacheInfo> + AppCacheInfoList; typedef std::vector<BrowsingDataDatabaseHelper::DatabaseInfo> DatabaseInfoList; typedef std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo> @@ -345,24 +386,26 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> { void LoadCookies(); void LoadCookiesWithFilter(const std::wstring& filter); + void OnAppCacheModelInfoLoaded(); void OnDatabaseModelInfoLoaded(const DatabaseInfoList& database_info); - void OnStorageModelInfoLoaded(const LocalStorageInfoList& local_storage_info); + void PopulateAppCacheInfoWithFilter(const std::wstring& filter); void PopulateDatabaseInfoWithFilter(const std::wstring& filter); - void PopulateLocalStorageInfoWithFilter(const std::wstring& filter); // The profile from which this model sources cookies. Profile* profile_; CookieList all_cookies_; + scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper_; scoped_refptr<BrowsingDataDatabaseHelper> database_helper_; DatabaseInfoList database_info_list_; scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper_; LocalStorageInfoList local_storage_info_list_; + friend class CookieTreeAppCacheNode; friend class CookieTreeCookieNode; friend class CookieTreeDatabaseNode; friend class CookieTreeLocalStorageNode; diff --git a/chrome/browser/cookies_tree_model_unittest.cc b/chrome/browser/cookies_tree_model_unittest.cc index 925a141..6e026b8 100644 --- a/chrome/browser/cookies_tree_model_unittest.cc +++ b/chrome/browser/cookies_tree_model_unittest.cc @@ -7,6 +7,7 @@ #include <string> #include "app/l10n_util.h" +#include "chrome/browser/mock_browsing_data_appcache_helper.h" #include "chrome/browser/mock_browsing_data_database_helper.h" #include "chrome/browser/mock_browsing_data_local_storage_helper.h" #include "chrome/browser/net/url_request_context_getter.h" @@ -32,6 +33,8 @@ class CookiesTreeModelTest : public testing::Test { new MockBrowsingDataDatabaseHelper(profile_.get()); mock_browsing_data_local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile_.get()); + mock_browsing_data_appcache_helper_ = + new MockBrowsingDataAppCacheHelper(profile_.get()); } CookiesTreeModel* CreateCookiesTreeModelWithInitialSample() { @@ -41,7 +44,8 @@ class CookiesTreeModelTest : public testing::Test { monster->SetCookie(GURL("http://foo3"), "C=1"); CookiesTreeModel* cookies_model = new CookiesTreeModel( profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -91,6 +95,9 @@ class CookiesTreeModelTest : public testing::Test { return node->GetDetailedInfo().database_info->database_name + ","; case CookieTreeNode::DetailedInfo::TYPE_COOKIE: return node->GetDetailedInfo().cookie->second.Name() + ","; + case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: + return node->GetDetailedInfo().appcache_info->manifest_url.spec() + + ","; default: return ""; } @@ -142,6 +149,11 @@ class CookiesTreeModelTest : public testing::Test { CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE); } + std::string GetDisplayedAppCaches(CookiesTreeModel* cookies_model) { + return GetDisplayedNodes(cookies_model, + CookieTreeNode::DetailedInfo::TYPE_APPCACHE); + } + // do not call on the root void DeleteStoredObjects(CookieTreeNode* node) { node->DeleteStoredObjects(); @@ -160,6 +172,8 @@ class CookiesTreeModelTest : public testing::Test { mock_browsing_data_database_helper_; scoped_refptr<MockBrowsingDataLocalStorageHelper> mock_browsing_data_local_storage_helper_; + scoped_refptr<MockBrowsingDataAppCacheHelper> + mock_browsing_data_appcache_helper_; }; TEST_F(CookiesTreeModelTest, RemoveAll) { @@ -327,7 +341,8 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNode) { monster->SetCookie(GURL("http://foo3"), "D=1"); CookiesTreeModel cookies_model(profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -365,7 +380,8 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNodeOf3) { monster->SetCookie(GURL("http://foo3"), "E=1"); CookiesTreeModel cookies_model(profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -403,8 +419,9 @@ TEST_F(CookiesTreeModelTest, RemoveSecondOrigin) { monster->SetCookie(GURL("http://foo3"), "D=1"); monster->SetCookie(GURL("http://foo3"), "E=1"); CookiesTreeModel cookies_model(profile_.get(), - mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); { SCOPED_TRACE("Initial State 5 cookies"); // 11 because there's the root, then foo1 -> cookies -> a, @@ -437,7 +454,8 @@ TEST_F(CookiesTreeModelTest, OriginOrdering) { CookiesTreeModel cookies_model(profile_.get(), new MockBrowsingDataDatabaseHelper(profile_.get()), - new MockBrowsingDataLocalStorageHelper(profile_.get())); + new MockBrowsingDataLocalStorageHelper(profile_.get()), + new MockBrowsingDataAppCacheHelper(profile_.get())); { SCOPED_TRACE("Initial State 8 cookies"); @@ -454,6 +472,4 @@ TEST_F(CookiesTreeModelTest, OriginOrdering) { } } - - } // namespace diff --git a/chrome/browser/gtk/options/cookie_filter_page_gtk.cc b/chrome/browser/gtk/options/cookie_filter_page_gtk.cc index 97ce956..07de705 100644 --- a/chrome/browser/gtk/options/cookie_filter_page_gtk.cc +++ b/chrome/browser/gtk/options/cookie_filter_page_gtk.cc @@ -210,6 +210,8 @@ void CookieFilterPageGtk::OnShowCookiesClicked( new BrowsingDataDatabaseHelper( cookie_page->profile()), new BrowsingDataLocalStorageHelper( + cookie_page->profile()), + new BrowsingDataAppCacheHelper( cookie_page->profile())); } diff --git a/chrome/browser/gtk/options/cookies_view.cc b/chrome/browser/gtk/options/cookies_view.cc index 8b7f105..a5735f7 100644 --- a/chrome/browser/gtk/options/cookies_view.cc +++ b/chrome/browser/gtk/options/cookies_view.cc @@ -61,10 +61,12 @@ void CookiesView::Show( GtkWindow* parent, Profile* profile, BrowsingDataDatabaseHelper* browsing_data_database_helper, - BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper) { + BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper, + BrowsingDataAppCacheHelper* browsing_data_appcache_helper) { DCHECK(profile); DCHECK(browsing_data_database_helper); DCHECK(browsing_data_local_storage_helper); + DCHECK(browsing_data_appcache_helper); // If there's already an existing editor window, activate it. if (instance_) { @@ -73,7 +75,8 @@ void CookiesView::Show( instance_ = new CookiesView(parent, profile, browsing_data_database_helper, - browsing_data_local_storage_helper); + browsing_data_local_storage_helper, + browsing_data_appcache_helper); instance_->InitStylesAndShow(); } } @@ -82,10 +85,12 @@ CookiesView::CookiesView( GtkWindow* parent, Profile* profile, BrowsingDataDatabaseHelper* browsing_data_database_helper, - BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper) + BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper, + BrowsingDataAppCacheHelper* browsing_data_appcache_helper) : profile_(profile), browsing_data_database_helper_(browsing_data_database_helper), browsing_data_local_storage_helper_(browsing_data_local_storage_helper), + browsing_data_appcache_helper_(browsing_data_appcache_helper), filter_update_factory_(this) { Init(parent); } @@ -179,7 +184,8 @@ void CookiesView::Init(GtkWindow* parent) { cookies_tree_model_.reset(new CookiesTreeModel(profile_, browsing_data_database_helper_, - browsing_data_local_storage_helper_)); + browsing_data_local_storage_helper_, + browsing_data_appcache_helper_)); cookies_tree_adapter_.reset( new gtk_tree::TreeAdapter(this, cookies_tree_model_.get())); tree_ = gtk_tree_view_new_with_model( @@ -244,13 +250,15 @@ void CookiesView::Init(GtkWindow* parent) { GTK_SHADOW_ETCHED_IN); gtk_box_pack_start(GTK_BOX(cookie_list_vbox), database_details_frame, FALSE, FALSE, 0); - database_details_table_ = gtk_table_new(3, 2, FALSE); + database_details_table_ = gtk_table_new(4, 2, FALSE); gtk_container_add(GTK_CONTAINER(database_details_frame), database_details_table_); gtk_table_set_col_spacing(GTK_TABLE(database_details_table_), 0, gtk_util::kLabelSpacing); row = 0; + InitDetailRow(row++, IDS_COOKIES_COOKIE_NAME_LABEL, + database_details_table_, &database_name_entry_); InitDetailRow(row++, IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL, database_details_table_, &database_description_entry_); InitDetailRow(row++, IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL, @@ -280,6 +288,27 @@ void CookiesView::Init(GtkWindow* parent) { local_storage_details_table_, &local_storage_last_modified_entry_); + // AppCache details. + GtkWidget* appcache_details_frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(appcache_details_frame), + GTK_SHADOW_ETCHED_IN); + gtk_box_pack_start(GTK_BOX(cookie_list_vbox), appcache_details_frame, + FALSE, FALSE, 0); + appcache_details_table_ = gtk_table_new(4, 2, FALSE); + gtk_container_add(GTK_CONTAINER(appcache_details_frame), + appcache_details_table_); + gtk_table_set_col_spacing(GTK_TABLE(appcache_details_table_), 0, + gtk_util::kLabelSpacing); + row = 0; + InitDetailRow(row++, IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL, + appcache_details_table_, &appcache_manifest_entry_); + InitDetailRow(row++, IDS_COOKIES_SIZE_LABEL, + appcache_details_table_, &appcache_size_entry_); + InitDetailRow(row++, IDS_COOKIES_COOKIE_CREATED_LABEL, + appcache_details_table_, &appcache_created_entry_); + InitDetailRow(row++, IDS_COOKIES_LAST_ACCESSED_LABEL, + appcache_details_table_, &appcache_last_accessed_entry_); + UpdateVisibleDetailedInfo(cookie_details_table_); // Populate the view. cookies_tree_adapter_->Init(); @@ -304,6 +333,7 @@ void CookiesView::InitStylesAndShow() { InitBrowserDetailStyle(cookie_expires_entry_, label_style, dialog_style); // Database details. + InitBrowserDetailStyle(database_name_entry_, label_style, dialog_style); InitBrowserDetailStyle(database_description_entry_, label_style, dialog_style); InitBrowserDetailStyle(database_size_entry_, label_style, dialog_style); @@ -317,6 +347,13 @@ void CookiesView::InitStylesAndShow() { InitBrowserDetailStyle(local_storage_last_modified_entry_, label_style, dialog_style); + // AppCache details. + InitBrowserDetailStyle(appcache_manifest_entry_, label_style, dialog_style); + InitBrowserDetailStyle(appcache_size_entry_, label_style, dialog_style); + InitBrowserDetailStyle(appcache_created_entry_, label_style, dialog_style); + InitBrowserDetailStyle(appcache_last_accessed_entry_, label_style, + dialog_style); + gtk_widget_show_all(dialog_); } @@ -368,6 +405,10 @@ void CookiesView::EnableControls() { CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { UpdateVisibleDetailedInfo(local_storage_details_table_); PopulateLocalStorageDetails(*detailed_info.local_storage_info); + } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_APPCACHE) { + UpdateVisibleDetailedInfo(appcache_details_table_); + PopulateAppCacheDetails(*detailed_info.appcache_info); } else { UpdateVisibleDetailedInfo(cookie_details_table_); ClearCookieDetails(); @@ -388,6 +429,7 @@ void CookiesView::SetCookieDetailsSensitivity(gboolean enabled) { } void CookiesView::SetDatabaseDetailsSensitivity(gboolean enabled) { + gtk_widget_set_sensitive(database_name_entry_, enabled); gtk_widget_set_sensitive(database_description_entry_, enabled); gtk_widget_set_sensitive(database_size_entry_, enabled); gtk_widget_set_sensitive(database_last_modified_entry_, enabled); @@ -399,6 +441,13 @@ void CookiesView::SetLocalStorageDetailsSensitivity(gboolean enabled) { gtk_widget_set_sensitive(local_storage_last_modified_entry_, enabled); } +void CookiesView::SetAppCacheDetailsSensitivity(gboolean enabled) { + gtk_widget_set_sensitive(appcache_manifest_entry_, enabled); + gtk_widget_set_sensitive(appcache_size_entry_, enabled); + gtk_widget_set_sensitive(appcache_created_entry_, enabled); + gtk_widget_set_sensitive(appcache_last_accessed_entry_, enabled); +} + void CookiesView::PopulateCookieDetails( const std::string& domain, const net::CookieMonster::CanonicalCookie& cookie) { @@ -428,6 +477,12 @@ void CookiesView::PopulateCookieDetails( void CookiesView::PopulateDatabaseDetails( const BrowsingDataDatabaseHelper::DatabaseInfo& database_info) { + gtk_entry_set_text( + GTK_ENTRY(database_name_entry_), + database_info.database_name.empty() ? + l10n_util::GetStringUTF8( + IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME).c_str() : + database_info.database_name.c_str()); gtk_entry_set_text(GTK_ENTRY(database_description_entry_), database_info.description.c_str()); gtk_entry_set_text(GTK_ENTRY(database_size_entry_), @@ -457,6 +512,24 @@ void CookiesView::PopulateLocalStorageDetails( SetLocalStorageDetailsSensitivity(TRUE); } +void CookiesView::PopulateAppCacheDetails( + const BrowsingDataAppCacheHelper::AppCacheInfo& info) { + gtk_entry_set_text(GTK_ENTRY(appcache_manifest_entry_), + info.manifest_url.spec().c_str()); + gtk_entry_set_text(GTK_ENTRY(appcache_size_entry_), + WideToUTF8(FormatBytes( + info.size, + GetByteDisplayUnits(info.size), + true)).c_str()); + gtk_entry_set_text(GTK_ENTRY(appcache_created_entry_), + WideToUTF8(base::TimeFormatFriendlyDateAndTime( + info.creation_time)).c_str()); + gtk_entry_set_text(GTK_ENTRY(appcache_last_accessed_entry_), + WideToUTF8(base::TimeFormatFriendlyDateAndTime( + info.last_access_time)).c_str()); + SetAppCacheDetailsSensitivity(TRUE); +} + void CookiesView::ClearCookieDetails() { std::string no_cookie = l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_NONESELECTED); @@ -572,6 +645,7 @@ void CookiesView::UpdateVisibleDetailedInfo(GtkWidget* table) { SetCookieDetailsSensitivity(table == cookie_details_table_); SetDatabaseDetailsSensitivity(table == database_details_table_); SetLocalStorageDetailsSensitivity(table == local_storage_details_table_); + SetAppCacheDetailsSensitivity(table == appcache_details_table_); // Toggle the parent (the table frame) visibility and sensitivity. gtk_widget_show(gtk_widget_get_parent(table)); // Toggle the other tables. @@ -581,6 +655,8 @@ void CookiesView::UpdateVisibleDetailedInfo(GtkWidget* table) { gtk_widget_hide(gtk_widget_get_parent(database_details_table_)); if (table != local_storage_details_table_) gtk_widget_hide(gtk_widget_get_parent(local_storage_details_table_)); + if (table != appcache_details_table_) + gtk_widget_hide(gtk_widget_get_parent(appcache_details_table_)); } // static diff --git a/chrome/browser/gtk/options/cookies_view.h b/chrome/browser/gtk/options/cookies_view.h index 80e768f..6aedbf6 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_appcache_helper.h" #include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" #include "chrome/common/gtk_tree.h" @@ -37,7 +38,8 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { GtkWindow* parent, Profile* profile, BrowsingDataDatabaseHelper* browsing_data_database_helper, - BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper); + BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper, + BrowsingDataAppCacheHelper* browsing_data_appcache_helper); // gtk_tree::TreeAdapter::Delegate implementation. virtual void OnAnyModelUpdateStart(); @@ -48,7 +50,8 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { GtkWindow* parent, Profile* profile, BrowsingDataDatabaseHelper* browsing_data_database_helper, - BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper); + BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper, + BrowsingDataAppCacheHelper* browsing_data_appcache_helper); // Initialize the dialog contents and layout. void Init(GtkWindow* parent); @@ -75,6 +78,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { // Set sensitivity of local storage details. void SetLocalStorageDetailsSensitivity(gboolean enabled); + // Set sensitivity of appcache details. + void SetAppCacheDetailsSensitivity(gboolean enabled); + // Show the details of the currently selected cookie. void PopulateCookieDetails(const std::string& domain, const net::CookieMonster::CanonicalCookie& cookie); @@ -88,6 +94,10 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { const BrowsingDataLocalStorageHelper::LocalStorageInfo& local_storage_info); + // Show the details of the currently selected appcache. + void PopulateAppCacheDetails( + const BrowsingDataAppCacheHelper::AppCacheInfo& info); + // Reset the cookie details display. void ClearCookieDetails(); @@ -151,6 +161,7 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { // The database details widgets. GtkWidget* database_details_table_; + GtkWidget* database_name_entry_; GtkWidget* database_description_entry_; GtkWidget* database_size_entry_; GtkWidget* database_last_modified_entry_; @@ -161,15 +172,19 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { GtkWidget* local_storage_size_entry_; GtkWidget* local_storage_last_modified_entry_; - // The profile. - Profile* profile_; + // The appcache details widgets. + GtkWidget* appcache_details_table_; + GtkWidget* appcache_manifest_entry_; + GtkWidget* appcache_size_entry_; + GtkWidget* appcache_created_entry_; + GtkWidget* appcache_last_accessed_entry_; - // Database Helper. + // The profile and related helpers. + Profile* profile_; scoped_refptr<BrowsingDataDatabaseHelper> browsing_data_database_helper_; - - // Local Storage Helper. scoped_refptr<BrowsingDataLocalStorageHelper> browsing_data_local_storage_helper_; + scoped_refptr<BrowsingDataAppCacheHelper> browsing_data_appcache_helper_; // A factory to construct Runnable Methods so that we can be called back to // re-evaluate the model after the search query string changes. diff --git a/chrome/browser/gtk/options/cookies_view_unittest.cc b/chrome/browser/gtk/options/cookies_view_unittest.cc index 00175c3..0c12dfd 100644 --- a/chrome/browser/gtk/options/cookies_view_unittest.cc +++ b/chrome/browser/gtk/options/cookies_view_unittest.cc @@ -10,6 +10,7 @@ #include <gtk/gtk.h> #include "base/string_util.h" +#include "chrome/browser/mock_browsing_data_appcache_helper.h" #include "chrome/browser/mock_browsing_data_database_helper.h" #include "chrome/browser/mock_browsing_data_local_storage_helper.h" #include "chrome/browser/net/url_request_context_getter.h" @@ -32,11 +33,14 @@ class CookiesViewTest : public testing::Test { new MockBrowsingDataDatabaseHelper(profile_.get()); mock_browsing_data_local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile_.get()); + mock_browsing_data_appcache_helper_ = + new MockBrowsingDataAppCacheHelper(profile_.get()); } void CheckDetailsSensitivity(gboolean expected_cookies, gboolean expected_database, gboolean expected_local_storage, + gboolean expected_appcache, const CookiesView& cookies_view) { // Cookies EXPECT_EQ(expected_cookies, @@ -69,7 +73,16 @@ class CookiesViewTest : public testing::Test { EXPECT_EQ(expected_local_storage, GTK_WIDGET_SENSITIVE( cookies_view.local_storage_last_modified_entry_)); - + // AppCache + EXPECT_EQ(expected_appcache, + GTK_WIDGET_SENSITIVE(cookies_view.appcache_manifest_entry_)); + EXPECT_EQ(expected_appcache, + GTK_WIDGET_SENSITIVE(cookies_view.appcache_size_entry_)); + EXPECT_EQ(expected_appcache, + GTK_WIDGET_SENSITIVE(cookies_view.appcache_created_entry_)); + EXPECT_EQ(expected_appcache, + GTK_WIDGET_SENSITIVE( + cookies_view.appcache_last_accessed_entry_)); } // Get the cookie names in the cookie list, as a comma seperated string. @@ -178,16 +191,19 @@ class CookiesViewTest : public testing::Test { mock_browsing_data_database_helper_; scoped_refptr<MockBrowsingDataLocalStorageHelper> mock_browsing_data_local_storage_helper_; + scoped_refptr<MockBrowsingDataAppCacheHelper> + mock_browsing_data_appcache_helper_; }; TEST_F(CookiesViewTest, Empty) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("", GetDisplayedCookies(cookies_view).c_str()); } @@ -203,7 +219,8 @@ TEST_F(CookiesViewTest, Noop) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -218,7 +235,7 @@ TEST_F(CookiesViewTest, Noop) { GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); } TEST_F(CookiesViewTest, RemoveAll) { @@ -228,7 +245,8 @@ TEST_F(CookiesViewTest, RemoveAll) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -241,7 +259,7 @@ TEST_F(CookiesViewTest, RemoveAll) { SCOPED_TRACE("Before removing"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo,_Cookies,__A,foo2,_Cookies,__B," "gdbhost1,_Web Databases,__db1," "gdbhost2,_Web Databases,__db2," @@ -259,7 +277,7 @@ TEST_F(CookiesViewTest, RemoveAll) { EXPECT_EQ(0u, monster->GetAllCookies().size()); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("", GetDisplayedCookies(cookies_view).c_str()); EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted()); EXPECT_TRUE(mock_browsing_data_local_storage_helper_->AllDeleted()); @@ -273,7 +291,8 @@ TEST_F(CookiesViewTest, RemoveAllWithDefaultSelected) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -285,7 +304,7 @@ TEST_F(CookiesViewTest, RemoveAllWithDefaultSelected) { SCOPED_TRACE("Before removing"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo,_Cookies,__A,foo2,_Cookies,__B," "gdbhost1,_Web Databases,__db1," "gdbhost2,_Web Databases,__db2," @@ -303,7 +322,7 @@ TEST_F(CookiesViewTest, RemoveAllWithDefaultSelected) { EXPECT_EQ(0u, monster->GetAllCookies().size()); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(0, gtk_tree_selection_count_selected_rows(cookies_view.selection_)); @@ -320,7 +339,8 @@ TEST_F(CookiesViewTest, Remove) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -333,7 +353,7 @@ TEST_F(CookiesViewTest, Remove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,_Cookies,__A,foo2,+Cookies,++B,++C," "gdbhost1,_Web Databases,__db1," "gdbhost2,_Web Databases,__db2," @@ -356,7 +376,7 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, FALSE, cookies_view); } EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); @@ -374,7 +394,7 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); } ASSERT_TRUE(ExpandByPath(cookies_view, "0")); @@ -394,7 +414,7 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," "gdbhost1,_Web Databases,__db1," "gdbhost2,_Web Databases,__db2," @@ -420,7 +440,7 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("2:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," "gdbhost1,+Web Databases," "gdbhost2,_Web Databases,__db2," @@ -450,7 +470,7 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("4:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," "gdbhost1,+Web Databases," "gdbhost2,_Web Databases,__db2," @@ -474,7 +494,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByType) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -637,7 +658,8 @@ TEST_F(CookiesViewTest, RemoveByDomain) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -761,7 +783,8 @@ TEST_F(CookiesViewTest, RemoveDefaultSelection) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -867,7 +890,8 @@ TEST_F(CookiesViewTest, Filter) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -935,7 +959,8 @@ TEST_F(CookiesViewTest, FilterRemoveAll) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -1002,7 +1027,8 @@ TEST_F(CookiesViewTest, FilterRemove) { CookiesView cookies_view(NULL, profile_.get(), mock_browsing_data_database_helper_, - mock_browsing_data_local_storage_helper_); + mock_browsing_data_local_storage_helper_, + mock_browsing_data_appcache_helper_); mock_browsing_data_database_helper_->AddDatabaseSamples(); mock_browsing_data_database_helper_->Notify(); mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); @@ -1050,7 +1076,7 @@ TEST_F(CookiesViewTest, FilterRemove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -1064,7 +1090,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -1078,7 +1104,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); } ASSERT_TRUE(ExpandByPath(cookies_view, "0")); @@ -1092,7 +1118,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("bar0,+Cookies," "bar1,+Cookies", GetDisplayedCookies(cookies_view).c_str()); @@ -1140,7 +1166,7 @@ TEST_F(CookiesViewTest, FilterRemove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, TRUE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, TRUE, FALSE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -1156,7 +1182,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); } ASSERT_TRUE(ExpandByPath(cookies_view, "3")); @@ -1171,7 +1197,7 @@ TEST_F(CookiesViewTest, FilterRemove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, TRUE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, TRUE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -1187,6 +1213,6 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("3:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, FALSE, cookies_view); } } diff --git a/chrome/browser/mock_browsing_data_appcache_helper.cc b/chrome/browser/mock_browsing_data_appcache_helper.cc new file mode 100644 index 0000000..1dccff4 --- /dev/null +++ b/chrome/browser/mock_browsing_data_appcache_helper.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/mock_browsing_data_appcache_helper.h" + +#include "base/callback.h" +#include "base/logging.h" + +MockBrowsingDataAppCacheHelper::MockBrowsingDataAppCacheHelper( + Profile* profile) + : BrowsingDataAppCacheHelper(profile) { +} + +MockBrowsingDataAppCacheHelper::~MockBrowsingDataAppCacheHelper() { +} + +void MockBrowsingDataAppCacheHelper::StartFetching( + Callback0::Type* completion_callback) { + completion_callback_.reset(completion_callback); +} + +void MockBrowsingDataAppCacheHelper::CancelNotification() { + completion_callback_.reset(NULL); +} + +void MockBrowsingDataAppCacheHelper::DeleteAppCache(int64 group_id) { +} + diff --git a/chrome/browser/mock_browsing_data_appcache_helper.h b/chrome/browser/mock_browsing_data_appcache_helper.h new file mode 100644 index 0000000..6dc6607 --- /dev/null +++ b/chrome/browser/mock_browsing_data_appcache_helper.h @@ -0,0 +1,26 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MOCK_BROWSING_DATA_APPCACHE_HELPER_H_ +#define CHROME_BROWSER_MOCK_BROWSING_DATA_APPCACHE_HELPER_H_ + +#include <map> + +#include "base/callback.h" +#include "chrome/browser/browsing_data_appcache_helper.h" + +class MockBrowsingDataAppCacheHelper + : public BrowsingDataAppCacheHelper { + public: + explicit MockBrowsingDataAppCacheHelper(Profile* profile); + + virtual void StartFetching(Callback0::Type* completion_callback); + virtual void CancelNotification(); + virtual void DeleteAppCache(int64 group_id); + + private: + virtual ~MockBrowsingDataAppCacheHelper(); +}; + +#endif // CHROME_BROWSER_MOCK_BROWSING_DATA_APPCACHE_HELPER_H_ diff --git a/chrome/browser/views/appcache_info_view.cc b/chrome/browser/views/appcache_info_view.cc new file mode 100755 index 0000000..fd23e7f --- /dev/null +++ b/chrome/browser/views/appcache_info_view.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/appcache_info_view.h" + +#include <algorithm> + +#include "app/gfx/color_utils.h" +#include "app/l10n_util.h" +#include "base/i18n/time_formatting.h" +#include "base/string_util.h" +#include "grit/generated_resources.h" +#include "views/grid_layout.h" +#include "views/controls/label.h" +#include "views/controls/textfield/textfield.h" +#include "views/standard_layout.h" + +/////////////////////////////////////////////////////////////////////////////// +// AppCacheInfoView, public: + +AppCacheInfoView::AppCacheInfoView() + : manifest_url_field_(NULL), + size_field_(NULL), + creation_date_field_(NULL), + last_access_field_(NULL) { +} + +AppCacheInfoView::~AppCacheInfoView() { +} + +void AppCacheInfoView::SetAppCacheInfo( + const BrowsingDataAppCacheHelper::AppCacheInfo* info) { + DCHECK(info); + manifest_url_field_->SetText(UTF8ToWide(info->manifest_url.spec())); + size_field_->SetText( + FormatBytes(info->size, GetByteDisplayUnits(info->size), true)); + creation_date_field_->SetText( + base::TimeFormatFriendlyDateAndTime(info->creation_time)); + last_access_field_->SetText( + base::TimeFormatFriendlyDateAndTime(info->last_access_time)); + EnableAppCacheDisplay(true); +} + +void AppCacheInfoView::EnableAppCacheDisplay(bool enabled) { + manifest_url_field_->SetEnabled(enabled); + size_field_->SetEnabled(enabled); + creation_date_field_->SetEnabled(enabled); + last_access_field_->SetEnabled(enabled); +} + +void AppCacheInfoView::ClearAppCacheDisplay() { + const string16 kEmpty; + manifest_url_field_->SetText(kEmpty); + size_field_->SetText(kEmpty); + creation_date_field_->SetText(kEmpty); + last_access_field_->SetText(kEmpty); + EnableAppCacheDisplay(false); +} + +/////////////////////////////////////////////////////////////////////////////// +// AppCacheInfoView, views::View overrides: + +void AppCacheInfoView::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this) + Init(); +} + +/////////////////////////////////////////////////////////////////////////////// +// AppCacheInfoView, private: + + +void AppCacheInfoView::Init() { + const int kInfoViewBorderSize = 1; + const int kInfoViewInsetSize = 3; + const int kLayoutId = 0; + + SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); + views::Border* border = views::Border::CreateSolidBorder( + kInfoViewBorderSize, border_color); + set_border(border); + + views::Label* manifest_url_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL)); + manifest_url_field_ = new views::Textfield; + views::Label* size_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_SIZE_LABEL)); + size_field_ = new views::Textfield; + views::Label* creation_date_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_COOKIE_CREATED_LABEL)); + creation_date_field_ = new views::Textfield; + views::Label* last_access_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_LAST_ACCESSED_LABEL)); + last_access_field_ = new views::Textfield; + + using views::GridLayout; + + GridLayout* layout = new GridLayout(this); + layout->SetInsets(kInfoViewInsetSize, kInfoViewInsetSize, + kInfoViewInsetSize, kInfoViewInsetSize); + SetLayoutManager(layout); + + views::ColumnSet* column_set = layout->AddColumnSet(kLayoutId); + 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); + + AddRow(kLayoutId, layout, manifest_url_label, manifest_url_field_, true); + AddRow(kLayoutId, layout, size_label, size_field_, true); + AddRow(kLayoutId, layout, creation_date_label, creation_date_field_, true); + AddRow(kLayoutId, layout, last_access_label, last_access_field_, false); +} + +void AppCacheInfoView::AddRow( + int layout_id, views::GridLayout* layout, views::Label* label, + views::Textfield* field, bool add_padding_row) { + // Add to the view hierarchy. + layout->StartRow(0, layout_id); + layout->AddView(label); + layout->AddView(field); + + // Color these borderless text areas the same as the containing dialog. + SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); + + // Init them now that they're in the view heirarchy. + field->SetReadOnly(true); + field->RemoveBorder(); + field->SetBackgroundColor(text_area_background); + + if (add_padding_row) + layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); +} diff --git a/chrome/browser/views/appcache_info_view.h b/chrome/browser/views/appcache_info_view.h new file mode 100755 index 0000000..ad209d0 --- /dev/null +++ b/chrome/browser/views/appcache_info_view.h @@ -0,0 +1,52 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_APPCACHE_INFO_VIEW_H_ +#define CHROME_BROWSER_VIEWS_APPCACHE_INFO_VIEW_H_ + +#include <string> +#include <vector> + +#include "views/view.h" +#include "chrome/browser/browsing_data_appcache_helper.h" + +namespace views { +class GridLayout; +class Label; +class Textfield; +} + +/////////////////////////////////////////////////////////////////////////////// +// AppCacheInfoView +// +// Responsible for displaying a tabular grid of AppCache information. +class AppCacheInfoView : public views::View { + public: + AppCacheInfoView(); + virtual ~AppCacheInfoView(); + + void SetAppCacheInfo(const BrowsingDataAppCacheHelper::AppCacheInfo* info); + void ClearAppCacheDisplay(); + void EnableAppCacheDisplay(bool enabled); + + protected: + // views::View overrides: + virtual void ViewHierarchyChanged( + bool is_add, views::View* parent, views::View* child); + + private: + void Init(); + void AddRow(int layout_id, views::GridLayout* layout, views::Label* label, + views::Textfield* field, bool add_padding_row); + + views::Textfield* manifest_url_field_; + views::Textfield* size_field_; + views::Textfield* creation_date_field_; + views::Textfield* last_access_field_; + + DISALLOW_COPY_AND_ASSIGN(AppCacheInfoView); +}; + +#endif // CHROME_BROWSER_VIEWS_APPCACHE_INFO_VIEW_H_ + diff --git a/chrome/browser/views/database_info_view.cc b/chrome/browser/views/database_info_view.cc index aff6df5..2d9a801 100755 --- a/chrome/browser/views/database_info_view.cc +++ b/chrome/browser/views/database_info_view.cc @@ -23,7 +23,8 @@ static const int kDatabaseInfoViewInsetSize = 3; // DatabaseInfoView, public: DatabaseInfoView::DatabaseInfoView() - : description_value_field_(NULL), + : name_value_field_(NULL), + description_value_field_(NULL), size_value_field_(NULL), last_modified_value_field_(NULL) { } @@ -33,6 +34,9 @@ DatabaseInfoView::~DatabaseInfoView() { void DatabaseInfoView::SetDatabaseInfo( const BrowsingDataDatabaseHelper::DatabaseInfo& database_info) { + name_value_field_->SetText(database_info.database_name.empty() ? + l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) : + UTF8ToWide(database_info.database_name)); description_value_field_->SetText(UTF8ToWide(database_info.description)); size_value_field_->SetText( FormatBytes(database_info.size, @@ -44,17 +48,17 @@ void DatabaseInfoView::SetDatabaseInfo( } void DatabaseInfoView::EnableDatabaseDisplay(bool enabled) { + name_value_field_->SetEnabled(enabled); description_value_field_->SetEnabled(enabled); size_value_field_->SetEnabled(enabled); last_modified_value_field_->SetEnabled(enabled); } void DatabaseInfoView::ClearDatabaseDisplay() { - std::wstring no_cookie_string = - l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED); - description_value_field_->SetText(no_cookie_string); - size_value_field_->SetText(no_cookie_string); - last_modified_value_field_->SetText(no_cookie_string); + const std::wstring kEmpty; + description_value_field_->SetText(kEmpty); + size_value_field_->SetText(kEmpty); + last_modified_value_field_->SetText(kEmpty); EnableDatabaseDisplay(false); } @@ -77,6 +81,9 @@ void DatabaseInfoView::Init() { kDatabaseInfoViewBorderSize, border_color); set_border(border); + views::Label* name_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_COOKIE_NAME_LABEL)); + name_value_field_ = new views::Textfield; views::Label* description_label = new views::Label( l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL)); description_value_field_ = new views::Textfield; @@ -105,6 +112,9 @@ void DatabaseInfoView::Init() { GridLayout::USE_PREF, 0, 0); layout->StartRow(0, three_column_layout_id); + layout->AddView(name_label); + layout->AddView(name_value_field_); + layout->StartRow(0, three_column_layout_id); layout->AddView(description_label); layout->AddView(description_value_field_); layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); @@ -119,6 +129,9 @@ void DatabaseInfoView::Init() { // 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. + name_value_field_->SetReadOnly(true); + name_value_field_->RemoveBorder(); + name_value_field_->SetBackgroundColor(text_area_background); description_value_field_->SetReadOnly(true); description_value_field_->RemoveBorder(); description_value_field_->SetBackgroundColor(text_area_background); diff --git a/chrome/browser/views/database_info_view.h b/chrome/browser/views/database_info_view.h index a3b6743..b6b6279 100755 --- a/chrome/browser/views/database_info_view.h +++ b/chrome/browser/views/database_info_view.h @@ -46,6 +46,7 @@ class DatabaseInfoView : public views::View { void Init(); // Individual property labels. + views::Textfield* name_value_field_; views::Textfield* description_value_field_; views::Textfield* size_value_field_; views::Textfield* last_modified_value_field_; diff --git a/chrome/browser/views/options/cookies_view.cc b/chrome/browser/views/options/cookies_view.cc index 4b70389..584cf85 100644 --- a/chrome/browser/views/options/cookies_view.cc +++ b/chrome/browser/views/options/cookies_view.cc @@ -14,6 +14,7 @@ #include "base/string_util.h" #include "chrome/browser/cookies_tree_model.h" #include "chrome/browser/profile.h" +#include "chrome/browser/views/appcache_info_view.h" #include "chrome/browser/views/cookie_info_view.h" #include "chrome/browser/views/database_info_view.h" #include "chrome/browser/views/local_storage_info_view.h" @@ -63,6 +64,28 @@ void CookiesTreeView::RemoveSelectedItems() { } /////////////////////////////////////////////////////////////////////////////// +// CookiesView::InfoPanelView +// Overridden to handle layout of the various info views. +// +// This view is a child of the CookiesView and participates +// in its GridLayout. The various info views are all children +// of this view. Only one child is expected to be visible at a time. + +class CookiesView::InfoPanelView : public views::View { + public: + virtual void Layout() { + int child_count = GetChildViewCount(); + for (int i = 0; i < child_count; ++i) + GetChildViewAt(i)->SetBounds(0, 0, width(), height()); + } + + virtual gfx::Size GetPreferredSize() { + DCHECK(GetChildViewCount() > 0); + return GetChildViewAt(0)->GetPreferredSize(); + } +}; + +/////////////////////////////////////////////////////////////////////////////// // CookiesView, public: // static @@ -204,6 +227,10 @@ void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) { UpdateVisibleDetailedInfo(local_storage_info_view_); local_storage_info_view_->SetLocalStorageInfo( *detailed_info.local_storage_info); + } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_APPCACHE) { + UpdateVisibleDetailedInfo(appcache_info_view_); + appcache_info_view_->SetAppCacheInfo(detailed_info.appcache_info); } else { UpdateVisibleDetailedInfo(cookie_info_view_); cookie_info_view_->ClearCookieDisplay(); @@ -236,9 +263,11 @@ CookiesView::CookiesView(Profile* profile) clear_search_button_(NULL), description_label_(NULL), cookies_tree_(NULL), + info_panel_(NULL), cookie_info_view_(NULL), database_info_view_(NULL), local_storage_info_view_(NULL), + appcache_info_view_(NULL), remove_button_(NULL), remove_all_button_(NULL), profile_(profile), @@ -258,11 +287,20 @@ void CookiesView::Init() { description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); cookies_tree_model_.reset(new CookiesTreeModel(profile_, new BrowsingDataDatabaseHelper(profile_), - new BrowsingDataLocalStorageHelper(profile_))); + new BrowsingDataLocalStorageHelper(profile_), + new BrowsingDataAppCacheHelper(profile_))); cookies_tree_model_->AddObserver(this); + + info_panel_ = new InfoPanelView; cookie_info_view_ = new CookieInfoView(false); database_info_view_ = new DatabaseInfoView; local_storage_info_view_ = new LocalStorageInfoView; + appcache_info_view_ = new AppCacheInfoView; + info_panel_->AddChildView(cookie_info_view_); + info_panel_->AddChildView(database_info_view_); + info_panel_->AddChildView(local_storage_info_view_); + info_panel_->AddChildView(appcache_info_view_); + cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get()); remove_button_ = new views::NativeButton( this, l10n_util::GetString(IDS_COOKIES_REMOVE_LABEL)); @@ -310,13 +348,7 @@ void CookiesView::Init() { layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); layout->StartRow(0, single_column_layout_id); - layout->AddView(cookie_info_view_, 1, 2); - - layout->StartRow(0, single_column_layout_id); - layout->AddView(database_info_view_); - - layout->StartRow(0, single_column_layout_id); - layout->AddView(local_storage_info_view_); + layout->AddView(info_panel_); // Add the Remove/Remove All buttons to the ClientView View* parent = GetParent(); @@ -352,4 +384,5 @@ void CookiesView::UpdateVisibleDetailedInfo(views::View* view) { cookie_info_view_->SetVisible(view == cookie_info_view_); database_info_view_->SetVisible(view == database_info_view_); local_storage_info_view_->SetVisible(view == local_storage_info_view_); + appcache_info_view_->SetVisible(view == appcache_info_view_); } diff --git a/chrome/browser/views/options/cookies_view.h b/chrome/browser/views/options/cookies_view.h index f16d0cb..ee2c314 100644 --- a/chrome/browser/views/options/cookies_view.h +++ b/chrome/browser/views/options/cookies_view.h @@ -25,6 +25,7 @@ class NativeButton; } // namespace views +class AppCacheInfoView; class CookieInfoView; class CookiesTreeModel; class CookiesTreeView; @@ -107,6 +108,8 @@ class CookiesView : public TreeModelObserver, views::View* child); private: + class InfoPanelView; + // Use the static factory method to show. explicit CookiesView(Profile* profile); @@ -119,15 +122,6 @@ class CookiesView : public TreeModelObserver, // 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 database is selected. - void UpdateForDatabaseState(); - - // Update the UI when a local storage is selected. - void UpdateForLocalStorageState(); - // Enable or disable the remove and remove all buttons. void UpdateRemoveButtonsState(); @@ -140,9 +134,11 @@ class CookiesView : public TreeModelObserver, views::NativeButton* clear_search_button_; views::Label* description_label_; CookiesTreeView* cookies_tree_; + InfoPanelView* info_panel_; CookieInfoView* cookie_info_view_; DatabaseInfoView* database_info_view_; LocalStorageInfoView* local_storage_info_view_; + AppCacheInfoView* appcache_info_view_; views::NativeButton* remove_button_; views::NativeButton* remove_all_button_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 1e0fb0c1..8cd7e52 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -252,6 +252,8 @@ 'browser/browser_url_handler.cc', 'browser/browser_url_handler.h', 'browser/browser_window.h', + 'browser/browsing_data_appcache_helper.cc', + 'browser/browsing_data_appcache_helper.h', 'browser/browsing_data_database_helper.cc', 'browser/browsing_data_database_helper.h', 'browser/browsing_data_local_storage_helper.cc', @@ -1889,6 +1891,8 @@ 'browser/views/accelerator_table_gtk.h', 'browser/views/accessible_toolbar_view.cc', 'browser/views/accessible_toolbar_view.h', + 'browser/views/appcache_info_view.cc', + 'browser/views/appcache_info_view.h', 'browser/views/autocomplete/autocomplete_popup_contents_view.cc', 'browser/views/autocomplete/autocomplete_popup_contents_view.h', 'browser/views/autocomplete/autocomplete_popup_win.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 70cd9db..fc32a04 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -57,10 +57,12 @@ # The only thing used from browser is Browser::Type. 'browser/browser.h', 'browser/cocoa/browser_test_helper.h', - 'browser/mock_browsing_data_database_helper.h', + 'browser/mock_browsing_data_appcache_helper.cc', + 'browser/mock_browsing_data_appcache_helper.h', 'browser/mock_browsing_data_database_helper.cc', - 'browser/mock_browsing_data_local_storage_helper.h', + 'browser/mock_browsing_data_database_helper.h', 'browser/mock_browsing_data_local_storage_helper.cc', + 'browser/mock_browsing_data_local_storage_helper.h', # TODO: these should live here but are currently used by # production code code in libbrowser (in chrome.gyp). #'browser/net/url_request_mock_http_job.cc', |