Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: Source/core/page/CreateWindow.cpp

Issue 1109213002: Make createWindow (mostly) work with OOPIF (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix popup unit test failures Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 10 matching lines...) Expand all
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
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 "config.h" 27 #include "config.h"
28 #include "core/page/CreateWindow.h" 28 #include "core/page/CreateWindow.h"
29 29
30 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
31 #include "core/frame/FrameClient.h"
31 #include "core/frame/FrameHost.h" 32 #include "core/frame/FrameHost.h"
32 #include "core/frame/LocalFrame.h" 33 #include "core/frame/LocalFrame.h"
33 #include "core/frame/Settings.h" 34 #include "core/frame/Settings.h"
34 #include "core/inspector/ConsoleMessage.h" 35 #include "core/inspector/ConsoleMessage.h"
35 #include "core/loader/FrameLoadRequest.h" 36 #include "core/loader/FrameLoadRequest.h"
36 #include "core/page/Chrome.h" 37 #include "core/page/Chrome.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 "platform/UserGestureIndicator.h" 42 #include "platform/UserGestureIndicator.h"
42 #include "platform/network/ResourceRequest.h" 43 #include "platform/network/ResourceRequest.h"
43 #include "platform/weborigin/KURL.h" 44 #include "platform/weborigin/KURL.h"
44 #include "platform/weborigin/SecurityOrigin.h" 45 #include "platform/weborigin/SecurityOrigin.h"
45 #include "platform/weborigin/SecurityPolicy.h" 46 #include "platform/weborigin/SecurityPolicy.h"
46 #include "public/platform/WebURLRequest.h" 47 #include "public/platform/WebURLRequest.h"
47 48
48 namespace blink { 49 namespace blink {
49 50
50 static LocalFrame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame , const FrameLoadRequest& request, const WindowFeatures& features, NavigationPol icy policy, ShouldSendReferrer shouldSendReferrer, bool& created) 51 static Frame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame, con st FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy p olicy, ShouldSendReferrer shouldSendReferrer)
51 { 52 {
52 ASSERT(!features.dialog || request.frameName().isEmpty()); 53 ASSERT(!features.dialog || request.frameName().isEmpty());
53 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeAuxi liary); 54 ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeAuxi liary);
54 55
55 if (!request.frameName().isEmpty() && request.frameName() != "_blank" && pol icy == NavigationPolicyIgnore) { 56 if (!request.frameName().isEmpty() && request.frameName() != "_blank" && pol icy == NavigationPolicyIgnore) {
56 if (Frame* frame = lookupFrame.findFrameForNavigation(request.frameName( ), openerFrame)) { 57 if (Frame* frame = lookupFrame.findFrameForNavigation(request.frameName( ), openerFrame)) {
57 if (request.frameName() != "_self") { 58 if (request.frameName() != "_self") {
58 if (FrameHost* host = frame->host()) { 59 if (FrameHost* host = frame->host()) {
59 if (host == openerFrame.host()) 60 if (host == openerFrame.host())
60 frame->page()->focusController().setFocusedFrame(frame); 61 frame->page()->focusController().setFocusedFrame(frame);
61 else 62 else
62 host->chrome().focus(); 63 host->chrome().focus();
63 } 64 }
64 } 65 }
65 created = false; 66 return frame;
66 // FIXME: Make this work with RemoteFrames.
67 return frame->isLocalFrame() ? toLocalFrame(frame) : nullptr;
68 } 67 }
69 } 68 }
70 69
71 // Sandboxed frames cannot open new auxiliary browsing contexts. 70 // Sandboxed frames cannot open new auxiliary browsing contexts.
72 if (openerFrame.document()->isSandboxed(SandboxPopups)) { 71 if (openerFrame.document()->isSandboxed(SandboxPopups)) {
73 // FIXME: This message should be moved off the console once a solution t o https://bugs.webkit.org/show_bug.cgi?id=103274 exists. 72 // FIXME: This message should be moved off the console once a solution t o https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
74 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.")); 73 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."));
75 return nullptr; 74 return nullptr;
76 } 75 }
77 76
78 if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindo ws()) { 77 if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindo ws())
79 created = false; 78 return openerFrame.tree().top();
80 if (!openerFrame.tree().top()->isLocalFrame())
81 return nullptr;
82 return toLocalFrame(openerFrame.tree().top());
83 }
84 79
85 Page* oldPage = openerFrame.page(); 80 FrameHost* oldHost = openerFrame.host();
86 if (!oldPage) 81 if (!oldHost)
87 return nullptr; 82 return nullptr;
88 83
89 Page* page = oldPage->chrome().client().createWindow(&openerFrame, request, features, policy, shouldSendReferrer); 84 Page* page = oldHost->chrome().client().createWindow(&openerFrame, request, features, policy, shouldSendReferrer);
90 if (!page || !page->mainFrame()->isLocalFrame()) 85 if (!page)
91 return nullptr; 86 return nullptr;
92 FrameHost* host = &page->frameHost(); 87 FrameHost* host = &page->frameHost();
93 88
94 ASSERT(page->mainFrame()); 89 ASSERT(page->mainFrame());
95 LocalFrame& frame = *page->deprecatedLocalMainFrame(); 90 Frame& frame = *page->mainFrame();
96 91
97 if (request.frameName() != "_blank") 92 if (request.frameName() != "_blank")
98 frame.tree().setName(request.frameName()); 93 frame.tree().setName(request.frameName());
99 94
100 host->chrome().setWindowFeatures(features); 95 host->chrome().setWindowFeatures(features);
101 96
102 // 'x' and 'y' specify the location of the window, while 'width' and 'height ' 97 // 'x' and 'y' specify the location of the window, while 'width' and 'height '
103 // specify the size of the viewport. We can only resize the window, so adjus t 98 // specify the size of the viewport. We can only resize the window, so adjus t
104 // for the difference between the window size and the viewport size. 99 // for the difference between the window size and the viewport size.
105 100
106 IntRect windowRect = host->chrome().windowRect(); 101 IntRect windowRect = host->chrome().windowRect();
107 IntSize viewportSize = host->chrome().pageRect().size(); 102 IntSize viewportSize = host->chrome().pageRect().size();
108 103
109 if (features.xSet) 104 if (features.xSet)
110 windowRect.setX(features.x); 105 windowRect.setX(features.x);
111 if (features.ySet) 106 if (features.ySet)
112 windowRect.setY(features.y); 107 windowRect.setY(features.y);
113 if (features.widthSet) 108 if (features.widthSet)
114 windowRect.setWidth(features.width + (windowRect.width() - viewportSize. width())); 109 windowRect.setWidth(features.width + (windowRect.width() - viewportSize. width()));
115 if (features.heightSet) 110 if (features.heightSet)
116 windowRect.setHeight(features.height + (windowRect.height() - viewportSi ze.height())); 111 windowRect.setHeight(features.height + (windowRect.height() - viewportSi ze.height()));
117 112
118 // Ensure minimum size as well as being within valid screen area. 113 host->chrome().setWindowRect(windowRect);
119 IntRect newWindowRect = LocalDOMWindow::adjustWindowRect(frame, windowRect);
120
121 host->chrome().setWindowRect(newWindowRect);
122 host->chrome().show(policy); 114 host->chrome().show(policy);
123 115
124 frame.loader().forceSandboxFlags(openerFrame.document()->sandboxFlags()); 116 // TODO(japhet): There's currently no way to set sandbox flags on a RemoteFr ame and have it propagate
117 // to the real frame in a different process. See crbug.com/483584.
118 if (frame.isLocalFrame())
119 toLocalFrame(&frame)->loader().forceSandboxFlags(openerFrame.document()- >sandboxFlags());
125 120
126 created = true;
127 return &frame; 121 return &frame;
128 } 122 }
129 123
130 LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, 124 Frame* createWindow(const String& urlString, const AtomicString& frameName, cons t WindowFeatures& windowFeatures,
131 LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFra me) 125 LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFra me)
132 { 126 {
133 LocalFrame* activeFrame = callingWindow.frame(); 127 LocalFrame* activeFrame = callingWindow.frame();
134 ASSERT(activeFrame); 128 ASSERT(activeFrame);
135 129
136 KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString( )) : firstFrame.document()->completeURL(urlString); 130 KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString( )) : firstFrame.document()->completeURL(urlString);
137 if (!completedURL.isEmpty() && !completedURL.isValid()) { 131 if (!completedURL.isEmpty() && !completedURL.isValid()) {
138 // Don't expose client code to invalid URLs. 132 // Don't expose client code to invalid URLs.
139 callingWindow.printErrorMessage("Unable to open a window with invalid UR L '" + completedURL.string() + "'.\n"); 133 callingWindow.printErrorMessage("Unable to open a window with invalid UR L '" + completedURL.string() + "'.\n");
140 return nullptr; 134 return nullptr;
141 } 135 }
142 136
143 FrameLoadRequest frameRequest(callingWindow.document(), completedURL, frameN ame); 137 FrameLoadRequest frameRequest(callingWindow.document(), completedURL, frameN ame);
144 frameRequest.resourceRequest().setFrameType(WebURLRequest::FrameTypeAuxiliar y); 138 frameRequest.resourceRequest().setFrameType(WebURLRequest::FrameTypeAuxiliar y);
145 139
146 // Normally, FrameLoader would take care of setting the referrer for a navig ation that is 140 // Normally, FrameLoader would take care of setting the referrer for a navig ation that is
147 // triggered from javascript. However, creating a window goes through suffic ient processing 141 // triggered from javascript. However, creating a window goes through suffic ient processing
148 // that it eventually enters FrameLoader as an embedder-initiated navigation . FrameLoader 142 // that it eventually enters FrameLoader as an embedder-initiated navigation . FrameLoader
149 // assumes no responsibility for generating an embedder-initiated navigation 's referrer, 143 // assumes no responsibility for generating an embedder-initiated navigation 's referrer,
150 // so we need to ensure the proper referrer is set now. 144 // so we need to ensure the proper referrer is set now.
151 frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateRefer rer(activeFrame->document()->referrerPolicy(), completedURL, activeFrame->docume nt()->outgoingReferrer())); 145 frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateRefer rer(activeFrame->document()->referrerPolicy(), completedURL, activeFrame->docume nt()->outgoingReferrer()));
152 146
153 bool hasUserGesture = UserGestureIndicator::processingUserGesture();
dcheng 2015/05/04 17:38:11 I think this might be plumbed through into a few p
Nate Chapin 2015/05/04 18:09:13 FrameLoader::load() will call setHasUserGesture()
dcheng 2015/05/05 21:54:45 Hmm... I guess as long as it gets set on the Resou
154
155 // We pass the opener frame for the lookupFrame in case the active frame is different from 147 // 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. 148 // the opener frame, and the name references a frame relative to the opener frame.
157 bool created; 149 Frame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, wind owFeatures, NavigationPolicyIgnore, MaybeSendReferrer);
158 LocalFrame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created);
159 if (!newFrame) 150 if (!newFrame)
160 return nullptr; 151 return nullptr;
161 152
162 newFrame->loader().setOpener(&openerFrame); 153 newFrame->client()->setOpener(&openerFrame);
163 154
164 if (newFrame->localDOMWindow()->isInsecureScriptAccess(callingWindow, comple tedURL)) 155 if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedUR L))
165 return newFrame; 156 return newFrame;
166 157
167 if (created) { 158 // TODO(dcheng): Special case for window.open("about:blank") to ensure it lo ads synchronously into
168 FrameLoadRequest request(callingWindow.document(), completedURL); 159 // a new window. This is our historical behavior, and it's consistent with t he creation of
169 request.resourceRequest().setHasUserGesture(hasUserGesture); 160 // a new iframe with src="about:blank". Perhaps we could get rid of this if we started reporting
170 newFrame->loader().load(request); 161 // the initial empty document's url as about:blank? See crbug.com/471239.
171 } else if (!urlString.isEmpty()) { 162 if (newFrame->isLocalFrame() && newFrame->isMainFrame() && !toLocalFrame(new Frame)->loader().stateMachine()->committedFirstRealDocumentLoad() && (completedU RL.isEmpty() || completedURL.isAboutBlankURL()))
163 toLocalFrame(newFrame)->loader().load(FrameLoadRequest(callingWindow.doc ument(), completedURL));
164 else
172 newFrame->navigate(*callingWindow.document(), completedURL, false); 165 newFrame->navigate(*callingWindow.document(), completedURL, false);
173 }
174 return newFrame; 166 return newFrame;
175 } 167 }
176 168
177 void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerF rame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer) 169 void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerF rame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer)
178 { 170 {
179 if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document: :NoDismissal) 171 if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document: :NoDismissal)
180 return; 172 return;
181 173
182 if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPop ups)) 174 if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPop ups))
183 return; 175 return;
184 176
185 if (!LocalDOMWindow::allowPopUp(openerFrame)) 177 if (!LocalDOMWindow::allowPopUp(openerFrame))
186 return; 178 return;
187 179
188 if (policy == NavigationPolicyCurrentTab) 180 if (policy == NavigationPolicyCurrentTab)
189 policy = NavigationPolicyNewForegroundTab; 181 policy = NavigationPolicyNewForegroundTab;
190 182
191 WindowFeatures features; 183 WindowFeatures features;
192 bool created; 184 Frame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer);
193 LocalFrame* newFrame = createWindow(openerFrame, openerFrame, request, featu res, policy, shouldSendReferrer, created);
194 if (!newFrame) 185 if (!newFrame)
195 return; 186 return;
196 if (shouldSendReferrer == MaybeSendReferrer) { 187 if (shouldSendReferrer == MaybeSendReferrer)
197 newFrame->loader().setOpener(&openerFrame); 188 newFrame->client()->setOpener(&openerFrame);
198 newFrame->document()->setReferrerPolicy(openerFrame.document()->referrer Policy()); 189
199 } 190 // TODO(japhet): Form submissions on RemoteFrames don't work yet.
200 FrameLoadRequest newRequest(0, request.resourceRequest()); 191 FrameLoadRequest newRequest(0, request.resourceRequest());
201 newRequest.setFormState(request.formState()); 192 newRequest.setFormState(request.formState());
202 newFrame->loader().load(newRequest); 193 if (newFrame->isLocalFrame())
194 toLocalFrame(newFrame)->loader().load(newRequest);
203 } 195 }
204 196
205 } // namespace blink 197 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698