1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef BindingDOMWindow_h 32 #define BindingDOMWindow_h 33 34 #include "Frame.h" 35 #include "FrameLoadRequest.h" 36 #include "GenericBinding.h" 37 #include "Page.h" 38 #include "SecurityOrigin.h" 39 40 namespace WebCore { 41 42 template <class Binding> 43 class BindingDOMWindow { 44 public: 45 typedef typename Binding::Value BindingValue; 46 47 static Frame* createWindow(State<Binding>*, 48 Frame* callingFrame, 49 Frame* enteredFrame, 50 Frame* openerFrame, 51 const String& url, 52 const String& frameName, 53 const WindowFeatures& windowFeatures, 54 BindingValue dialogArgs); 55 }; 56 57 // Implementations of templated methods must be in this file. 58 59 template <class Binding> 60 Frame* BindingDOMWindow<Binding>::createWindow(State<Binding>* state, 61 Frame* callingFrame, 62 Frame* enteredFrame, 63 Frame* openerFrame, 64 const String& url, 65 const String& frameName, 66 const WindowFeatures& windowFeatures, 67 BindingValue dialogArgs) 68 { 69 ASSERT(callingFrame); 70 ASSERT(enteredFrame); 71 72 if (Document* callingDocument = callingFrame->document()) { 73 // Sandboxed iframes cannot open new auxiliary browsing contexts. 74 if (callingDocument->securityOrigin()->isSandboxed(SandboxNavigation)) 75 return 0; 76 } 77 78 ResourceRequest request; 79 80 // For whatever reason, Firefox uses the entered frame to determine 81 // the outgoingReferrer. We replicate that behavior here. 82 String referrer = enteredFrame->loader()->outgoingReferrer(); 83 request.setHTTPReferrer(referrer); 84 FrameLoader::addHTTPOriginIfNeeded(request, enteredFrame->loader()->outgoingOrigin()); 85 FrameLoadRequest frameRequest(request, frameName); 86 87 // FIXME: It's much better for client API if a new window starts with a URL, 88 // here where we know what URL we are going to open. Unfortunately, this 89 // code passes the empty string for the URL, but there's a reason for that. 90 // Before loading we have to set up the opener, openedByDOM, 91 // and dialogArguments values. Also, to decide whether to use the URL 92 // we currently do an allowsAccessFrom call using the window we create, 93 // which can't be done before creating it. We'd have to resolve all those 94 // issues to pass the URL instead of "". 95 96 bool created; 97 // We pass in the opener frame here so it can be used for looking up the 98 // frame name, in case the active frame is different from the opener frame, 99 // and the name references a frame relative to the opener frame, for example 100 // "_self" or "_parent". 101 Frame* newFrame = callingFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); 102 if (!newFrame) 103 return 0; 104 105 newFrame->loader()->setOpener(openerFrame); 106 newFrame->page()->setOpenedByDOM(); 107 108 Binding::DOMWindow::storeDialogArgs(state, newFrame, dialogArgs); 109 110 if (!protocolIsJavaScript(url) || BindingSecurity<Binding>::canAccessFrame(state, newFrame, true)) { 111 KURL completedUrl = 112 url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(url); 113 bool userGesture = processingUserGesture(); 114 115 if (created) 116 newFrame->loader()->changeLocation(completedUrl, referrer, false, false, userGesture); 117 else if (!url.isEmpty()) 118 newFrame->redirectScheduler()->scheduleLocationChange(completedUrl.string(), referrer, false, userGesture); 119 } 120 121 return newFrame; 122 } 123 124 } // namespace WebCore 125 126 #endif // BindingDOMWindow_h 127