NPObject* ScriptController::windowScriptNPObject() { if (!m_windowScriptNPObject) { JSLockHolder lock(JSDOMWindowBase::commonVM()); if (canExecuteScripts(NotAboutToExecuteScript)) { // JavaScript is enabled, so there is a JavaScript window object. // Return an NPObject bound to the window object. JSDOMWindow* win = windowShell(pluginWorld())->window(); ASSERT(win); Bindings::RootObject* root = bindingRootObject(); m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root); } else { // JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object. // Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object. m_windowScriptNPObject = _NPN_CreateNoScriptObject(); } } return m_windowScriptNPObject; }
NPObject* ScriptController::windowScriptNPObject() { if (!m_windowScriptNPObject) { if (isEnabled()) { // JavaScript is enabled, so there is a JavaScript window object. // Return an NPObject bound to the window object. JSC::JSLock lock(false); JSObject* win = windowShell()->window(); ASSERT(win); Bindings::RootObject* root = bindingRootObject(); m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root); } else { // JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object. // Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object. m_windowScriptNPObject = _NPN_CreateNoScriptObject(); } } return m_windowScriptNPObject; }
bool ScriptController::executeIfJavaScriptURL(const URL& url, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL) { if (!protocolIsJavaScript(url)) return false; if (!m_frame.page() || !m_frame.document()->contentSecurityPolicy()->allowJavaScriptURLs(m_frame.document()->url(), eventHandlerPosition().m_line)) return true; // We need to hold onto the Frame here because executing script can // destroy the frame. Ref<Frame> protector(m_frame); RefPtr<Document> ownerDocument(m_frame.document()); const int javascriptSchemeLength = sizeof("javascript:") - 1; String decodedURL = decodeURLEscapeSequences(url.string()); auto result = executeScript(decodedURL.substring(javascriptSchemeLength)); // If executing script caused this frame to be removed from the page, we // don't want to try to replace its document! if (!m_frame.page()) return true; String scriptResult; if (!result || !result.getString(windowShell(mainThreadNormalWorld())->window()->globalExec(), scriptResult)) return true; // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: // http://bugs.webkit.org/show_bug.cgi?id=16782 if (shouldReplaceDocumentIfJavaScriptURL == ReplaceDocumentIfJavaScriptURL) { // We're still in a frame, so there should be a DocumentLoader. ASSERT(m_frame.document()->loader()); // DocumentWriter::replaceDocument can cause the DocumentLoader to get deref'ed and possible destroyed, // so protect it with a RefPtr. if (RefPtr<DocumentLoader> loader = m_frame.document()->loader()) loader->writer().replaceDocument(scriptResult, ownerDocument.get()); } return true; }
ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld* world) { const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); String sourceURL = ustringToString(jsSourceCode.provider()->url()); // evaluate code. Returns the JS return value or 0 // if there was none, an error occurred or the type couldn't be converted. // inlineCode is true for <a href="javascript:doSomething()"> // and false for <script>doSomething()</script>. Check if it has the // expected value in all cases. // See smart window.open policy for where this is used. JSDOMWindowShell* shell = windowShell(world); ExecState* exec = shell->window()->globalExec(); const String* savedSourceURL = m_sourceURL; m_sourceURL = &sourceURL; JSLock lock(SilenceAssertionsOnly); RefPtr<Frame> protect = m_frame; InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, sourceURL, sourceCode.startLine()); JSValue evaluationException; exec->globalData().timeoutChecker.start(); JSValue returnValue = JSMainThreadExecState::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, shell, &evaluationException); exec->globalData().timeoutChecker.stop(); InspectorInstrumentation::didEvaluateScript(cookie); if (evaluationException) { reportException(exec, evaluationException); m_sourceURL = savedSourceURL; return ScriptValue(); } m_sourceURL = savedSourceURL; return ScriptValue(exec->globalData(), returnValue); }
Deprecated::ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld& world) { const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); String sourceURL = jsSourceCode.provider()->url(); // evaluate code. Returns the JS return value or 0 // if there was none, an error occurred or the type couldn't be converted. // inlineCode is true for <a href="javascript:doSomething()"> // and false for <script>doSomething()</script>. Check if it has the // expected value in all cases. // See smart window.open policy for where this is used. JSDOMWindowShell* shell = windowShell(world); ExecState* exec = shell->window()->globalExec(); const String* savedSourceURL = m_sourceURL; m_sourceURL = &sourceURL; JSLockHolder lock(exec); Ref<Frame> protect(m_frame); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(&m_frame, sourceURL, sourceCode.startLine()); JSValue evaluationException; JSValue returnValue = JSMainThreadExecState::evaluate(exec, jsSourceCode, shell, &evaluationException); InspectorInstrumentation::didEvaluateScript(cookie, &m_frame); if (evaluationException) { reportException(exec, evaluationException, sourceCode.cachedScript()); m_sourceURL = savedSourceURL; return Deprecated::ScriptValue(); } m_sourceURL = savedSourceURL; return Deprecated::ScriptValue(exec->vm(), returnValue); }
bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument) { if (!protocolIsJavaScript(url)) return false; if (m_frame->page() && !m_frame->page()->javaScriptURLsAreAllowed()) return true; if (m_frame->inViewSourceMode()) return true; const int javascriptSchemeLength = sizeof("javascript:") - 1; String script = decodeURLEscapeSequences(url.string().substring(javascriptSchemeLength)); ScriptValue result; if (xssAuditor()->canEvaluateJavaScriptURL(script)) result = executeScript(script, userGesture); String scriptResult; #if USE(JSC) JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); JSC::ExecState* exec = shell->window()->globalExec(); if (!result.getString(exec, scriptResult)) return true; #else if (!result.getString(scriptResult)) return true; #endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: // http://bugs.webkit.org/show_bug.cgi?id=16782 if (replaceDocument) m_frame->loader()->replaceDocument(scriptResult); return true; }
bool ScriptController::initializeMainWorld() { if (m_windowShell->isContextInitialized()) return false; return windowShell(DOMWrapperWorld::mainWorld())->isContextInitialized(); }
v8::Local<v8::Context> V8Proxy::mainWorldContext() { windowShell()->initContextIfNeeded(); return v8::Local<v8::Context>::New(windowShell()->context()); }
void V8Proxy::clearForNavigation() { resetIsolatedWorlds(); windowShell()->clearForNavigation(); }
void V8Proxy::clearForClose() { resetIsolatedWorlds(); windowShell()->clearForClose(); }
V8Proxy::~V8Proxy() { clearForClose(); windowShell()->destroyGlobal(); }
ScriptController::~ScriptController() { windowShell()->destroyGlobal(); clearForClose(); }
void ScriptController::disableEval() { windowShell(mainThreadNormalWorld())->window()->setEvalEnabled(false); }
void ScriptController::clearForNavigation() { resetIsolatedWorlds(); V8GCController::hintForCollectGarbage(); windowShell()->clearForNavigation(); }
bool ScriptController::haveInterpreter() const { return windowShell()->isContextInitialized(); }
v8::Local<v8::Context> ScriptController::mainWorldContext() { windowShell()->initializeIfNeeded(); return v8::Local<v8::Context>::New(windowShell()->context()); }
void ScriptController::updateSecurityOrigin() { windowShell()->updateSecurityOrigin(); }
bool ScriptController::initializeMainWorld() { if (m_windowShell->isContextInitialized()) return false; return windowShell(mainThreadNormalWorld())->isContextInitialized(); }
void V8Proxy::clearForNavigation() { resetIsolatedWorlds(); hintForGCIfNecessary(); windowShell()->clearForNavigation(); }