forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpopup_blocker.cc
131 lines (112 loc) · 5.06 KB
/
popup_blocker.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2018 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 "components/blocked_content/popup_blocker.h"
#include <string>
#include "base/check.h"
#include "base/command_line.h"
#include "components/blocked_content/popup_blocker_tab_helper.h"
#include "components/blocked_content/popup_navigation_delegate.h"
#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/embedder_support/switches.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-shared.h"
namespace blocked_content {
namespace {
content::Page& GetSourcePageForPopup(
const content::OpenURLParams* open_url_params,
content::WebContents* web_contents) {
if (open_url_params) {
content::RenderFrameHost* source = content::RenderFrameHost::FromID(
open_url_params->source_render_process_id,
open_url_params->source_render_frame_id);
if (source)
return source->GetPage();
}
// When there's no source RenderFrameHost, attribute the popup to the primary
// page.
return web_contents->GetPrimaryPage();
}
// If the popup should be blocked, returns the reason why it was blocked.
// Otherwise returns kNotBlocked.
PopupBlockType ShouldBlockPopup(content::WebContents* web_contents,
const GURL* opener_url,
bool user_gesture,
const content::OpenURLParams* open_url_params,
HostContentSettingsMap* settings_map) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
embedder_support::kDisablePopupBlocking)) {
return PopupBlockType::kNotBlocked;
}
// If an explicit opener is not given, use the current committed load in this
// web contents. This is because A page can't spawn popups (or do anything
// else, either) until its load commits, so when we reach here, the popup was
// spawned by the NavigationController's last committed entry, not the active
// entry. For example, if a page opens a popup in an onunload() handler, then
// the active entry is the page to be loaded as we navigate away from the
// unloading page.
const GURL& url =
opener_url ? *opener_url : web_contents->GetLastCommittedURL();
ContentSetting cs;
if (url.is_valid()) {
cs = settings_map->GetContentSetting(url, url, ContentSettingsType::POPUPS);
} else {
cs = settings_map->GetDefaultContentSetting(ContentSettingsType::POPUPS,
nullptr);
}
if (cs == CONTENT_SETTING_ALLOW)
return PopupBlockType::kNotBlocked;
if (!user_gesture)
return PopupBlockType::kNoGesture;
// This is trusted user action (e.g. shift-click), so make sure it is not
// blocked.
if (open_url_params &&
open_url_params->triggering_event_info !=
blink::mojom::TriggeringEventInfo::kFromUntrustedEvent) {
return PopupBlockType::kNotBlocked;
}
auto* safe_browsing_blocker =
SafeBrowsingTriggeredPopupBlocker::FromWebContents(web_contents);
if (safe_browsing_blocker &&
safe_browsing_blocker->ShouldApplyAbusivePopupBlocker(
GetSourcePageForPopup(open_url_params, web_contents))) {
return PopupBlockType::kAbusive;
}
return PopupBlockType::kNotBlocked;
}
} // namespace
bool ConsiderForPopupBlocking(WindowOpenDisposition disposition) {
return disposition == WindowOpenDisposition::NEW_POPUP ||
disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB ||
disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB ||
disposition == WindowOpenDisposition::NEW_WINDOW;
}
std::unique_ptr<PopupNavigationDelegate> MaybeBlockPopup(
content::WebContents* web_contents,
const GURL* opener_url,
std::unique_ptr<PopupNavigationDelegate> delegate,
const content::OpenURLParams* open_url_params,
const blink::mojom::WindowFeatures& window_features,
HostContentSettingsMap* settings_map) {
DCHECK(web_contents);
DCHECK(!open_url_params ||
open_url_params->user_gesture == delegate->GetOriginalUserGesture());
PopupBlockerTabHelper::LogAction(PopupBlockerTabHelper::Action::kInitiated);
// Check |popup_blocker| first since it is cheaper than ShouldBlockPopup().
auto* popup_blocker = PopupBlockerTabHelper::FromWebContents(web_contents);
if (!popup_blocker)
return delegate;
PopupBlockType block_type = ShouldBlockPopup(
web_contents, opener_url, delegate->GetOriginalUserGesture(),
open_url_params, settings_map);
if (block_type == PopupBlockType::kNotBlocked)
return delegate;
popup_blocker->AddBlockedPopup(std::move(delegate), window_features,
block_type);
return nullptr;
}
} // namespace blocked_content