Chromium Code Reviews| 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 |