Home | History | Annotate | Download | only in webui
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/webui/collected_cookies_ui_delegate.h"
      6 
      7 #include "base/message_loop.h"
      8 #include "base/string_util.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/cookies_tree_model.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
     13 #include "chrome/browser/ui/webui/constrained_html_ui.h"
     14 #include "chrome/browser/ui/webui/cookies_tree_model_util.h"
     15 #include "chrome/common/jstemplate_builder.h"
     16 #include "chrome/common/url_constants.h"
     17 #include "content/browser/tab_contents/tab_contents.h"
     18 #include "content/common/notification_service.h"
     19 #include "grit/browser_resources.h"
     20 #include "grit/generated_resources.h"
     21 #include "ui/base/l10n/l10n_util.h"
     22 #include "ui/base/resource/resource_bundle.h"
     23 #include "ui/gfx/size.h"
     24 
     25 namespace {
     26 
     27 // TODO(xiyuan): Localize this.
     28 const int kDialogWidth = 480;
     29 const int kDialogHeight = 470;
     30 
     31 CookieTreeOriginNode* GetOriginNode(CookiesTreeModel* model,
     32                                     const std::string& node_path) {
     33   CookieTreeNode* node = cookies_tree_model_util::GetTreeNodeFromPath(
     34       model->GetRoot(), node_path);
     35 
     36   while (node && node->GetDetailedInfo().node_type !=
     37                  CookieTreeNode::DetailedInfo::TYPE_ORIGIN) {
     38     node = node->parent();
     39   }
     40 
     41   return static_cast<CookieTreeOriginNode*>(node);
     42 }
     43 
     44 std::string GetInfobarLabel(ContentSetting setting,
     45                             const string16& domain_name) {
     46   switch (setting) {
     47     case CONTENT_SETTING_BLOCK:
     48       return l10n_util::GetStringFUTF8(
     49           IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name);
     50 
     51     case CONTENT_SETTING_ALLOW:
     52       return l10n_util::GetStringFUTF8(
     53           IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name);
     54 
     55     case CONTENT_SETTING_SESSION_ONLY:
     56       return l10n_util::GetStringFUTF8(
     57           IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name);
     58 
     59     default:
     60       NOTREACHED() << "Unknown ContentSetting, " << setting;
     61       return std::string();
     62   }
     63 }
     64 
     65 class CollectedCookiesSource : public ChromeURLDataManager::DataSource {
     66  public:
     67   explicit CollectedCookiesSource(bool block_third_party_cookies)
     68       : DataSource(chrome::kChromeUICollectedCookiesHost,
     69                    MessageLoop::current()),
     70         block_third_party_cookies_(block_third_party_cookies) {
     71   }
     72 
     73   virtual void StartDataRequest(const std::string& path,
     74                                 bool is_incognito,
     75                                 int request_id);
     76 
     77   virtual std::string GetMimeType(const std::string& path) const {
     78     return "text/html";
     79   }
     80 
     81  private:
     82   virtual ~CollectedCookiesSource() {}
     83 
     84   bool block_third_party_cookies_;
     85 
     86   DISALLOW_COPY_AND_ASSIGN(CollectedCookiesSource);
     87 };
     88 
     89 void CollectedCookiesSource::StartDataRequest(const std::string& path,
     90                                               bool is_incognito,
     91                                               int request_id) {
     92   DictionaryValue localized_strings;
     93   localized_strings.SetString("title",
     94       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE));
     95 
     96   localized_strings.SetString("title",
     97       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE));
     98   localized_strings.SetString("allowedCookies",
     99       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL));
    100   localized_strings.SetString("blockButton",
    101       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON));
    102 
    103   localized_strings.SetString("blockedCookies",
    104       l10n_util::GetStringUTF16(block_third_party_cookies_ ?
    105           IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED :
    106           IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL));
    107 
    108   localized_strings.SetString("allowButton",
    109       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON));
    110   localized_strings.SetString("allowThisSessionButton",
    111       l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON));
    112   localized_strings.SetString("closeButton",
    113       l10n_util::GetStringUTF16(IDS_CLOSE));
    114 
    115   SetFontAndTextDirection(&localized_strings);
    116 
    117   static const base::StringPiece html(
    118       ResourceBundle::GetSharedInstance().GetRawDataResource(
    119           IDR_COLLECTED_COOKIES_HTML));
    120   const std::string response = jstemplate_builder::GetI18nTemplateHtml(
    121       html, &localized_strings);
    122 
    123   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
    124   html_bytes->data.resize(response.size());
    125   std::copy(response.begin(), response.end(), html_bytes->data.begin());
    126 
    127   SendResponse(request_id, html_bytes);
    128 }
    129 
    130 }  // namespace
    131 
    132 // static
    133 void CollectedCookiesUIDelegate::Show(TabContents* tab_contents) {
    134   CollectedCookiesUIDelegate* delegate =
    135       new CollectedCookiesUIDelegate(tab_contents);
    136   ConstrainedHtmlUI::CreateConstrainedHtmlDialog(tab_contents->profile(),
    137                                                  delegate,
    138                                                  tab_contents);
    139 }
    140 
    141 CollectedCookiesUIDelegate::CollectedCookiesUIDelegate(
    142     TabContents* tab_contents)
    143     : tab_contents_(tab_contents),
    144       closed_(false) {
    145   TabSpecificContentSettings* content_settings =
    146       tab_contents->GetTabSpecificContentSettings();
    147   HostContentSettingsMap* host_content_settings_map =
    148       tab_contents_->profile()->GetHostContentSettingsMap();
    149 
    150   registrar_.Add(this, NotificationType::COLLECTED_COOKIES_SHOWN,
    151                  Source<TabSpecificContentSettings>(content_settings));
    152 
    153   allowed_cookies_tree_model_.reset(
    154       content_settings->GetAllowedCookiesTreeModel());
    155   blocked_cookies_tree_model_.reset(
    156       content_settings->GetBlockedCookiesTreeModel());
    157 
    158   CollectedCookiesSource* source = new CollectedCookiesSource(
    159       host_content_settings_map->BlockThirdPartyCookies());
    160   tab_contents->profile()->GetChromeURLDataManager()->AddDataSource(source);
    161 }
    162 
    163 CollectedCookiesUIDelegate::~CollectedCookiesUIDelegate() {
    164 }
    165 
    166 bool CollectedCookiesUIDelegate::IsDialogModal() const {
    167   return false;
    168 }
    169 
    170 std::wstring CollectedCookiesUIDelegate::GetDialogTitle() const {
    171   return std::wstring();
    172 }
    173 
    174 GURL CollectedCookiesUIDelegate::GetDialogContentURL() const {
    175   return GURL(chrome::kChromeUICollectedCookiesURL);
    176 }
    177 
    178 void CollectedCookiesUIDelegate::GetWebUIMessageHandlers(
    179     std::vector<WebUIMessageHandler*>* handlers) const {
    180   const WebUIMessageHandler* handler = this;
    181   handlers->push_back(const_cast<WebUIMessageHandler*>(handler));
    182 }
    183 
    184 void CollectedCookiesUIDelegate::GetDialogSize(gfx::Size* size) const {
    185   size->set_width(kDialogWidth);
    186   size->set_height(kDialogHeight);
    187 }
    188 
    189 std::string CollectedCookiesUIDelegate::GetDialogArgs() const {
    190   return std::string();
    191 }
    192 
    193 void CollectedCookiesUIDelegate::OnDialogClosed(
    194     const std::string& json_retval) {
    195   closed_ = true;
    196 }
    197 
    198 bool CollectedCookiesUIDelegate::ShouldShowDialogTitle() const {
    199   return true;
    200 }
    201 
    202 void CollectedCookiesUIDelegate::RegisterMessages() {
    203   web_ui_->RegisterMessageCallback("BindCookiesTreeModel",
    204       NewCallback(this, &CollectedCookiesUIDelegate::BindCookiesTreeModel));
    205   web_ui_->RegisterMessageCallback("Block",
    206       NewCallback(this, &CollectedCookiesUIDelegate::Block));
    207   web_ui_->RegisterMessageCallback("Allow",
    208       NewCallback(this, &CollectedCookiesUIDelegate::Allow));
    209   web_ui_->RegisterMessageCallback("AllowThisSession",
    210       NewCallback(this, &CollectedCookiesUIDelegate::AllowThisSession));
    211 
    212   allowed_cookies_adapter_.Init(web_ui_);
    213   blocked_cookies_adapter_.Init(web_ui_);
    214 }
    215 
    216 void CollectedCookiesUIDelegate::CloseDialog() {
    217   if (!closed_ && web_ui_)
    218     web_ui_->CallJavascriptFunction("closeDialog");
    219 }
    220 
    221 void CollectedCookiesUIDelegate::SetInfobarLabel(const std::string& text) {
    222   StringValue string(text);
    223   web_ui_->CallJavascriptFunction("setInfobarLabel", string);
    224 }
    225 
    226 void CollectedCookiesUIDelegate::AddContentException(
    227     CookieTreeOriginNode* origin_node, ContentSetting setting) {
    228   if (origin_node->CanCreateContentException()) {
    229     origin_node->CreateContentException(
    230         tab_contents_->profile()->GetHostContentSettingsMap(), setting);
    231 
    232     SetInfobarLabel(GetInfobarLabel(setting, origin_node->GetTitle()));
    233   }
    234 }
    235 
    236 void CollectedCookiesUIDelegate::Observe(NotificationType type,
    237                                          const NotificationSource& source,
    238                                          const NotificationDetails& details) {
    239   DCHECK_EQ(type.value, NotificationType::COLLECTED_COOKIES_SHOWN);
    240   DCHECK_EQ(Source<TabSpecificContentSettings>(source).ptr(),
    241             tab_contents_->GetTabSpecificContentSettings());
    242   CloseDialog();
    243 }
    244 
    245 void CollectedCookiesUIDelegate::BindCookiesTreeModel(const ListValue* args) {
    246   allowed_cookies_adapter_.Bind("allowed-cookies",
    247       allowed_cookies_tree_model_.get());
    248   blocked_cookies_adapter_.Bind("blocked-cookies",
    249       blocked_cookies_tree_model_.get());
    250 }
    251 
    252 void CollectedCookiesUIDelegate::Block(const ListValue* args) {
    253   std::string node_path;
    254   if (!args->GetString(0, &node_path))
    255     return;
    256 
    257   CookieTreeOriginNode* origin_node = GetOriginNode(
    258       allowed_cookies_tree_model_.get(), node_path);
    259   if (!origin_node)
    260     return;
    261 
    262   AddContentException(origin_node, CONTENT_SETTING_BLOCK);
    263 }
    264 
    265 void CollectedCookiesUIDelegate::Allow(const ListValue* args) {
    266   std::string node_path;
    267   if (!args->GetString(0, &node_path))
    268     return;
    269 
    270   CookieTreeOriginNode* origin_node = GetOriginNode(
    271       blocked_cookies_tree_model_.get(), node_path);
    272   if (!origin_node)
    273     return;
    274 
    275   AddContentException(origin_node, CONTENT_SETTING_ALLOW);
    276 }
    277 
    278 void CollectedCookiesUIDelegate::AllowThisSession(const ListValue* args) {
    279   std::string node_path;
    280   if (!args->GetString(0, &node_path))
    281     return;
    282 
    283   CookieTreeOriginNode* origin_node = GetOriginNode(
    284       blocked_cookies_tree_model_.get(), node_path);
    285   if (!origin_node)
    286     return;
    287 
    288   AddContentException(origin_node, CONTENT_SETTING_SESSION_ONLY);
    289 }
    290