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 29 matching lines...) Expand all Loading... | |
40 #include "core/page/WindowFeatures.h" | 40 #include "core/page/WindowFeatures.h" |
41 #include "platform/UserGestureIndicator.h" | 41 #include "platform/UserGestureIndicator.h" |
42 #include "platform/network/ResourceRequest.h" | 42 #include "platform/network/ResourceRequest.h" |
43 #include "platform/weborigin/KURL.h" | 43 #include "platform/weborigin/KURL.h" |
44 #include "platform/weborigin/SecurityOrigin.h" | 44 #include "platform/weborigin/SecurityOrigin.h" |
45 #include "platform/weborigin/SecurityPolicy.h" | 45 #include "platform/weborigin/SecurityPolicy.h" |
46 #include "public/platform/WebURLRequest.h" | 46 #include "public/platform/WebURLRequest.h" |
47 | 47 |
48 namespace blink { | 48 namespace blink { |
49 | 49 |
50 static Frame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame, con st FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy p olicy, ShouldSetOpener shouldSetOpener, bool& created) | 50 static Frame* reuseExistingWindow(LocalFrame& openerFrame, LocalFrame& lookupFra me, const AtomicString& frameName, NavigationPolicy policy) |
51 { | 51 { |
52 created = false; | 52 if (!frameName.isEmpty() && frameName != "_blank" && policy == NavigationPol icyIgnore) { |
53 | 53 if (Frame* frame = lookupFrame.findFrameForNavigation(frameName, openerF rame)) { |
54 ASSERT(!features.dialog || request.frameName().isEmpty()); | 54 if (frameName != "_self") { |
55 ASSERT(request.resourceRequest().requestorOrigin() || openerFrame.document() ->url().isEmpty()); | |
56 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeAuxi liary); | |
57 | |
58 if (!request.frameName().isEmpty() && request.frameName() != "_blank" && pol icy == NavigationPolicyIgnore) { | |
59 if (Frame* frame = lookupFrame.findFrameForNavigation(request.frameName( ), openerFrame)) { | |
60 if (request.frameName() != "_self") { | |
61 if (FrameHost* host = frame->host()) { | 55 if (FrameHost* host = frame->host()) { |
62 if (host == openerFrame.host()) | 56 if (host == openerFrame.host()) |
63 frame->page()->focusController().setFocusedFrame(frame); | 57 frame->page()->focusController().setFocusedFrame(frame); |
64 else | 58 else |
65 host->chromeClient().focus(); | 59 host->chromeClient().focus(); |
66 } | 60 } |
67 } | 61 } |
68 return frame; | 62 return frame; |
69 } | 63 } |
70 } | 64 } |
65 return nullptr; | |
66 } | |
71 | 67 |
72 // Sandboxed frames cannot open new auxiliary browsing contexts. | 68 static Frame* createNewWindow(LocalFrame& openerFrame, const FrameLoadRequest& r equest, const WindowFeatures& features, NavigationPolicy policy, ShouldSetOpener shouldSetOpener, bool& created) |
73 if (openerFrame.document()->isSandboxed(SandboxPopups)) { | 69 { |
74 // FIXME: This message should be moved off the console once a solution t o https://bugs.webkit.org/show_bug.cgi?id=103274 exists. | |
75 openerFrame.document()->addConsoleMessage(ConsoleMessage::create(Securit yMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest ().url().elidedString() + "' in a new window because the request was made in a s andboxed frame whose 'allow-popups' permission is not set.")); | |
76 return nullptr; | |
77 } | |
78 | |
79 if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindo ws()) | |
80 return openerFrame.tree().top(); | |
81 | |
82 FrameHost* oldHost = openerFrame.host(); | 70 FrameHost* oldHost = openerFrame.host(); |
83 if (!oldHost) | 71 if (!oldHost) |
84 return nullptr; | 72 return nullptr; |
85 | 73 |
86 Page* page = oldHost->chromeClient().createWindow(&openerFrame, request, fea tures, policy, shouldSetOpener); | 74 Page* page = oldHost->chromeClient().createWindow(&openerFrame, request, fea tures, policy, shouldSetOpener); |
87 if (!page) | 75 if (!page) |
88 return nullptr; | 76 return nullptr; |
89 FrameHost* host = &page->frameHost(); | 77 FrameHost* host = &page->frameHost(); |
90 | 78 |
91 ASSERT(page->mainFrame()); | 79 ASSERT(page->mainFrame()); |
(...skipping 25 matching lines...) Expand all Loading... | |
117 | 105 |
118 if (openerFrame.document()->isSandboxed(SandboxPropagatesToAuxiliaryBrowsing Contexts)) | 106 if (openerFrame.document()->isSandboxed(SandboxPropagatesToAuxiliaryBrowsing Contexts)) |
119 frame.loader().forceSandboxFlags(openerFrame.securityContext()->getSandb oxFlags()); | 107 frame.loader().forceSandboxFlags(openerFrame.securityContext()->getSandb oxFlags()); |
120 | 108 |
121 // This call may suspend the execution by running nested message loop. | 109 // This call may suspend the execution by running nested message loop. |
122 InspectorInstrumentation::windowCreated(&openerFrame, &frame); | 110 InspectorInstrumentation::windowCreated(&openerFrame, &frame); |
123 created = true; | 111 created = true; |
124 return &frame; | 112 return &frame; |
125 } | 113 } |
126 | 114 |
115 static Frame* createWindowHelper(LocalFrame& openerFrame, LocalFrame& lookupFram e, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPo licy policy, ShouldSetOpener shouldSetOpener, bool& created) | |
116 { | |
117 ASSERT(!features.dialog || request.frameName().isEmpty()); | |
118 ASSERT(request.resourceRequest().requestorOrigin() || openerFrame.document() ->url().isEmpty()); | |
119 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeAuxi liary); | |
120 | |
121 created = false; | |
122 | |
123 Frame* window = reuseExistingWindow(openerFrame, lookupFrame, request.frameN ame(), policy); | |
124 | |
125 if (!window) { | |
126 // Sandboxed frames cannot open new auxiliary browsing contexts. | |
127 if (openerFrame.document()->isSandboxed(SandboxPopups)) { | |
128 // FIXME: This message should be moved off the console once a soluti on to https://bugs.webkit.org/show_bug.cgi?id=103274 exists. | |
129 openerFrame.document()->addConsoleMessage(ConsoleMessage::create(Sec urityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceReq uest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.")); | |
130 return nullptr; | |
131 } | |
132 | |
133 if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleW indows()) | |
dcheng
2016/02/26 22:52:29
I wanted to remove this... but it turns out this i
| |
134 window = openerFrame.tree().top(); | |
135 } | |
136 | |
137 if (window) { | |
138 if (shouldSetOpener == MaybeSetOpener) | |
139 window->client()->setOpener(&openerFrame); | |
140 return window; | |
141 } | |
142 | |
143 return createNewWindow(openerFrame, request, features, policy, shouldSetOpen er, created); | |
144 } | |
145 | |
127 DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, | 146 DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, |
128 LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFra me) | 147 LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFra me) |
129 { | 148 { |
130 LocalFrame* activeFrame = callingWindow.frame(); | 149 LocalFrame* activeFrame = callingWindow.frame(); |
131 ASSERT(activeFrame); | 150 ASSERT(activeFrame); |
132 | 151 |
133 KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString( )) : firstFrame.document()->completeURL(urlString); | 152 KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString( )) : firstFrame.document()->completeURL(urlString); |
134 if (!completedURL.isEmpty() && !completedURL.isValid()) { | 153 if (!completedURL.isEmpty() && !completedURL.isValid()) { |
135 // Don't expose client code to invalid URLs. | 154 // Don't expose client code to invalid URLs. |
136 callingWindow.printErrorMessage("Unable to open a window with invalid UR L '" + completedURL.string() + "'.\n"); | 155 callingWindow.printErrorMessage("Unable to open a window with invalid UR L '" + completedURL.string() + "'.\n"); |
(...skipping 12 matching lines...) Expand all Loading... | |
149 frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateRefer rer(activeFrame->document()->getReferrerPolicy(), completedURL, activeFrame->doc ument()->outgoingReferrer())); | 168 frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateRefer rer(activeFrame->document()->getReferrerPolicy(), completedURL, activeFrame->doc ument()->outgoingReferrer())); |
150 | 169 |
151 // Records HasUserGesture before the value is invalidated inside createWindo w(LocalFrame& openerFrame, ...). | 170 // Records HasUserGesture before the value is invalidated inside createWindo w(LocalFrame& openerFrame, ...). |
152 // This value will be set in ResourceRequest loaded in a new LocalFrame. | 171 // This value will be set in ResourceRequest loaded in a new LocalFrame. |
153 bool hasUserGesture = UserGestureIndicator::processingUserGesture(); | 172 bool hasUserGesture = UserGestureIndicator::processingUserGesture(); |
154 | 173 |
155 // We pass the opener frame for the lookupFrame in case the active frame is different from | 174 // We pass the opener frame for the lookupFrame in case the active frame is different from |
156 // the opener frame, and the name references a frame relative to the opener frame. | 175 // the opener frame, and the name references a frame relative to the opener frame. |
157 bool created; | 176 bool created; |
158 ShouldSetOpener opener = windowFeatures.noopener ? NeverSetOpener : MaybeSet Opener; | 177 ShouldSetOpener opener = windowFeatures.noopener ? NeverSetOpener : MaybeSet Opener; |
159 Frame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, wind owFeatures, NavigationPolicyIgnore, opener, created); | 178 Frame* newFrame = createWindowHelper(*activeFrame, openerFrame, frameRequest , windowFeatures, NavigationPolicyIgnore, opener, created); |
160 if (!newFrame) | 179 if (!newFrame) |
161 return nullptr; | 180 return nullptr; |
162 | 181 |
163 if (!windowFeatures.noopener) | |
164 newFrame->client()->setOpener(&openerFrame); | |
165 | |
166 if (!newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedU RL)) { | 182 if (!newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedU RL)) { |
167 if (!urlString.isEmpty() || created) | 183 if (!urlString.isEmpty() || created) |
168 newFrame->navigate(*callingWindow.document(), completedURL, false, h asUserGesture ? UserGestureStatus::Active : UserGestureStatus::None); | 184 newFrame->navigate(*callingWindow.document(), completedURL, false, h asUserGesture ? UserGestureStatus::Active : UserGestureStatus::None); |
169 } | 185 } |
170 return newFrame->domWindow(); | 186 return newFrame->domWindow(); |
171 } | 187 } |
172 | 188 |
173 void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerF rame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, ShouldSetO pener shouldSetOpener) | 189 void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerF rame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, ShouldSetO pener shouldSetOpener) |
174 { | 190 { |
175 ASSERT(request.resourceRequest().requestorOrigin() || (openerFrame.document( ) && openerFrame.document()->url().isEmpty())); | 191 ASSERT(request.resourceRequest().requestorOrigin() || (openerFrame.document( ) && openerFrame.document()->url().isEmpty())); |
176 | 192 |
177 if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document: :NoDismissal) | 193 if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document: :NoDismissal) |
178 return; | 194 return; |
179 | 195 |
180 if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPop ups)) | 196 if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPop ups)) |
181 return; | 197 return; |
182 | 198 |
183 if (!LocalDOMWindow::allowPopUp(openerFrame)) | 199 if (!LocalDOMWindow::allowPopUp(openerFrame)) |
184 return; | 200 return; |
185 | 201 |
186 if (policy == NavigationPolicyCurrentTab) | 202 if (policy == NavigationPolicyCurrentTab) |
187 policy = NavigationPolicyNewForegroundTab; | 203 policy = NavigationPolicyNewForegroundTab; |
188 | 204 |
189 WindowFeatures features; | 205 WindowFeatures features; |
190 bool created; | 206 bool created; |
191 Frame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSetOpener, created); | 207 Frame* newFrame = createWindowHelper(openerFrame, openerFrame, request, feat ures, policy, shouldSetOpener, created); |
192 if (!newFrame) | 208 if (!newFrame) |
193 return; | 209 return; |
194 if (shouldSetOpener == MaybeSetOpener) | |
195 newFrame->client()->setOpener(&openerFrame); | |
196 if (shouldSendReferrer == MaybeSendReferrer) { | 210 if (shouldSendReferrer == MaybeSendReferrer) { |
197 // TODO(japhet): Does ReferrerPolicy need to be proagated for RemoteFram es? | 211 // TODO(japhet): Does ReferrerPolicy need to be proagated for RemoteFram es? |
198 if (newFrame->isLocalFrame()) | 212 if (newFrame->isLocalFrame()) |
199 toLocalFrame(newFrame)->document()->setReferrerPolicy(openerFrame.do cument()->getReferrerPolicy()); | 213 toLocalFrame(newFrame)->document()->setReferrerPolicy(openerFrame.do cument()->getReferrerPolicy()); |
200 } | 214 } |
201 | 215 |
202 // TODO(japhet): Form submissions on RemoteFrames don't work yet. | 216 // TODO(japhet): Form submissions on RemoteFrames don't work yet. |
203 FrameLoadRequest newRequest(0, request.resourceRequest()); | 217 FrameLoadRequest newRequest(0, request.resourceRequest()); |
204 newRequest.setForm(request.form()); | 218 newRequest.setForm(request.form()); |
205 if (newFrame->isLocalFrame()) | 219 if (newFrame->isLocalFrame()) |
206 toLocalFrame(newFrame)->loader().load(newRequest); | 220 toLocalFrame(newFrame)->loader().load(newRequest); |
207 } | 221 } |
208 | 222 |
209 } // namespace blink | 223 } // namespace blink |
OLD | NEW |