inline void DialogHandler::dialogCreated(DOMWindow* dialog) { m_frame = dialog->frame(); // FIXME: This looks like a leak between the normal world and an isolated // world if dialogArguments comes from an isolated world. JSDOMWindow* globalObject = toJSDOMWindow(m_frame.get(), normalWorld(m_exec->globalData())); if (JSValue dialogArguments = m_exec->argument(1)) globalObject->putDirect(m_exec->globalData(), Identifier(m_exec, "dialogArguments"), dialogArguments); }
// Helper for window.open() and window.showModalDialog() static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicFrame, Frame* openerFrame, const String& url, const String& frameName, const WindowFeatures& windowFeatures, JSValue dialogArgs) { ASSERT(lexicalFrame); ASSERT(dynamicFrame); ResourceRequest request; // For whatever reason, Firefox uses the dynamicGlobalObject to determine // the outgoingReferrer. We replicate that behavior here. String referrer = dynamicFrame->loader()->outgoingReferrer(); request.setHTTPReferrer(referrer); FrameLoader::addHTTPOriginIfNeeded(request, dynamicFrame->loader()->outgoingOrigin()); FrameLoadRequest frameRequest(request, frameName); // FIXME: It's much better for client API if a new window starts with a URL, here where we // know what URL we are going to open. Unfortunately, this code passes the empty string // for the URL, but there's a reason for that. Before loading we have to set up the opener, // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently // do an allowsAccessFrom call using the window we create, which can't be done before creating it. // We'd have to resolve all those issues to pass the URL instead of "". bool created; // We pass the opener frame for the lookupFrame in case the active frame is different from // the opener frame, and the name references a frame relative to the opener frame. Frame* newFrame = createWindow(lexicalFrame, openerFrame, frameRequest, windowFeatures, created); if (!newFrame) return 0; newFrame->loader()->setOpener(openerFrame); newFrame->page()->setOpenedByDOM(); // FIXME: If a window is created from an isolated world, what are the consequences of this? 'dialogArguments' only appears back in the normal world? JSDOMWindow* newWindow = toJSDOMWindow(newFrame, normalWorld(exec->globalData())); if (dialogArgs) newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs); if (!protocolIsJavaScript(url) || newWindow->allowsAccessFrom(exec)) { KURL completedURL = url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(exec, url); bool userGesture = processingUserGesture(); if (created) newFrame->loader()->changeLocation(completedURL, referrer, false, false, userGesture); else if (!url.isEmpty()) newFrame->redirectScheduler()->scheduleLocationChange(completedURL.string(), referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } return newFrame; }
static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& url, const String& frameName, const WindowFeatures& windowFeatures, JSValuePtr dialogArgs) { Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); ASSERT(activeFrame); ResourceRequest request; request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer()); FrameLoader::addHTTPOriginIfNeeded(request, activeFrame->loader()->outgoingOrigin()); FrameLoadRequest frameRequest(request, frameName); // FIXME: It's much better for client API if a new window starts with a URL, here where we // know what URL we are going to open. Unfortunately, this code passes the empty string // for the URL, but there's a reason for that. Before loading we have to set up the opener, // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently // do an allowsAccessFrom call using the window we create, which can't be done before creating it. // We'd have to resolve all those issues to pass the URL instead of "". bool created; // We pass in the opener frame here so it can be used for looking up the frame name, in case the active frame // is different from the opener frame, and the name references a frame relative to the opener frame, for example // "_self" or "_parent". Frame* newFrame = activeFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); if (!newFrame) return 0; newFrame->loader()->setOpener(openerFrame); newFrame->loader()->setOpenedByDOM(); JSDOMWindow* newWindow = toJSDOMWindow(newFrame); if (dialogArgs) newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs); if (!protocolIs(url, "javascript") || newWindow->allowsAccessFrom(exec)) { KURL completedURL = url.isEmpty() ? KURL("") : activeFrame->document()->completeURL(url); bool userGesture = activeFrame->script()->processingUserGesture(); if (created) newFrame->loader()->changeLocation(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture); else if (!url.isEmpty()) newFrame->loader()->scheduleLocationChange(completedURL.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture); } return newFrame; }