summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-24 20:38:29 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-24 20:38:29 +0000
commit3868baed7247f13ac96e2f14f09121d43b59aab2 (patch)
tree46f15ba8f29d762b99a20c83b7011e3bb965396d
parent2b8e7ca060b5c7cae81676c233039c33c5ce080f (diff)
downloadchromium_src-3868baed7247f13ac96e2f14f09121d43b59aab2.zip
chromium_src-3868baed7247f13ac96e2f14f09121d43b59aab2.tar.gz
chromium_src-3868baed7247f13ac96e2f14f09121d43b59aab2.tar.bz2
Put up a prompt to create appcaches if the Content Settings indicate to do so. Done for windows and linux (sorry mac, you're out of luck). Also put in place a GenericInfoView class.
BUG=38362 TEST=manual and generic_info_view_unittest.cc Review URL: http://codereview.chromium.org/1115005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42525 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/appcache/chrome_appcache_service.cc88
-rw-r--r--chrome/browser/appcache/chrome_appcache_service.h19
-rw-r--r--chrome/browser/cocoa/cookie_details.mm6
-rw-r--r--chrome/browser/cocoa/cookie_prompt_window_controller.mm3
-rw-r--r--chrome/browser/cookie_modal_dialog.cc14
-rw-r--r--chrome/browser/cookie_modal_dialog.h20
-rw-r--r--chrome/browser/cookie_modal_dialog_gtk.cc4
-rw-r--r--chrome/browser/gtk/gtk_chrome_cookie_view.cc36
-rw-r--r--chrome/browser/gtk/gtk_chrome_cookie_view.h8
-rw-r--r--chrome/browser/message_box_handler.cc10
-rw-r--r--chrome/browser/message_box_handler.h9
-rw-r--r--chrome/browser/views/appcache_info_view.cc139
-rw-r--r--chrome/browser/views/appcache_info_view.h35
-rw-r--r--chrome/browser/views/cookie_prompt_view.cc10
-rw-r--r--chrome/browser/views/generic_info_view.cc105
-rw-r--r--chrome/browser/views/generic_info_view.h66
-rw-r--r--chrome/browser/views/generic_info_view_unittest.cc62
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi2
19 files changed, 470 insertions, 168 deletions
diff --git a/chrome/browser/appcache/chrome_appcache_service.cc b/chrome/browser/appcache/chrome_appcache_service.cc
index 2fb7772..6e94f25 100644
--- a/chrome/browser/appcache/chrome_appcache_service.cc
+++ b/chrome/browser/appcache/chrome_appcache_service.cc
@@ -6,7 +6,9 @@
#include "base/file_path.h"
#include "base/file_util.h"
-#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/cookie_prompt_modal_dialog_delegate.h"
+#include "chrome/browser/message_box_handler.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"
@@ -15,6 +17,34 @@
static bool has_initialized_thread_ids;
+// ChromeAppCacheService cannot just subclass the delegate interface
+// because we may have several prompts pending.
+class ChromeAppCacheService::PromptDelegate
+ : public CookiePromptModalDialogDelegate {
+ public:
+ PromptDelegate(ChromeAppCacheService* service,
+ const GURL& manifest_url, net::CompletionCallback* callback)
+ : service_(service), manifest_url_(manifest_url), callback_(callback) {
+ }
+
+ virtual void AllowSiteData(bool session_expire) {
+ service_->DidPrompt(net::OK, manifest_url_, callback_);
+ delete this;
+ }
+
+ virtual void BlockSiteData() {
+ service_->DidPrompt(net::ERR_ACCESS_DENIED, manifest_url_, callback_);
+ delete this;
+ }
+
+ private:
+ scoped_refptr<ChromeAppCacheService> service_;
+ GURL manifest_url_;
+ net::CompletionCallback* callback_;
+};
+
+// ----------------------------------------------------------------------------
+
ChromeAppCacheService::ChromeAppCacheService(
const FilePath& profile_path,
ChromeURLRequestContext* request_context) {
@@ -48,6 +78,7 @@ void ChromeAppCacheService::ClearLocalState(const FilePath& profile_path) {
}
bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
ContentSetting setting = host_contents_settings_map_->GetContentSetting(
manifest_url, CONTENT_SETTINGS_TYPE_COOKIES);
DCHECK(setting != CONTENT_SETTING_DEFAULT);
@@ -57,23 +88,72 @@ bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
int ChromeAppCacheService::CanCreateAppCache(
const GURL& manifest_url, net::CompletionCallback* callback) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
ContentSetting setting = host_contents_settings_map_->GetContentSetting(
manifest_url, CONTENT_SETTINGS_TYPE_COOKIES);
DCHECK(setting != CONTENT_SETTING_DEFAULT);
if (setting == CONTENT_SETTING_ASK) {
- // TODO(michaeln): prompt the user, for now we block
- setting = CONTENT_SETTING_BLOCK;
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &ChromeAppCacheService::DoPrompt,
+ manifest_url, callback));
+ return net::ERR_IO_PENDING;
}
- return (setting != CONTENT_SETTING_BLOCK) ? net::OK : net::ERR_ACCESS_DENIED;
+ return (setting != CONTENT_SETTING_BLOCK) ? net::OK :
+ net::ERR_ACCESS_DENIED;
+}
+
+void ChromeAppCacheService::DoPrompt(
+ const GURL& manifest_url, net::CompletionCallback* callback) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ // The setting may have changed (due to the "remember" option)
+ ContentSetting setting = host_contents_settings_map_->GetContentSetting(
+ manifest_url, CONTENT_SETTINGS_TYPE_COOKIES);
+ if (setting != CONTENT_SETTING_ASK) {
+ int rv = (setting != CONTENT_SETTING_BLOCK) ? net::OK :
+ net::ERR_ACCESS_DENIED;
+ DidPrompt(rv, manifest_url, callback);
+ return;
+ }
+
+ // Show the prompt on top of the current tab.
+ Browser* browser = BrowserList::GetLastActive();
+ if (!browser || !browser->GetSelectedTabContents()) {
+ DidPrompt(net::ERR_ACCESS_DENIED, manifest_url, callback);
+ return;
+ }
+
+ RunAppCachePrompt(browser->GetSelectedTabContents(),
+ host_contents_settings_map_, manifest_url,
+ new PromptDelegate(this, manifest_url, callback));
+}
+
+void ChromeAppCacheService::DidPrompt(
+ int rv, const GURL& manifest_url, net::CompletionCallback* callback) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &ChromeAppCacheService::CallCallback,
+ rv, callback));
+}
+
+void ChromeAppCacheService::CallCallback(
+ int rv, net::CompletionCallback* callback) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ callback->Run(rv);
}
void ChromeAppCacheService::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
DCHECK(type == NotificationType::PURGE_MEMORY);
PurgeMemory();
}
+// ----------------------------------------------------------------------------
+
static ChromeThread::ID ToChromeThreadID(int id) {
DCHECK(has_initialized_thread_ids);
DCHECK(id == ChromeThread::DB || id == ChromeThread::IO);
diff --git a/chrome/browser/appcache/chrome_appcache_service.h b/chrome/browser/appcache/chrome_appcache_service.h
index 848a83f..888b672 100644
--- a/chrome/browser/appcache/chrome_appcache_service.h
+++ b/chrome/browser/appcache/chrome_appcache_service.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_APPCACHE_CHROME_APPCACHE_SERVICE_H_
#include "base/ref_counted.h"
+#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/common/notification_registrar.h"
#include "webkit/appcache/appcache_policy.h"
@@ -21,9 +22,10 @@ class FilePath;
// owning profile.
//
// All methods, including the ctor and dtor, are expected to be called on
-// the IO thread.
+// the IO thread (unless specifically called out in doc comments).
class ChromeAppCacheService
- : public base::RefCounted<ChromeAppCacheService>,
+ : public base::RefCountedThreadSafe<ChromeAppCacheService,
+ ChromeThread::DeleteOnIOThread>,
public appcache::AppCacheService,
public appcache::AppCachePolicy,
public NotificationObserver {
@@ -34,7 +36,11 @@ class ChromeAppCacheService
static void ClearLocalState(const FilePath& profile_path);
private:
- friend class base::RefCounted<ChromeAppCacheService>;
+ friend class ChromeThread;
+ friend class DeleteTask<ChromeAppCacheService>;
+
+ class PromptDelegate;
+
virtual ~ChromeAppCacheService();
// AppCachePolicy overrides
@@ -42,6 +48,13 @@ class ChromeAppCacheService
virtual int CanCreateAppCache(const GURL& manifest_url,
net::CompletionCallback* callback);
+ // The DoPrompt and DidPrrompt methods are called on the UI thread, and
+ // the following CallCallback method is called on the IO thread.
+ void DoPrompt(const GURL& manifest_url, net::CompletionCallback* callback);
+ void DidPrompt(int rv, const GURL& manifest_url,
+ net::CompletionCallback* callback);
+ void CallCallback(int rv, net::CompletionCallback* callback);
+
// NotificationObserver override
virtual void Observe(NotificationType type,
const NotificationSource& source,
diff --git a/chrome/browser/cocoa/cookie_details.mm b/chrome/browser/cocoa/cookie_details.mm
index 7552c7f..8f5a5d3 100644
--- a/chrome/browser/cocoa/cookie_details.mm
+++ b/chrome/browser/cocoa/cookie_details.mm
@@ -212,6 +212,12 @@
details = [[CocoaCookieDetails alloc]
initWithDatabase:dialog->origin().host()
name:dialog->database_name()];
+ } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) {
+ // TODO(michaeln): Show an appropiate details view, for now we
+ // overload the database details view.
+ details = [[CocoaCookieDetails alloc]
+ initWithDatabase:dialog->origin().host()
+ name:UTF8ToUTF16(dialog->appcache_manifest_url().spec())];
} else {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller.mm b/chrome/browser/cocoa/cookie_prompt_window_controller.mm
index 833423b..8881e93 100644
--- a/chrome/browser/cocoa/cookie_prompt_window_controller.mm
+++ b/chrome/browser/cocoa/cookie_prompt_window_controller.mm
@@ -79,9 +79,8 @@
descriptionStringId = IDS_COOKIE_ALERT_LABEL;
break;
case CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE:
- descriptionStringId = IDS_DATA_ALERT_LABEL;
- break;
case CookiePromptModalDialog::DIALOG_TYPE_DATABASE:
+ case CookiePromptModalDialog::DIALOG_TYPE_APPCACHE:
descriptionStringId = IDS_DATA_ALERT_LABEL;
break;
default:
diff --git a/chrome/browser/cookie_modal_dialog.cc b/chrome/browser/cookie_modal_dialog.cc
index 99378dc..45347dc 100644
--- a/chrome/browser/cookie_modal_dialog.cc
+++ b/chrome/browser/cookie_modal_dialog.cc
@@ -59,6 +59,20 @@ CookiePromptModalDialog::CookiePromptModalDialog(
delegate_(delegate) {
}
+// AppCache
+CookiePromptModalDialog::CookiePromptModalDialog(
+ TabContents* tab_contents,
+ HostContentSettingsMap* host_content_settings_map,
+ const GURL& appcache_manifest_url,
+ CookiePromptModalDialogDelegate* delegate)
+ : AppModalDialog(tab_contents, std::wstring()),
+ host_content_settings_map_(host_content_settings_map),
+ dialog_type_(DIALOG_TYPE_APPCACHE),
+ origin_(appcache_manifest_url.GetOrigin()),
+ appcache_manifest_url_(appcache_manifest_url),
+ delegate_(delegate) {
+}
+
CookiePromptModalDialog::~CookiePromptModalDialog() {
}
diff --git a/chrome/browser/cookie_modal_dialog.h b/chrome/browser/cookie_modal_dialog.h
index 997dd7f..9a2ce77 100644
--- a/chrome/browser/cookie_modal_dialog.h
+++ b/chrome/browser/cookie_modal_dialog.h
@@ -31,8 +31,8 @@ class CookiePromptModalDialog : public AppModalDialog {
enum DialogType {
DIALOG_TYPE_COOKIE = 0,
DIALOG_TYPE_LOCAL_STORAGE,
- DIALOG_TYPE_DATABASE
- // TODO(michaeln): AppCache
+ DIALOG_TYPE_DATABASE,
+ DIALOG_TYPE_APPCACHE
};
// A union of data necessary to determine the type of message box to
@@ -53,6 +53,10 @@ class CookiePromptModalDialog : public AppModalDialog {
const GURL& origin,
const string16& database_name,
CookiePromptModalDialogDelegate* delegate);
+ CookiePromptModalDialog(TabContents* tab_contents,
+ HostContentSettingsMap* host_content_settings_map,
+ const GURL& appcache_manifest_url,
+ CookiePromptModalDialogDelegate* delegate);
virtual ~CookiePromptModalDialog();
static void RegisterPrefs(PrefService* prefs);
@@ -76,6 +80,7 @@ class CookiePromptModalDialog : public AppModalDialog {
const string16& local_storage_key() const { return local_storage_key_; }
const string16& local_storage_value() const { return local_storage_value_; }
const string16& database_name() const { return database_name_; }
+ const GURL& appcache_manifest_url() const { return appcache_manifest_url_; }
TabContents* tab_contents() const { return tab_contents_; }
// Implement CookiePromptModalDialogDelegate.
@@ -102,19 +107,16 @@ class CookiePromptModalDialog : public AppModalDialog {
const DialogType dialog_type_;
// The origin connected to this request.
- GURL origin_;
+ const GURL origin_;
- // Cookie to display.
+ // Which data members are relevant depends on the dialog_type.
const std::string cookie_line_;
-
- // LocalStorage key/value.
const string16 local_storage_key_;
const string16 local_storage_value_;
-
- // Database name.
const string16 database_name_;
+ const GURL appcache_manifest_url_;
- // Delegate. The caller should provide one in order to receive results
+ // The caller should provide a delegate in order to receive results
// from this delegate. Any time after calling one of these methods, the
// delegate could be deleted
CookiePromptModalDialogDelegate* delegate_;
diff --git a/chrome/browser/cookie_modal_dialog_gtk.cc b/chrome/browser/cookie_modal_dialog_gtk.cc
index 4ff08f6..700236a 100644
--- a/chrome/browser/cookie_modal_dialog_gtk.cc
+++ b/chrome/browser/cookie_modal_dialog_gtk.cc
@@ -119,6 +119,10 @@ NativeDialog CookiePromptModalDialog::CreateNativeDialog() {
cookie_view,
origin().host(),
database_name());
+ } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) {
+ gtk_chrome_cookie_view_display_appcache_created(
+ cookie_view,
+ appcache_manifest_url());
} else {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/gtk/gtk_chrome_cookie_view.cc b/chrome/browser/gtk/gtk_chrome_cookie_view.cc
index 1abb6d2..b4a823d 100644
--- a/chrome/browser/gtk/gtk_chrome_cookie_view.cc
+++ b/chrome/browser/gtk/gtk_chrome_cookie_view.cc
@@ -101,6 +101,10 @@ void InitStyles(GtkChromeCookieView *self) {
dialog_style);
InitBrowserDetailStyle(self->database_accessed_name_entry_, label_style,
dialog_style);
+
+ // AppCache created item.
+ InitBrowserDetailStyle(self->appcache_created_manifest_entry_, label_style,
+ dialog_style);
}
void SetCookieDetailsSensitivity(GtkChromeCookieView *self,
@@ -150,6 +154,11 @@ void SetDatabaseAccessedSensitivity(GtkChromeCookieView* self,
gtk_widget_set_sensitive(self->database_accessed_name_entry_, enabled);
}
+void SetAppCacheCreatedSensitivity(GtkChromeCookieView* self,
+ gboolean enabled) {
+ gtk_widget_set_sensitive(self->appcache_created_manifest_entry_, enabled);
+}
+
void ClearCookieDetails(GtkChromeCookieView *self) {
std::string no_cookie =
l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_NONESELECTED);
@@ -180,6 +189,9 @@ void UpdateVisibleDetailedInfo(GtkChromeCookieView *self, GtkWidget* table) {
table == self->local_storage_item_table_);
SetDatabaseAccessedSensitivity(self,
table == self->database_accessed_table_);
+ SetAppCacheCreatedSensitivity(self,
+ table == self->appcache_created_table_);
+
// Display everything
gtk_widget_show(self->table_box_);
gtk_widget_show_all(table);
@@ -196,6 +208,8 @@ void UpdateVisibleDetailedInfo(GtkChromeCookieView *self, GtkWidget* table) {
gtk_widget_hide(self->local_storage_item_table_);
if (table != self->database_accessed_table_)
gtk_widget_hide(self->database_accessed_table_);
+ if (table != self->appcache_created_table_)
+ gtk_widget_hide(self->appcache_created_table_);
}
} // namespace
@@ -305,7 +319,7 @@ static void gtk_chrome_cookie_view_init(GtkChromeCookieView *self) {
self->local_storage_item_table_,
&self->local_storage_item_value_entry_);
- // Database accessed item.
+ // Database accessed prompt.
self->database_accessed_table_ = gtk_table_new(2, 2, FALSE);
gtk_container_add(GTK_CONTAINER(self->table_box_),
self->database_accessed_table_);
@@ -320,6 +334,17 @@ static void gtk_chrome_cookie_view_init(GtkChromeCookieView *self) {
self->database_accessed_table_,
&self->database_accessed_name_entry_);
+ // AppCache created prompt.
+ self->appcache_created_table_ = gtk_table_new(1, 2, FALSE);
+ gtk_container_add(GTK_CONTAINER(self->table_box_),
+ self->appcache_created_table_);
+ gtk_table_set_col_spacing(GTK_TABLE(self->appcache_created_table_), 0,
+ gtk_util::kLabelSpacing);
+ row = 0;
+ InitDetailRow(row++, IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL,
+ self->appcache_created_table_,
+ &self->appcache_created_manifest_entry_);
+
gtk_frame_set_shadow_type(GTK_FRAME(self), GTK_SHADOW_ETCHED_IN);
gtk_container_add(GTK_CONTAINER(self), self->table_box_);
}
@@ -479,3 +504,12 @@ void gtk_chrome_cookie_view_display_database_accessed(
UTF16ToUTF8(database_name).c_str());
SetDatabaseAccessedSensitivity(self, TRUE);
}
+
+void gtk_chrome_cookie_view_display_appcache_created(
+ GtkChromeCookieView* self,
+ const GURL& manifest_url) {
+ UpdateVisibleDetailedInfo(self, self->appcache_created_table_);
+ gtk_entry_set_text(GTK_ENTRY(self->appcache_created_manifest_entry_),
+ manifest_url.spec().c_str());
+ SetAppCacheCreatedSensitivity(self, TRUE);
+}
diff --git a/chrome/browser/gtk/gtk_chrome_cookie_view.h b/chrome/browser/gtk/gtk_chrome_cookie_view.h
index ce157bf..73706f3 100644
--- a/chrome/browser/gtk/gtk_chrome_cookie_view.h
+++ b/chrome/browser/gtk/gtk_chrome_cookie_view.h
@@ -95,6 +95,10 @@ typedef struct {
GtkWidget* database_accessed_table_;
GtkWidget* database_accessed_origin_entry_;
GtkWidget* database_accessed_name_entry_;
+
+ // The appcache created widgets.
+ GtkWidget* appcache_created_table_;
+ GtkWidget* appcache_created_manifest_entry_;
} GtkChromeCookieView;
typedef struct {
@@ -155,4 +159,8 @@ void gtk_chrome_cookie_view_display_database_accessed(
const std::string& host,
const string16& database_name);
+void gtk_chrome_cookie_view_display_appcache_created(
+ GtkChromeCookieView* self,
+ const GURL& manifest_url);
+
#endif // CHROME_BROWSER_GTK_GTK_CHROME_COOKIE_VIEW_H_
diff --git a/chrome/browser/message_box_handler.cc b/chrome/browser/message_box_handler.cc
index 0f5b63c..e004a0e 100644
--- a/chrome/browser/message_box_handler.cc
+++ b/chrome/browser/message_box_handler.cc
@@ -75,3 +75,13 @@ void RunDatabasePrompt(
new CookiePromptModalDialog(tab_contents, host_content_settings_map,
origin, database_name, delegate));
}
+
+void RunAppCachePrompt(
+ TabContents* tab_contents,
+ HostContentSettingsMap* host_content_settings_map,
+ const GURL& manifest_url,
+ CookiePromptModalDialogDelegate* delegate) {
+ Singleton<AppModalDialogQueue>()->AddDialog(
+ new CookiePromptModalDialog(tab_contents, host_content_settings_map,
+ manifest_url, delegate));
+}
diff --git a/chrome/browser/message_box_handler.h b/chrome/browser/message_box_handler.h
index cf08804..be821f7 100644
--- a/chrome/browser/message_box_handler.h
+++ b/chrome/browser/message_box_handler.h
@@ -71,5 +71,14 @@ void RunDatabasePrompt(
const string16& database_name,
CookiePromptModalDialogDelegate* delegate);
+// This will display a modal dialog box with the |manifest_url| and ask the
+// user to accept or reject it. The caller should pass |delegate| that will
+// handle the reply from the dialog.
+void RunAppCachePrompt(
+ TabContents* tab_contents,
+ HostContentSettingsMap* host_content_settings_map,
+ const GURL& manifest_url,
+ CookiePromptModalDialogDelegate* delegate);
+
#endif // CHROME_BROWSER_MESSAGE_BOX_HANDLER_H_
diff --git a/chrome/browser/views/appcache_info_view.cc b/chrome/browser/views/appcache_info_view.cc
index ade35f8..55973ec 100644
--- a/chrome/browser/views/appcache_info_view.cc
+++ b/chrome/browser/views/appcache_info_view.cc
@@ -4,132 +4,37 @@
#include "chrome/browser/views/appcache_info_view.h"
-#include <algorithm>
-
#include "app/l10n_util.h"
#include "base/i18n/time_formatting.h"
#include "base/utf_string_conversions.h"
-#include "gfx/color_utils.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:
+namespace {
+const int kInfoLabelIds[] = {
+ IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL,
+ IDS_COOKIES_SIZE_LABEL,
+ IDS_COOKIES_COOKIE_CREATED_LABEL,
+ IDS_COOKIES_LAST_ACCESSED_LABEL
+};
+} // namespace
AppCacheInfoView::AppCacheInfoView()
- : manifest_url_field_(NULL),
- size_field_(NULL),
- creation_date_field_(NULL),
- last_access_field_(NULL) {
-}
-
-AppCacheInfoView::~AppCacheInfoView() {
+ : GenericInfoView(ARRAYSIZE(kInfoLabelIds), kInfoLabelIds) {
}
void AppCacheInfoView::SetAppCacheInfo(const appcache::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);
+ string16 manifest_url =
+ UTF8ToUTF16(info->manifest_url.spec());
+ string16 size =
+ FormatBytes(info->size, GetByteDisplayUnits(info->size), true);
+ string16 creation_date =
+ base::TimeFormatFriendlyDateAndTime(info->creation_time);
+ string16 last_access_date =
+ base::TimeFormatFriendlyDateAndTime(info->last_access_time);
+ int row = 0;
+ SetValue(row++, manifest_url);
+ SetValue(row++, size);
+ SetValue(row++, creation_date);
+ SetValue(row++, last_access_date);
}
diff --git a/chrome/browser/views/appcache_info_view.h b/chrome/browser/views/appcache_info_view.h
index 25db5dd..f78162f 100644
--- a/chrome/browser/views/appcache_info_view.h
+++ b/chrome/browser/views/appcache_info_view.h
@@ -5,46 +5,17 @@
#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/views/generic_info_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 {
+// Displays a tabular grid of AppCache information.
+class AppCacheInfoView : public GenericInfoView {
public:
AppCacheInfoView();
- virtual ~AppCacheInfoView();
-
void SetAppCacheInfo(const appcache::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);
};
diff --git a/chrome/browser/views/cookie_prompt_view.cc b/chrome/browser/views/cookie_prompt_view.cc
index 16e2b94..dacc169 100644
--- a/chrome/browser/views/cookie_prompt_view.cc
+++ b/chrome/browser/views/cookie_prompt_view.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/views/browser_dialogs.h"
#include "chrome/browser/views/cookie_info_view.h"
#include "chrome/browser/views/database_open_info_view.h"
+#include "chrome/browser/views/generic_info_view.h"
#include "chrome/browser/views/local_storage_set_item_info_view.h"
#include "chrome/browser/views/options/content_settings_window_view.h"
#include "chrome/common/pref_names.h"
@@ -251,6 +252,15 @@ void CookiePromptView::Init() {
view->SetFields(parent_->origin().host(),
parent_->database_name());
info_view_ = view;
+ } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) {
+ static const int kAppCacheInfoLabels[] = {
+ IDS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL
+ };
+ GenericInfoView* view = new GenericInfoView(ARRAYSIZE(kAppCacheInfoLabels),
+ kAppCacheInfoLabels);
+ layout->AddView(view, 1, 1, GridLayout::FILL, GridLayout::CENTER);
+ view->SetValue(0, UTF8ToUTF16(parent_->appcache_manifest_url().spec()));
+ info_view_ = view;
} else {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/views/generic_info_view.cc b/chrome/browser/views/generic_info_view.cc
new file mode 100644
index 0000000..edd8492
--- /dev/null
+++ b/chrome/browser/views/generic_info_view.cc
@@ -0,0 +1,105 @@
+// 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/generic_info_view.h"
+
+#include "app/l10n_util.h"
+#include "gfx/color_utils.h"
+#include "base/logging.h"
+#include "views/grid_layout.h"
+#include "views/controls/label.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/standard_layout.h"
+
+GenericInfoView::GenericInfoView(int number_of_rows)
+ : number_of_rows_(number_of_rows), name_string_ids_(NULL) {
+ DCHECK(number_of_rows_ > 0);
+}
+
+GenericInfoView::GenericInfoView(
+ int number_of_rows, const int name_string_ids[])
+ : number_of_rows_(number_of_rows), name_string_ids_(name_string_ids) {
+ DCHECK(number_of_rows_ > 0);
+}
+
+void GenericInfoView::SetNameByStringId(int row, int name_string_id) {
+ SetName(row, l10n_util::GetString(name_string_id));
+}
+
+void GenericInfoView::SetName(int row, const string16& name) {
+ DCHECK(name_views_.get()); // Can only be called after Init time.
+ DCHECK(row >= 0 && row < number_of_rows_);
+ name_views_[row]->SetText(name);
+}
+
+void GenericInfoView::SetValue(int row, const string16& name) {
+ DCHECK(value_views_.get()); // Can only be called after Init time.
+ DCHECK(row >= 0 && row < number_of_rows_);
+ value_views_[row]->SetText(name);
+}
+
+void GenericInfoView::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (is_add && child == this) {
+ InitGenericInfoView();
+ if (name_string_ids_) {
+ for (int i = 0; i < number_of_rows_; ++i)
+ SetNameByStringId(i, name_string_ids_[i]);
+ }
+ }
+}
+
+void GenericInfoView::InitGenericInfoView() {
+ 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);
+
+ 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);
+
+ name_views_.reset(new views::Label* [number_of_rows_]);
+ value_views_.reset(new views::Textfield* [number_of_rows_]);
+
+ for (int i = 0; i < number_of_rows_; ++i) {
+ if (i)
+ layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing);
+ name_views_[i] = new views::Label;
+ value_views_[i] = new views::Textfield;
+ AddRow(kLayoutId, layout, name_views_[i], value_views_[i]);
+ }
+}
+
+void GenericInfoView::AddRow(
+ int layout_id, views::GridLayout* layout, views::Label* name,
+ views::Textfield* value) {
+ // Add to the view hierarchy.
+ layout->StartRow(0, layout_id);
+ layout->AddView(name);
+ layout->AddView(value);
+
+ // 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.
+ value->SetReadOnly(true);
+ value->RemoveBorder();
+ value->SetBackgroundColor(text_area_background);
+}
diff --git a/chrome/browser/views/generic_info_view.h b/chrome/browser/views/generic_info_view.h
new file mode 100644
index 0000000..ff03b14
--- /dev/null
+++ b/chrome/browser/views/generic_info_view.h
@@ -0,0 +1,66 @@
+// 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_GENERIC_INFO_VIEW_H_
+#define CHROME_BROWSER_VIEWS_GENERIC_INFO_VIEW_H_
+
+#include "base/scoped_ptr.h"
+#include "base/string16.h"
+#include "testing/gtest/include/gtest/gtest_prod.h"
+#include "views/view.h"
+
+namespace views {
+class GridLayout;
+class Label;
+class Textfield;
+}
+
+// GenericInfoView, displays a tabular grid of read-only textual information,
+// <name, value> pairs. The fixed number of rows must be known at the time of
+// construction.
+class GenericInfoView : public views::View {
+ public:
+ // Constructs a info view with |number_of_rows| and populated with
+ // empty strings.
+ explicit GenericInfoView(int number_of_rows);
+
+ // Constructs a info view with |number_of_rows|, and populates
+ // the name column with localized strings having the given
+ // |name_string_ids|. The array of ids should contain |number_of_rows|
+ // values and should remain valid for the life of the view.
+ GenericInfoView(int number_of_rows, const int name_string_ids[]);
+
+ // The following methods should only be called after
+ // the view has been added to a view hierarchy.
+ void SetNameByStringId(int row, int id);
+ void SetName(int row, const string16& name);
+ void SetValue(int row, const string16& value);
+ void ClearValues() {
+ const string16 kEmptyString;
+ for (int i = 0; i < number_of_rows_; ++i)
+ SetValue(i, kEmptyString);
+ }
+
+ protected:
+ // views::View override
+ virtual void ViewHierarchyChanged(
+ bool is_add, views::View* parent, views::View* child);
+
+ private:
+ FRIEND_TEST(GenericInfoViewTest, GenericInfoView);
+
+ void InitGenericInfoView();
+ void AddRow(int layout_id, views::GridLayout* layout,
+ views::Label* name, views::Textfield* value);
+
+ const int number_of_rows_;
+ const int* name_string_ids_;
+ scoped_array<views::Label*> name_views_;
+ scoped_array<views::Textfield*> value_views_;
+
+ DISALLOW_COPY_AND_ASSIGN(GenericInfoView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_GENERIC_INFO_VIEW_H_
+
diff --git a/chrome/browser/views/generic_info_view_unittest.cc b/chrome/browser/views/generic_info_view_unittest.cc
new file mode 100644
index 0000000..ca0a030
--- /dev/null
+++ b/chrome/browser/views/generic_info_view_unittest.cc
@@ -0,0 +1,62 @@
+// 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 "app/l10n_util.h"
+#include "chrome/browser/views/generic_info_view.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "views/controls/label.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/widget/root_view.h"
+#if defined(OS_WIN)
+#include "views/widget/widget_win.h"
+#endif
+#include "views/window/window.h"
+
+// This class is only used on windows for now.
+#if defined(OS_WIN)
+
+using namespace views;
+
+class GenericInfoViewTest : public testing::Test {
+ public:
+ Widget* CreateWidget() {
+ return new WidgetWin();
+ }
+ private:
+ MessageLoopForUI message_loop_;
+};
+
+TEST_F(GenericInfoViewTest, GenericInfoView) {
+ const string16 kName = ASCIIToUTF16("Name");
+ const string16 kValue = ASCIIToUTF16("Value");
+
+ Widget* window = CreateWidget();
+ static_cast<WidgetWin*>(window)->Init(NULL, gfx::Rect(0, 0, 100, 100));
+ RootView* root_view = window->GetRootView();
+
+ GenericInfoView* view1 = new GenericInfoView(1);
+ root_view->AddChildView(view1);
+ view1->SetName(0, kName);
+ view1->SetValue(0, kValue);
+ EXPECT_EQ(kName, view1->name_views_[0]->GetText());
+ EXPECT_EQ(kValue, view1->value_views_[0]->text());
+ view1->ClearValues();
+ EXPECT_TRUE(view1->value_views_[0]->text().empty());
+
+ // Test setting values by localized string id.
+ static int kNameIds[] = {
+ IDS_PRODUCT_NAME,
+ IDS_PRODUCT_DESCRIPTION
+ };
+ GenericInfoView* view2 = new GenericInfoView(ARRAYSIZE(kNameIds), kNameIds);
+ root_view->AddChildView(view2);
+
+ string16 product_name = l10n_util::GetString(IDS_PRODUCT_NAME);
+ string16 product_desc = l10n_util::GetString(IDS_PRODUCT_DESCRIPTION);
+ EXPECT_EQ(product_name, view2->name_views_[0]->GetText());
+ EXPECT_EQ(product_desc, view2->name_views_[1]->GetText());
+}
+#endif // OS_WIN
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a0596e6..8c13b7f 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2188,6 +2188,8 @@
'browser/views/frame/opaque_browser_frame_view.h',
'browser/views/fullscreen_exit_bubble.cc',
'browser/views/fullscreen_exit_bubble.h',
+ 'browser/views/generic_info_view.cc',
+ 'browser/views/generic_info_view.h',
'browser/views/go_button.cc',
'browser/views/go_button.h',
'browser/views/html_dialog_view.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index b641527..afa4f7a 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -908,6 +908,7 @@
'browser/views/bookmark_context_menu_test.cc',
'browser/views/bookmark_editor_view_unittest.cc',
'browser/views/extensions/browser_action_drag_data_unittest.cc',
+ 'browser/views/generic_info_view_unittest.cc',
'browser/visitedlink_unittest.cc',
'browser/webdata/web_data_service_unittest.cc',
'browser/webdata/web_database_unittest.cc',
@@ -1145,6 +1146,7 @@
'browser/views/bookmark_editor_view_unittest.cc',
'browser/views/extensions/browser_action_drag_data_unittest.cc',
'browser/views/find_bar_host_unittest.cc',
+ 'browser/views/generic_info_view_unittest.cc',
'browser/views/keyword_editor_view_unittest.cc',
'common/net/url_util_unittest.cc',
],