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 10 matching lines...) Expand all Loading... | |
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(frame.widget(), 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 // FIXME: There's currently no way to set sandbox flags on a RemoteFrame and have it propagate |
117 // to the real frame in a different process. | |
dcheng
2015/04/29 21:37:47
The new style is TODO(foo). Maybe file a bug? alex
Nate Chapin
2015/05/01 20:30:53
Done.
| |
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(); | |
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 // FIXME: Special case for window.open("about:blank") to ensure it loads syn chronously 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? |
dcheng
2015/04/29 21:37:46
TODO(dcheng): for this one, and point to https://c
Nate Chapin
2015/05/01 20:30:53
Done.
| |
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 // FIXME: Form submissions on RemoteFrames don't work yet. |
dcheng
2015/04/29 21:37:46
Oh dear...
Nate Chapin
2015/05/01 20:30:53
Oh dear? TODO'd.
| |
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 |
OLD | NEW |