OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 11 matching lines...) Expand all Loading... | |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #include "core/page/CreateWindow.h" | 27 #include "core/page/CreateWindow.h" |
28 | 28 |
29 #include "bindings/core/v8/ExceptionState.h" | 29 #include "bindings/core/v8/ExceptionState.h" |
30 #include "core/dom/Document.h" | 30 #include "core/dom/Document.h" |
31 #include "core/dom/UserGestureIndicator.h" | 31 #include "core/dom/UserGestureIndicator.h" |
32 #include "core/events/UIEventWithKeyState.h" | |
32 #include "core/frame/FrameClient.h" | 33 #include "core/frame/FrameClient.h" |
33 #include "core/frame/LocalFrame.h" | 34 #include "core/frame/LocalFrame.h" |
34 #include "core/frame/Settings.h" | 35 #include "core/frame/Settings.h" |
35 #include "core/inspector/ConsoleMessage.h" | 36 #include "core/inspector/ConsoleMessage.h" |
36 #include "core/loader/FrameLoadRequest.h" | 37 #include "core/loader/FrameLoadRequest.h" |
37 #include "core/page/ChromeClient.h" | 38 #include "core/page/ChromeClient.h" |
38 #include "core/page/FocusController.h" | 39 #include "core/page/FocusController.h" |
39 #include "core/page/Page.h" | 40 #include "core/page/Page.h" |
40 #include "core/page/WindowFeatures.h" | 41 #include "core/page/WindowFeatures.h" |
41 #include "core/probe/CoreProbes.h" | 42 #include "core/probe/CoreProbes.h" |
43 #include "platform/KeyboardCodes.h" | |
42 #include "platform/loader/fetch/ResourceRequest.h" | 44 #include "platform/loader/fetch/ResourceRequest.h" |
43 #include "platform/weborigin/KURL.h" | 45 #include "platform/weborigin/KURL.h" |
44 #include "platform/weborigin/SecurityOrigin.h" | 46 #include "platform/weborigin/SecurityOrigin.h" |
45 #include "platform/weborigin/SecurityPolicy.h" | 47 #include "platform/weborigin/SecurityPolicy.h" |
48 #include "public/platform/WebInputEvent.h" | |
49 #include "public/platform/WebKeyboardEvent.h" | |
50 #include "public/platform/WebMouseEvent.h" | |
46 #include "public/platform/WebURLRequest.h" | 51 #include "public/platform/WebURLRequest.h" |
47 | 52 |
48 namespace blink { | 53 namespace blink { |
49 | 54 |
55 void UpdatePolicyForEvent(const WebInputEvent* input_event, | |
kinuko
2017/06/01 06:39:28
nit: put these in anon namespace except for Effect
Nate Chapin
2017/06/01 20:57:11
Done.
| |
56 NavigationPolicy* policy) { | |
57 if (!input_event) | |
58 return; | |
59 | |
60 unsigned short button_number = 0; | |
61 if (input_event->GetType() == WebInputEvent::kMouseUp) { | |
62 const WebMouseEvent* mouse_event = | |
63 static_cast<const WebMouseEvent*>(input_event); | |
64 | |
65 switch (mouse_event->button) { | |
66 case WebMouseEvent::Button::kLeft: | |
67 button_number = 0; | |
68 break; | |
69 case WebMouseEvent::Button::kMiddle: | |
70 button_number = 1; | |
71 break; | |
72 case WebMouseEvent::Button::kRight: | |
73 button_number = 2; | |
74 break; | |
75 default: | |
76 return; | |
77 } | |
78 } else if ((WebInputEvent::IsKeyboardEventType(input_event->GetType()) && | |
79 static_cast<const WebKeyboardEvent*>(input_event) | |
80 ->windows_key_code == VKEY_RETURN) || | |
81 WebInputEvent::IsGestureEventType(input_event->GetType())) { | |
82 // Keyboard and gesture events can simulate mouse events. | |
83 button_number = 0; | |
84 } else { | |
85 return; | |
86 } | |
87 | |
88 bool ctrl = input_event->GetModifiers() & WebInputEvent::kControlKey; | |
89 bool shift = input_event->GetModifiers() & WebInputEvent::kShiftKey; | |
90 bool alt = input_event->GetModifiers() & WebInputEvent::kAltKey; | |
91 bool meta = input_event->GetModifiers() & WebInputEvent::kMetaKey; | |
92 | |
93 NavigationPolicy user_policy = *policy; | |
94 NavigationPolicyFromMouseEvent(button_number, ctrl, shift, alt, meta, | |
95 &user_policy); | |
96 | |
97 // When the input event suggests a download, but the navigation was initiated | |
98 // by script, we should not override it. | |
99 if (user_policy == kNavigationPolicyDownload && | |
100 *policy != kNavigationPolicyIgnore) | |
101 return; | |
102 | |
103 // User and app agree that we want a new window; let the app override the | |
104 // decorations. | |
105 if (user_policy == kNavigationPolicyNewWindow && | |
106 *policy == kNavigationPolicyNewPopup) | |
107 return; | |
108 *policy = user_policy; | |
109 } | |
110 | |
111 NavigationPolicy GetNavigationPolicy(const WebInputEvent* current_event, | |
112 bool toolbar_visible) { | |
113 // If the window features didn't enable the toolbar, or this window wasn't | |
114 // created by a user gesture, show as a popup instead of a new tab. | |
115 // | |
116 // Note: this previously also checked that menubar, resizable, scrollbar, and | |
117 // statusbar are enabled too. When no feature string is specified, these | |
118 // features default to enabled (and the window opens as a new tab). However, | |
119 // when a feature string is specified, any *unspecified* features default to | |
120 // disabled, often causing the window to open as a popup instead. | |
121 // | |
122 // As specifying menubar, resizable, scrollbar, and statusbar have no effect | |
123 // on the UI, just ignore them and only consider whether or not the toolbar is | |
124 // enabled, which matches Firefox's behavior. | |
125 NavigationPolicy policy = toolbar_visible ? kNavigationPolicyNewForegroundTab | |
126 : kNavigationPolicyNewPopup; | |
127 UpdatePolicyForEvent(current_event, &policy); | |
128 return policy; | |
129 } | |
130 | |
131 NavigationPolicy EffectiveNavigationPolicy(NavigationPolicy policy, | |
132 const WebInputEvent* current_event, | |
133 bool toolbar_visible) { | |
134 if (policy == kNavigationPolicyIgnore) | |
135 return GetNavigationPolicy(current_event, toolbar_visible); | |
136 if (policy == kNavigationPolicyNewBackgroundTab && | |
137 GetNavigationPolicy(current_event, toolbar_visible) != | |
138 kNavigationPolicyNewBackgroundTab && | |
139 !UIEventWithKeyState::NewTabModifierSetFromIsolatedWorld()) { | |
140 return kNavigationPolicyNewForegroundTab; | |
141 } | |
142 return policy; | |
143 } | |
144 | |
50 static Frame* ReuseExistingWindow(LocalFrame& active_frame, | 145 static Frame* ReuseExistingWindow(LocalFrame& active_frame, |
51 LocalFrame& lookup_frame, | 146 LocalFrame& lookup_frame, |
52 const AtomicString& frame_name, | 147 const AtomicString& frame_name, |
53 NavigationPolicy policy) { | 148 NavigationPolicy policy) { |
54 if (!frame_name.IsEmpty() && !EqualIgnoringASCIICase(frame_name, "_blank") && | 149 if (!frame_name.IsEmpty() && !EqualIgnoringASCIICase(frame_name, "_blank") && |
55 policy == kNavigationPolicyIgnore) { | 150 policy == kNavigationPolicyIgnore) { |
56 if (Frame* frame = | 151 if (Frame* frame = |
57 lookup_frame.FindFrameForNavigation(frame_name, active_frame)) { | 152 lookup_frame.FindFrameForNavigation(frame_name, active_frame)) { |
58 if (!EqualIgnoringASCIICase(frame_name, "_self")) { | 153 if (!EqualIgnoringASCIICase(frame_name, "_self")) { |
59 if (Page* page = frame->GetPage()) { | 154 if (Page* page = frame->GetPage()) { |
(...skipping 11 matching lines...) Expand all Loading... | |
71 | 166 |
72 static Frame* CreateNewWindow(LocalFrame& opener_frame, | 167 static Frame* CreateNewWindow(LocalFrame& opener_frame, |
73 const FrameLoadRequest& request, | 168 const FrameLoadRequest& request, |
74 const WindowFeatures& features, | 169 const WindowFeatures& features, |
75 NavigationPolicy policy, | 170 NavigationPolicy policy, |
76 bool& created) { | 171 bool& created) { |
77 Page* old_page = opener_frame.GetPage(); | 172 Page* old_page = opener_frame.GetPage(); |
78 if (!old_page) | 173 if (!old_page) |
79 return nullptr; | 174 return nullptr; |
80 | 175 |
176 policy = EffectiveNavigationPolicy( | |
Nate Chapin
2017/05/31 16:55:13
Bonus of calling this: here we only need to do it
| |
177 policy, old_page->GetChromeClient().GetCurrentInputEvent(), | |
178 features.tool_bar_visible); | |
179 | |
81 Page* page = old_page->GetChromeClient().CreateWindow(&opener_frame, request, | 180 Page* page = old_page->GetChromeClient().CreateWindow(&opener_frame, request, |
82 features, policy); | 181 features, policy); |
83 if (!page) | 182 if (!page) |
84 return nullptr; | 183 return nullptr; |
85 | 184 |
86 if (page == old_page) | 185 if (page == old_page) |
87 return &opener_frame.Tree().Top(); | 186 return &opener_frame.Tree().Top(); |
88 | 187 |
89 DCHECK(page->MainFrame()); | 188 DCHECK(page->MainFrame()); |
90 LocalFrame& frame = *ToLocalFrame(page->MainFrame()); | 189 LocalFrame& frame = *ToLocalFrame(page->MainFrame()); |
91 | 190 |
92 if (!EqualIgnoringASCIICase(request.FrameName(), "_blank")) | 191 if (!EqualIgnoringASCIICase(request.FrameName(), "_blank")) |
93 frame.Tree().SetName(request.FrameName()); | 192 frame.Tree().SetName(request.FrameName()); |
94 | 193 |
95 page->GetChromeClient().SetWindowFeatures(features); | 194 page->SetWindowFeatures(features); |
195 | |
196 frame.View()->SetCanHaveScrollbars(features.scrollbars_visible); | |
Nate Chapin
2017/05/31 16:55:12
This was a side effect of ChromeClientImpl::SetScr
| |
96 | 197 |
97 // 'x' and 'y' specify the location of the window, while 'width' and 'height' | 198 // 'x' and 'y' specify the location of the window, while 'width' and 'height' |
98 // specify the size of the viewport. We can only resize the window, so adjust | 199 // specify the size of the viewport. We can only resize the window, so adjust |
99 // for the difference between the window size and the viewport size. | 200 // for the difference between the window size and the viewport size. |
100 | 201 |
101 IntRect window_rect = page->GetChromeClient().RootWindowRect(); | 202 IntRect window_rect = page->GetChromeClient().RootWindowRect(); |
102 IntSize viewport_size = page->GetChromeClient().PageRect().Size(); | 203 IntSize viewport_size = page->GetChromeClient().PageRect().Size(); |
103 | 204 |
104 if (features.x_set) | 205 if (features.x_set) |
105 window_rect.SetX(features.x); | 206 window_rect.SetX(features.x); |
(...skipping 20 matching lines...) Expand all Loading... | |
126 return &frame; | 227 return &frame; |
127 } | 228 } |
128 | 229 |
129 static Frame* CreateWindowHelper(LocalFrame& opener_frame, | 230 static Frame* CreateWindowHelper(LocalFrame& opener_frame, |
130 LocalFrame& active_frame, | 231 LocalFrame& active_frame, |
131 LocalFrame& lookup_frame, | 232 LocalFrame& lookup_frame, |
132 const FrameLoadRequest& request, | 233 const FrameLoadRequest& request, |
133 const WindowFeatures& features, | 234 const WindowFeatures& features, |
134 NavigationPolicy policy, | 235 NavigationPolicy policy, |
135 bool& created) { | 236 bool& created) { |
136 DCHECK(!features.dialog || request.FrameName().IsEmpty()); | |
137 DCHECK(request.GetResourceRequest().RequestorOrigin() || | 237 DCHECK(request.GetResourceRequest().RequestorOrigin() || |
138 opener_frame.GetDocument()->Url().IsEmpty()); | 238 opener_frame.GetDocument()->Url().IsEmpty()); |
139 DCHECK_EQ(request.GetResourceRequest().GetFrameType(), | 239 DCHECK_EQ(request.GetResourceRequest().GetFrameType(), |
140 WebURLRequest::kFrameTypeAuxiliary); | 240 WebURLRequest::kFrameTypeAuxiliary); |
141 | 241 |
142 created = false; | 242 created = false; |
143 | 243 |
144 Frame* window = features.noopener | 244 Frame* window = features.noopener |
145 ? nullptr | 245 ? nullptr |
146 : ReuseExistingWindow(active_frame, lookup_frame, | 246 : ReuseExistingWindow(active_frame, lookup_frame, |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 } | 389 } |
290 | 390 |
291 // TODO(japhet): Form submissions on RemoteFrames don't work yet. | 391 // TODO(japhet): Form submissions on RemoteFrames don't work yet. |
292 FrameLoadRequest new_request(0, request.GetResourceRequest()); | 392 FrameLoadRequest new_request(0, request.GetResourceRequest()); |
293 new_request.SetForm(request.Form()); | 393 new_request.SetForm(request.Form()); |
294 if (new_frame->IsLocalFrame()) | 394 if (new_frame->IsLocalFrame()) |
295 ToLocalFrame(new_frame)->Loader().Load(new_request); | 395 ToLocalFrame(new_frame)->Loader().Load(new_request); |
296 } | 396 } |
297 | 397 |
298 } // namespace blink | 398 } // namespace blink |
OLD | NEW |