PassRefPtr<JSLazyEventListener> JSLazyEventListener::createForDOMWindow(Frame& frame, const QualifiedName& attributeName, const AtomicString& attributeValue) { if (attributeValue.isNull()) return nullptr; if (!frame.script().canExecuteScripts(AboutToExecuteScript)) return nullptr; return adoptRef(new JSLazyEventListener(attributeName.localName().string(), eventParameterName(frame.document()->isSVGDocument()), attributeValue, nullptr, frame.document()->url().string(), frame.script().eventHandlerPosition(), toJSDOMWindow(&frame, mainThreadNormalWorld()), mainThreadNormalWorld())); }
JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext* scriptExecutionContext) { if (scriptExecutionContext->isDocument()) return toJSDOMWindow(static_cast<Document*>(scriptExecutionContext)->frame()); #if ENABLE(WORKERS) if (scriptExecutionContext->isWorkerContext()) return static_cast<WorkerContext*>(scriptExecutionContext)->script()->workerContextWrapper(); #endif ASSERT_NOT_REACHED(); return 0; }
void JSXMLHttpRequestUpload::setOnabort(ExecState* exec, JSValue* value) { XMLHttpRequest* xmlHttpRequest = impl()->associatedXMLHttpRequest(); if (!xmlHttpRequest) return; Document* document = xmlHttpRequest->document(); if (!document) return; Frame* frame = document->frame(); if (!frame) return; impl()->setOnAbortListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true)); }
// 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; }
JSValue* JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& args) { // Arguments: PositionCallback, (optional)PositionErrorCallback, (optional)PositionOptions RefPtr<PositionCallback> positionCallback; JSObject* object = args.at(exec, 0)->getObject(); if (exec->hadException()) return jsUndefined(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } if (Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame()) positionCallback = JSCustomPositionCallback::create(object, frame); RefPtr<PositionErrorCallback> positionErrorCallback; if (!args.at(exec, 1)->isUndefinedOrNull()) { JSObject* object = args.at(exec, 1)->getObject(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } if (Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame()) positionErrorCallback = JSCustomPositionErrorCallback::create(object, frame); } RefPtr<PositionOptions> positionOptions; if (!args.at(exec, 2)->isUndefinedOrNull()) { positionOptions = createPositionOptions(exec, args.at(exec, 2)); if (exec->hadException()) return jsUndefined(); } m_impl->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.get()); return jsUndefined(); }
JSValue* JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList& args) { Document* document = impl()->document(); if (!document) return jsUndefined(); Frame* frame = document->frame(); if (!frame) return jsUndefined(); JSUnprotectedEventListener* listener = toJSDOMWindow(frame)->findJSUnprotectedEventListener(exec, args.at(exec, 1), true); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0)->toString(exec), listener, args.at(exec, 2)->toBoolean(exec)); return jsUndefined(); }
void InjectedBundle::reportException(JSContextRef context, JSValueRef exception) { if (!context || !exception) return; JSLock lock(JSC::SilenceAssertionsOnly); JSC::ExecState* execState = toJS(context); // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a Page. if (!toJSDOMWindow(execState->lexicalGlobalObject())) return; WebCore::reportException(execState, toJS(execState, exception)); }
void ScheduledAction::execute(Document* document) { JSDOMWindow* window = toJSDOMWindow(document->frame(), m_isolatedWorld.get()); if (!window) return; RefPtr<Frame> frame = window->impl()->frame(); if (!frame || !frame->script()->canExecuteScripts(AboutToExecuteScript)) return; if (m_function) executeFunctionInContext(window, window->shell(), document); else frame->script()->executeScriptInWorld(m_isolatedWorld.get(), m_code); }
JSValue* jsEventTargetRemoveEventListener(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args) { Node* eventNode = 0; EventTarget* eventTarget = 0; if (!retrieveEventTargetAndCorrespondingNode(exec, thisValue, eventNode, eventTarget)) return throwError(exec, TypeError); Frame* frame = eventNode->document()->frame(); if (!frame) return jsUndefined(); if (JSEventListener* listener = toJSDOMWindow(frame)->findJSEventListener(args.at(exec, 1))) eventTarget->removeEventListener(args.at(exec, 0)->toString(exec), listener, args.at(exec, 2)->toBoolean(exec)); return jsUndefined(); }
JSValue JSLocation::reload(ExecState* exec, const ArgList&) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); JSDOMWindow* window = toJSDOMWindow(frame); if (!window->allowsAccessFrom(exec)) return jsUndefined(); if (!frame->loader()->url().protocolIs("javascript") || (window && window->allowsAccessFrom(exec))) { bool userGesture = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame()->script()->processingUserGesture(); frame->loader()->scheduleRefresh(userGesture); } return jsUndefined(); }
void InspectorProfilerAgent::stopUserInitiatedProfiling() { m_recordingUserInitiatedProfile = false; String title = getCurrentUserInitiatedProfileName(); #if USE(JSC) JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); #else // Use null script state to avoid filtering by context security token. // All functions from all iframes should be visible from Inspector UI. ScriptState* scriptState = 0; #endif RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title); if (profile) addProfile(profile, 0, String()); toggleRecordButton(false); }
JSValue* jsEventTargetAddEventListener(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args) { Node* eventNode = 0; EventTarget* eventTarget = 0; if (!retrieveEventTargetAndCorrespondingNode(exec, thisValue, eventNode, eventTarget)) return throwError(exec, TypeError); Frame* frame = eventNode->document()->frame(); if (!frame) return jsUndefined(); if (RefPtr<JSEventListener> listener = toJSDOMWindow(frame)->findOrCreateJSEventListener(exec, args[1])) eventTarget->addEventListener(args[0]->toString(exec), listener.release(), args[2]->toBoolean(exec)); return jsUndefined(); }
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; }
void InspectorProfilerAgent::startUserInitiatedProfiling() { if (!enabled()) { enable(false); ScriptDebugServer::shared().recompileAllJSFunctions(); } m_recordingUserInitiatedProfile = true; String title = getCurrentUserInitiatedProfileName(true); #if USE(JSC) JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); #else ScriptState* scriptState = 0; #endif ScriptProfiler::start(scriptState, title); addStartProfilingMessageToConsole(title, 0, String()); toggleRecordButton(true); }
JSValue* JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& args) { XMLHttpRequest* xmlHttpRequest = impl()->associatedXMLHttpRequest(); if (!xmlHttpRequest) return jsUndefined(); Document* document = xmlHttpRequest->document(); if (!document) return jsUndefined(); Frame* frame = document->frame(); if (!frame) return jsUndefined(); RefPtr<JSUnprotectedEventListener> listener = toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1), true); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0)->toString(exec), listener.release(), args.at(exec, 2)->toBoolean(exec)); return jsUndefined(); }
void ScheduledAction::execute(Document* document) { JSDOMWindow* window = toJSDOMWindow(document->frame()); if (!window) return; RefPtr<Frame> frame = window->impl()->frame(); if (!frame || !frame->script()->isEnabled()) return; frame->script()->setProcessingTimerCallback(true); if (m_function) { executeFunctionInContext(window, window->shell()); Document::updateStyleForAllDocuments(); } else frame->loader()->executeScript(m_code); frame->script()->setProcessingTimerCallback(false); }
void PagePopupBlackBerry::installDOMFunction(Frame* frame) { JSDOMWindow* window = toJSDOMWindow(frame, mainThreadNormalWorld()); ASSERT(window); JSC::ExecState* exec = window->globalExec(); ASSERT(exec); JSC::JSLockHolder lock(exec); JSContextRef context = ::toRef(exec); JSObjectRef globalObject = JSContextGetGlobalObject(context); JSStringRef functionName = JSStringCreateWithUTF8CString( "setValueAndClosePopup"); JSObjectRef function = JSObjectMakeFunctionWithCallback(context, functionName, setValueAndClosePopupCallback); JSObjectSetProperty(context, globalObject, functionName, function, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); // Register client into DOM JSClassDefinition definition = kJSClassDefinitionEmpty; definition.staticValues = popUpExtensionStaticValues; definition.staticFunctions = popUpExtensionStaticFunctions; definition.initialize = popUpExtensionInitialize; definition.finalize = popUpExtensionFinalize; JSClassRef clientClass = JSClassCreate(&definition); JSObjectRef clientClassObject = JSObjectMake(context, clientClass, 0); // Add a reference. See popUpExtensionFinalize. m_sharedClientPointer->ref(); JSObjectSetPrivate(clientClassObject, m_sharedClientPointer.get()); String name("popUp"); JSC::PutPropertySlot slot; window->put(window, exec, JSC::Identifier(exec, name), toJS(clientClassObject), slot); JSClassRelease(clientClass); }
void JavaScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused) { ASSERT_ARG(frame, frame); if (!frame->script()->isEnabled()) return; frame->script()->setPaused(paused); if (JSDOMWindow* window = toJSDOMWindow(frame)) { if (paused) { OwnPtr<PausedTimeouts> timeouts; window->pauseTimeouts(timeouts); m_pausedTimeouts.set(frame, timeouts.release()); } else { OwnPtr<PausedTimeouts> timeouts(m_pausedTimeouts.take(frame)); window->resumeTimeouts(timeouts); } } setJavaScriptPaused(frame->view(), paused); }
JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Document* document) { if (!document) return jsNull(); JSDOMWrapper* wrapper = getCachedWrapper(currentWorld(exec), document); if (wrapper) return wrapper; if (DOMWindow* domWindow = document->domWindow()) { globalObject = toJSDOMWindow(toJS(exec, domWindow)); // Creating a wrapper for domWindow might have created a wrapper for document as well. wrapper = getCachedWrapper(currentWorld(exec), document); if (wrapper) return wrapper; } if (document->isHTMLDocument()) wrapper = CREATE_DOM_WRAPPER(exec, globalObject, HTMLDocument, document); #if ENABLE(SVG) else if (document->isSVGDocument()) wrapper = CREATE_DOM_WRAPPER(exec, globalObject, SVGDocument, document); #endif else wrapper = CREATE_DOM_WRAPPER(exec, globalObject, Document, document); // Make sure the document is kept around by the window object, and works right with the // back/forward cache. if (!document->frame()) { size_t nodeCount = 0; for (Node* n = document; n; n = NodeTraversal::next(n)) nodeCount++; exec->heap()->reportExtraMemoryCost(nodeCount * sizeof(Node)); } return wrapper; }
void InspectorProfilerAgent::stopUserInitiatedProfiling(bool ignoreProfile) { if (!m_recordingUserInitiatedProfile) return; m_recordingUserInitiatedProfile = false; String title = getCurrentUserInitiatedProfileName(); #if USE(JSC) JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec(); #else // Use null script state to avoid filtering by context security token. // All functions from all iframes should be visible from Inspector UI. ScriptState* scriptState = 0; #endif RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title); if (profile) { if (!ignoreProfile) addProfile(profile, 0, String()); else addProfileFinishedMessageToConsole(profile, 0, String()); } toggleRecordButton(false); m_inspectorState->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); }
static inline PassRefPtr<JSC::Profile> stopProfiling(Frame* frame, const String& title) { return stopProfiling(toJSDOMWindow(frame, debuggerWorld())->globalExec(), title); }
static inline void startProfiling(Frame* frame, const String& title, RefPtr<Stopwatch>&& stopwatch) { startProfiling(toJSDOMWindow(frame, debuggerWorld())->globalExec(), title, WTF::move(stopwatch)); }
JSDOMGlobalObject* toJSDOMGlobalObject(Document* document, DOMWrapperWorld& world) { return toJSDOMWindow(document->frame(), world); }
JSDOMGlobalObject* toJSDOMGlobalObject(Document* document, JSC::ExecState* exec) { return toJSDOMWindow(document->frame(), currentWorld(exec)); }
static inline void startProfiling(Frame* frame, const String& title) { JSC::LegacyProfiler::profiler()->startProfiling(toJSDOMWindow(frame, debuggerWorld())->globalExec(), title); }
static JSValuePtr showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValuePtr dialogArgs, const String& featureArgs) { if (!canShowModalDialogNow(frame) || !allowPopUp(exec)) return jsUndefined(); const HashMap<String, String> features = parseModalDialogFeatures(featureArgs); const bool trusted = false; // The following features from Microsoft's documentation are not implemented: // - default font settings // - width, height, left, and top specified in units other than "px" // - edge (sunken or raised, default is raised) // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) // - unadorned: trusted && boolFeature(features, "unadorned"); if (!frame) return jsUndefined(); FloatRect screenRect = screenAvailableRect(frame->view()); WindowFeatures wargs; wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE wargs.widthSet = true; wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE wargs.heightSet = true; wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); wargs.xSet = wargs.x > 0; wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); wargs.ySet = wargs.y > 0; if (WindowFeatures::boolFeature(features, "center", true)) { if (!wargs.xSet) { wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; wargs.xSet = true; } if (!wargs.ySet) { wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; wargs.ySet = true; } } wargs.dialog = true; wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true); wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted); wargs.menuBarVisible = false; wargs.toolBarVisible = false; wargs.locationBarVisible = false; wargs.fullscreen = false; Frame* dialogFrame = createWindow(exec, frame, url, "", wargs, dialogArgs); if (!dialogFrame) return jsUndefined(); JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame); // Get the return value either just before clearing the dialog window's // properties (in JSDOMWindowBase::clear), or when on return from runModal. JSValuePtr returnValue = noValue(); dialogWindow->setReturnValueSlot(&returnValue); dialogFrame->page()->chrome()->runModal(); dialogWindow->setReturnValueSlot(0); // If we don't have a return value, get it now. // Either JSDOMWindowBase::clear was not called yet, or there was no return value, // and in that case, there's no harm in trying again (no benefit either). if (!returnValue) returnValue = dialogWindow->getDirect(Identifier(exec, "returnValue")); return returnValue ? returnValue : jsUndefined(); }
void ScriptProfiler::startForPage(Page* inspectedPage, const String& title) { JSC::ExecState* scriptState = toJSDOMWindow(inspectedPage->mainFrame(), debuggerWorld())->globalExec(); start(scriptState, title); }
PassRefPtr<ScriptProfile> ScriptProfiler::stopForPage(Page* inspectedPage, const String& title) { JSC::ExecState* scriptState = toJSDOMWindow(inspectedPage->mainFrame(), debuggerWorld())->globalExec(); return stop(scriptState, title); }
JSValue JSDOMWindow::open(ExecState* exec) { String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)); AtomicString frameName = exec->argument(1).isUndefinedOrNull() ? "_blank" : ustringToAtomicString(exec->argument(1).toString(exec)); WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2))); Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); Frame* lexicalFrame = toLexicalFrame(exec); if (!lexicalFrame) return jsUndefined(); Frame* dynamicFrame = toDynamicFrame(exec); if (!dynamicFrame) return jsUndefined(); Page* page = frame->page(); // Because FrameTree::find() returns true for empty strings, we must check for empty framenames. // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker. if (!domWindowAllowPopUp(dynamicFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName))) return jsUndefined(); // Get the target frame for the special cases of _top and _parent. In those // cases, we can schedule a location change right now and return early. bool topOrParent = false; if (frameName == "_top") { frame = frame->tree()->top(); topOrParent = true; } else if (frameName == "_parent") { if (Frame* parent = frame->tree()->parent()) frame = parent; topOrParent = true; } if (topOrParent) { String completedURL; if (!urlString.isEmpty()) completedURL = completeURL(exec, urlString).string(); if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); const JSDOMWindow* targetedWindow = toJSDOMWindow(frame, currentWorld(exec)); if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { bool userGesture = processingUserGesture(); // For whatever reason, Firefox uses the dynamicGlobalObject to // determine the outgoingReferrer. We replicate that behavior // here. String referrer = dynamicFrame->loader()->outgoingReferrer(); frame->redirectScheduler()->scheduleLocationChange(completedURL, referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } return toJS(exec, frame->domWindow()); } // In the case of a named frame or a new window, we'll use the createWindow() helper FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0, windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0); DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect); windowFeatures.x = windowRect.x(); windowFeatures.y = windowRect.y(); windowFeatures.height = windowRect.height(); windowFeatures.width = windowRect.width(); frame = createWindow(exec, lexicalFrame, dynamicFrame, frame, urlString, frameName, windowFeatures, JSValue()); if (!frame) return jsUndefined(); return toJS(exec, frame->domWindow()); }
JSValue JSDOMWindow::showModalDialog(ExecState* exec) { String url = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)); JSValue dialogArgs = exec->argument(1); String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2)); Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); Frame* lexicalFrame = toLexicalFrame(exec); if (!lexicalFrame) return jsUndefined(); Frame* dynamicFrame = toDynamicFrame(exec); if (!dynamicFrame) return jsUndefined(); if (!DOMWindow::canShowModalDialogNow(frame) || !domWindowAllowPopUp(dynamicFrame)) return jsUndefined(); HashMap<String, String> features; DOMWindow::parseModalDialogFeatures(featureArgs, features); const bool trusted = false; // The following features from Microsoft's documentation are not implemented: // - default font settings // - width, height, left, and top specified in units other than "px" // - edge (sunken or raised, default is raised) // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) // - unadorned: trusted && boolFeature(features, "unadorned"); FloatRect screenRect = screenAvailableRect(frame->view()); WindowFeatures wargs; wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE wargs.widthSet = true; wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE wargs.heightSet = true; wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); wargs.xSet = wargs.x > 0; wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); wargs.ySet = wargs.y > 0; if (WindowFeatures::boolFeature(features, "center", true)) { if (!wargs.xSet) { wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; wargs.xSet = true; } if (!wargs.ySet) { wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; wargs.ySet = true; } } wargs.dialog = true; wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true); wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted); wargs.menuBarVisible = false; wargs.toolBarVisible = false; wargs.locationBarVisible = false; wargs.fullscreen = false; Frame* dialogFrame = createWindow(exec, lexicalFrame, dynamicFrame, frame, url, "", wargs, dialogArgs); if (!dialogFrame) return jsUndefined(); JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame, currentWorld(exec)); dialogFrame->page()->chrome()->runModal(); Identifier returnValue(exec, "returnValue"); if (dialogWindow->allowsAccessFromNoErrorMessage(exec)) { PropertySlot slot; // This is safe, we have already performed the origin security check and we are // not interested in any of the DOM properties of the window. if (dialogWindow->JSGlobalObject::getOwnPropertySlot(exec, returnValue, slot)) return slot.getValue(exec, returnValue); } return jsUndefined(); }