Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / blocked_content / popup_blocker_tab_helper.cc
1 // Copyright 2013 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/blocked_content/popup_blocker_tab_helper.h"
6
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/blocked_content/blocked_window_params.h"
11 #include "chrome/browser/ui/browser_navigator.h"
12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
13 #include "chrome/common/render_messages.h"
14 #include "components/content_settings/core/browser/host_content_settings_map.h"
15 #include "content/public/browser/navigation_controller.h"
16 #include "content/public/browser/navigation_details.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_delegate.h"
21 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
22
23 #if defined(OS_ANDROID)
24 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
25 #endif
26
27 using blink::WebWindowFeatures;
28
29 const size_t kMaximumNumberOfPopups = 25;
30
31 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PopupBlockerTabHelper);
32
33 struct PopupBlockerTabHelper::BlockedRequest {
34   BlockedRequest(const chrome::NavigateParams& params,
35                  const WebWindowFeatures& window_features)
36       : params(params), window_features(window_features) {}
37
38   chrome::NavigateParams params;
39   WebWindowFeatures window_features;
40 };
41
42 PopupBlockerTabHelper::PopupBlockerTabHelper(
43     content::WebContents* web_contents)
44     : content::WebContentsObserver(web_contents) {
45 }
46
47 PopupBlockerTabHelper::~PopupBlockerTabHelper() {
48 }
49
50 void PopupBlockerTabHelper::DidNavigateMainFrame(
51     const content::LoadCommittedDetails& details,
52     const content::FrameNavigateParams& params) {
53   // Clear all page actions, blocked content notifications and browser actions
54   // for this tab, unless this is an in-page navigation.
55   if (details.is_in_page)
56     return;
57
58   // Close blocked popups.
59   if (!blocked_popups_.IsEmpty()) {
60     blocked_popups_.Clear();
61     PopupNotificationVisibilityChanged(false);
62   }
63 }
64
65 void PopupBlockerTabHelper::PopupNotificationVisibilityChanged(
66     bool visible) {
67   if (!web_contents()->IsBeingDestroyed()) {
68     TabSpecificContentSettings::FromWebContents(web_contents())->
69         SetPopupsBlocked(visible);
70   }
71 }
72
73 bool PopupBlockerTabHelper::MaybeBlockPopup(
74     const chrome::NavigateParams& params,
75     const WebWindowFeatures& window_features) {
76   // A page can't spawn popups (or do anything else, either) until its load
77   // commits, so when we reach here, the popup was spawned by the
78   // NavigationController's last committed entry, not the active entry.  For
79   // example, if a page opens a popup in an onunload() handler, then the active
80   // entry is the page to be loaded as we navigate away from the unloading
81   // page.  For this reason, we can't use GetURL() to get the opener URL,
82   // because it returns the active entry.
83   content::NavigationEntry* entry =
84       web_contents()->GetController().GetLastCommittedEntry();
85   GURL creator = entry ? entry->GetVirtualURL() : GURL();
86   Profile* profile =
87       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
88
89   if (creator.is_valid() &&
90       profile->GetHostContentSettingsMap()->GetContentSetting(
91           creator, creator, CONTENT_SETTINGS_TYPE_POPUPS, std::string()) ==
92           CONTENT_SETTING_ALLOW) {
93     return false;
94   } else {
95     if (blocked_popups_.size() < kMaximumNumberOfPopups) {
96       blocked_popups_.Add(new BlockedRequest(params, window_features));
97       TabSpecificContentSettings::FromWebContents(web_contents())->
98           OnContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS);
99     }
100     return true;
101   }
102 }
103
104 void PopupBlockerTabHelper::AddBlockedPopup(const BlockedWindowParams& params) {
105   chrome::NavigateParams nav_params =
106       params.CreateNavigateParams(web_contents());
107
108   if (blocked_popups_.size() < kMaximumNumberOfPopups) {
109     blocked_popups_.Add(new BlockedRequest(nav_params, params.features()));
110     TabSpecificContentSettings::FromWebContents(web_contents())->
111         OnContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS);
112   }
113 }
114
115 void PopupBlockerTabHelper::ShowBlockedPopup(int32 id) {
116   BlockedRequest* popup = blocked_popups_.Lookup(id);
117   if (!popup)
118     return;
119   // We set user_gesture to true here, so the new popup gets correctly focused.
120   popup->params.user_gesture = true;
121 #if defined(OS_ANDROID)
122   TabModelList::HandlePopupNavigation(&popup->params);
123 #else
124   chrome::Navigate(&popup->params);
125 #endif
126   if (popup->params.target_contents) {
127     popup->params.target_contents->Send(new ChromeViewMsg_SetWindowFeatures(
128         popup->params.target_contents->GetRoutingID(), popup->window_features));
129   }
130   blocked_popups_.Remove(id);
131   if (blocked_popups_.IsEmpty())
132     PopupNotificationVisibilityChanged(false);
133 }
134
135 size_t PopupBlockerTabHelper::GetBlockedPopupsCount() const {
136   return blocked_popups_.size();
137 }
138
139 PopupBlockerTabHelper::PopupIdMap
140     PopupBlockerTabHelper::GetBlockedPopupRequests() {
141   PopupIdMap result;
142   for (IDMap<BlockedRequest, IDMapOwnPointer>::const_iterator iter(
143            &blocked_popups_);
144        !iter.IsAtEnd();
145        iter.Advance()) {
146     result[iter.GetCurrentKey()] = iter.GetCurrentValue()->params.url;
147   }
148   return result;
149 }