short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const { ASSERT(v8::Context::InContext()); if (!m_filter->IsFunction()) return NodeFilter::FILTER_ACCEPT; v8::TryCatch exceptionCatcher; v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global(); v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(m_filter); OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]); args[0] = toV8(node); V8Proxy* proxy = V8Proxy::retrieve(); ASSERT(proxy); v8::Handle<v8::Value> result = proxy->callFunction(callback, object, 1, args.get()); if (exceptionCatcher.HasCaught()) { state->setException(exceptionCatcher.Exception()); return NodeFilter::FILTER_REJECT; } ASSERT(!result.IsEmpty()); return result->Int32Value(); }
bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPString* npScript, NPVariant* result) { VOID_TO_NPVARIANT(*result); if (!npObject) return false; if (npObject->_class != npScriptObjectClass) return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); if (context.IsEmpty()) return false; V8Proxy* proxy = toV8Proxy(npObject); ASSERT(proxy); v8::Context::Scope scope(context); WebCore::String filename; if (!popupsAllowed) filename = "npscript"; WebCore::String script = WebCore::String::fromUTF8(npScript->UTF8Characters, npScript->UTF8Length); v8::Local<v8::Value> v8result = proxy->evaluate(WebCore::ScriptSourceCode(script, WebCore::KURL(WebCore::ParsedURLString, filename)), 0); if (v8result.IsEmpty()) return false; convertV8ObjectToNPVariant(v8result, npObject, result); return true; }
void V8CustomPositionErrorCallback::handleEvent(PositionError* error) { v8::HandleScope handleScope; // ActiveDOMObject will null our pointer to the ScriptExecutionContext when it goes away. ScriptExecutionContext* scriptContext = scriptExecutionContext(); if (!scriptContext) return; // The lookup of the proxy will fail if the Frame has been detached. V8Proxy* proxy = V8Proxy::retrieve(scriptContext); if (!proxy) return; v8::Handle<v8::Context> context = proxy->context(); if (context.IsEmpty()) return; v8::Context::Scope scope(context); v8::Handle<v8::Value> argv[] = { toV8(error) }; // Protect the script context until the callback returns. RefPtr<ScriptExecutionContext> protector(scriptContext); bool callbackReturnValue = false; invokeCallback(m_callback, 1, argv, callbackReturnValue, scriptContext); }
bool V8Proxy::handleOutOfMemory() { v8::Local<v8::Context> context = v8::Context::GetCurrent(); if (!context->HasOutOfMemoryException()) return false; // Warning, error, disable JS for this frame? Frame* frame = V8Proxy::retrieveFrame(context); V8Proxy* proxy = V8Proxy::retrieve(frame); if (proxy) { // Clean m_context, and event handlers. proxy->clearForClose(); proxy->windowShell()->destroyGlobal(); } #if PLATFORM(CHROMIUM) PlatformBridge::notifyJSOutOfMemory(frame); #endif // Disable JS. Settings* settings = frame->settings(); ASSERT(settings); settings->setJavaScriptEnabled(false); return true; }
String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) { v8::Handle<v8::Function> lookupNamespaceURIFunc; v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI"); // Check if the resolver has a function property named lookupNamespaceURI. if (m_resolver->Has(lookupNamespaceURIName)) { v8::Handle<v8::Value> lookupNamespaceURI = m_resolver->Get(lookupNamespaceURIName); if (lookupNamespaceURI->IsFunction()) lookupNamespaceURIFunc = v8::Handle<v8::Function>::Cast(lookupNamespaceURI); } if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) { Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String()); return String(); } // Catch exceptions from calling the namespace resolver. v8::TryCatch try_catch; try_catch.SetVerbose(true); // Print exceptions to console. const int argc = 1; v8::Handle<v8::Value> argv[argc] = { v8String(prefix) }; v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc; V8Proxy* proxy = V8Proxy::retrieve(); v8::Handle<v8::Value> retval = proxy->callFunction(function, m_resolver, argc, argv); // Eat exceptions from namespace resolver and return an empty string. This will most likely cause NAMESPACE_ERR. if (try_catch.HasCaught()) return String(); return toWebCoreStringWithNullCheck(retval); }
bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue) { // FIXME: If an exception was thrown by the callback, we should report it v8::TryCatch exceptionCatcher; v8::Local<v8::Function> callbackFunction; if (callback->IsFunction()) { callbackFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(callback)); } else if (callback->IsObject()) { v8::Local<v8::Value> handleEventFunction = callback->Get(v8::String::NewSymbol("handleEvent")); if (handleEventFunction->IsFunction()) { callbackFunction = v8::Local<v8::Function>::Cast(handleEventFunction); } } else return false; if (callbackFunction.IsEmpty()) return false; v8::Handle<v8::Object> thisObject = v8::Context::GetCurrent()->Global(); V8Proxy* proxy = V8Proxy::retrieve(); ASSERT(proxy); v8::Handle<v8::Value> result = proxy->CallFunction(callbackFunction, thisObject, argc, argv); callbackReturnValue = result.IsEmpty() && result->IsBoolean() && result->BooleanValue(); return exceptionCatcher.HasCaught(); }
v8::Handle<v8::Object> V8EntityReference::wrap(EntityReference* impl, bool forceNewObject) { v8::Handle<v8::Object> wrapper; V8Proxy* proxy = 0; if (impl->document()) { proxy = V8Proxy::retrieve(impl->document()->frame()); if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) proxy->windowShell()->initContextIfNeeded(); } if (!forceNewObject) { wrapper = V8DOMWrapper::getWrapper(impl); if (!wrapper.IsEmpty()) return wrapper; } v8::Handle<v8::Context> context; if (proxy) context = proxy->context(); // Enter the node's context and create the wrapper in that context. if (!context.IsEmpty()) context->Enter(); wrapper = V8DOMWrapper::instantiateV8Object(proxy, V8ClassIndex::ENTITYREFERENCE, impl); // Exit the node's context if it was entered. if (!context.IsEmpty()) context->Exit(); if (wrapper.IsEmpty()) return wrapper; impl->ref(); getDOMNodeMap().set(impl, v8::Persistent<v8::Object>::New(wrapper)); return wrapper; }
v8::Handle<v8::Object> V8TestNode::wrapSlow(PassRefPtr<TestNode> impl, v8::Isolate* isolate) { v8::Handle<v8::Object> wrapper; V8Proxy* proxy = V8Proxy::retrieve(impl->document()->frame()); // Enter the node's context and create the wrapper in that context. v8::Handle<v8::Context> context; if (proxy && !proxy->matchesCurrentContext()) { // For performance, we enter the context only if the currently running context // is different from the context that we are about to enter. context = proxy->context(); if (!context.IsEmpty()) context->Enter(); } wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl.get()); // Exit the node's context if it was entered. if (!context.IsEmpty()) context->Exit(); if (UNLIKELY(wrapper.IsEmpty())) return wrapper; v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper); if (!hasDependentLifetime) wrapperHandle.MarkIndependent(); wrapperHandle.SetWrapperClassId(v8DOMSubtreeClassId); V8DOMWrapper::setJSWrapperForDOMNode(impl, wrapperHandle, isolate); return wrapper; }
v8::Handle<v8::Object> V8SVGFEFuncAElement::wrap(SVGFEFuncAElement* impl) { v8::Handle<v8::Object> wrapper; V8Proxy* proxy = 0; if (impl->document()) { proxy = V8Proxy::retrieve(impl->document()->frame()); if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) proxy->windowShell()->initContextIfNeeded(); } wrapper = V8DOMWrapper::getWrapper(impl); if (!wrapper.IsEmpty()) return wrapper; v8::Handle<v8::Context> context; if (proxy) context = proxy->context(); // Enter the node's context and create the wrapper in that context. if (!context.IsEmpty()) context->Enter(); wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl); // Exit the node's context if it was entered. if (!context.IsEmpty()) context->Exit(); if (wrapper.IsEmpty()) return wrapper; impl->ref(); getDOMNodeMap().set(impl, v8::Persistent<v8::Object>::New(wrapper)); return wrapper; }
v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame) { V8Proxy* proxy = retrieve(frame); if (!proxy) return v8::Local<v8::Context>(); return proxy->mainWorldContext(); }
v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame) { V8Proxy* proxy = retrieve(frame); if (!proxy) return v8::Local<v8::Context>(); proxy->initContextIfNeeded(); return v8::Local<v8::Context>::New(proxy->context()); }
V8ObjectEventListener::~V8ObjectEventListener() { if (m_frame) { ASSERT(!m_listener.IsEmpty()); V8Proxy* proxy = V8Proxy::retrieve(m_frame); if (proxy) proxy->objectListeners()->remove(this); } disposeListenerObject(); }
void ScriptCachedFrameData::restore(Frame* frame) { if (m_context.get().IsEmpty()) return; v8::HandleScope handleScope; v8::Context::Scope contextScope(m_context.get()); m_context.get()->ReattachGlobal(m_global.get()); V8Proxy* proxy = V8Proxy::retrieve(frame); if (proxy) proxy->windowShell()->setContext(m_context.get()); }
String JSNSResolver::lookupNamespaceURI(ExceptionContext* exceptionContext, const String& prefix) { v8::Handle<v8::Function> lookupNamespaceURIFunc; v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI"); // Check if the resolver has a function property named lookupNamespaceURI. if (m_resolver->Has(lookupNamespaceURIName)) { // In case the property is a getter that throws an error, // see LayoutTests/fast/dom/SelectorAPI/NSResolver-exceptions.xhtml ExceptionCatcher exceptionCatcher(exceptionContext); v8::Handle<v8::Value> lookupNamespaceURI = m_resolver->Get( lookupNamespaceURIName); if (exceptionContext->hadException()) return String(); if (lookupNamespaceURI->IsFunction()) { lookupNamespaceURIFunc = v8::Handle<v8::Function>::Cast( lookupNamespaceURI); } } if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) { Frame* frame = ScriptController::retrieveActiveFrame(); log_info(frame, "NSResolver does not have a lookupNamespaceURI method.", String()); return String(); } // Catch exceptions from calling the namespace resolver. ExceptionCatcher exceptionCatcher(exceptionContext); const int argc = 1; v8::Handle<v8::Value> argv[argc] = { v8String(prefix) }; v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc; V8Proxy* proxy = V8Proxy::retrieve(); v8::Handle<v8::Value> retval = proxy->CallFunction(function, m_resolver, argc, argv); // Eat exceptions from namespace resolver and return an empty string. This // will cause NAMESPACE_ERR. if (exceptionContext->hadException()) return String(); return valueToStringWithNullOrUndefinedCheck(retval); }
bool ScriptController::processingUserGesture(DOMWrapperWorld*) const { Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); // No script is running, so it is user-initiated unless the gesture stack // explicitly says it is not. if (!activeFrame) return UserGestureIndicator::getUserGestureState() != DefinitelyNotProcessingUserGesture; V8Proxy* activeProxy = activeFrame->script()->proxy(); v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame); // FIXME: find all cases context can be empty: // 1) JS is disabled; // 2) page is NULL; if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> global = v8Context->Global(); v8::Handle<v8::Value> jsEvent = global->Get(v8::String::NewSymbol("event")); Event* event = V8DOMWrapper::isValidDOMObject(jsEvent) ? V8Event::toNative(v8::Handle<v8::Object>::Cast(jsEvent)) : 0; // Based on code from kjs_bindings.cpp. // Note: This is more liberal than Firefox's implementation. if (event) { if (!UserGestureIndicator::processingUserGesture()) return false; const AtomicString& type = event->type(); bool eventOk = // mouse events type == eventNames().clickEvent || type == eventNames().mousedownEvent || type == eventNames().mouseupEvent || type == eventNames().dblclickEvent // keyboard events || type == eventNames().keydownEvent || type == eventNames().keypressEvent || type == eventNames().keyupEvent // other accepted events || type == eventNames().selectEvent || type == eventNames().changeEvent || type == eventNames().focusEvent || type == eventNames().blurEvent || type == eventNames().submitEvent; if (eventOk) return true; } else if (m_sourceURL && m_sourceURL->isNull() && !activeProxy->timerCallback()) { // This is the <a href="javascript:window.open('...')> case -> we let it through. return true; } // This is the <script>window.open(...)</script> case or a timer callback -> block it. return false; }
// static v8::Handle<v8::Value> WebDevToolsAgentImpl::jsEvaluateOnSelf(const v8::Arguments& args) { String code; { v8::TryCatch exceptionCatcher; code = WebCore::toWebCoreStringWithNullCheck(args[0]); if (code.isEmpty() || exceptionCatcher.HasCaught()) return v8::Undefined(); } WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); v8::Context::Scope(agent->m_utilityContext); V8Proxy* proxy = V8Proxy::retrieve(agent->m_webViewImpl->page()->mainFrame()); v8::Local<v8::Value> result = proxy->runScript(v8::Script::Compile(v8::String::New(code.utf8().data())), true); return result; }
bool ScriptController::processingUserGesture() const { Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); // No script is running, so it must be run by users. if (!activeFrame) return true; V8Proxy* activeProxy = activeFrame->script()->proxy(); v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame); // FIXME: find all cases context can be empty: // 1) JS is disabled; // 2) page is NULL; if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> global = v8Context->Global(); v8::Handle<v8::Value> jsEvent = global->Get(v8::String::NewSymbol("event")); Event* event = V8DOMWrapper::convertToNativeEvent(jsEvent); // Based on code from kjs_bindings.cpp. // Note: This is more liberal than Firefox's implementation. if (event) { if (event->createdByDOM()) return false; const AtomicString& type = event->type(); bool eventOk = // mouse events type == eventNames().clickEvent || type == eventNames().mousedownEvent || type == eventNames().mouseupEvent || type == eventNames().dblclickEvent // keyboard events || type == eventNames().keydownEvent || type == eventNames().keypressEvent || type == eventNames().keyupEvent // other accepted events || type == eventNames().selectEvent || type == eventNames().changeEvent || type == eventNames().focusEvent || type == eventNames().blurEvent || type == eventNames().submitEvent; if (eventOk) return true; } else if (activeProxy->inlineCode() && !activeProxy->timerCallback()) { // This is the <a href="javascript:window.open('...')> case -> we let it through. return true; } // This is the <script>window.open(...)</script> case or a timer callback -> block it. return false; }
PassRefPtr<SharedPersistent<v8::Context> > V8Proxy::shared_context(Frame* frame) { V8Proxy *proxy = V8Proxy::retrieve(frame); if (!proxy) return 0; proxy->initContextIfNeeded(); RefPtr<SharedPersistent<v8::Context> > context = proxy->shared_context(); if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered()) { context = world->shared_context(); if (frame != V8Proxy::retrieveFrame(context->get())) return 0; } return context; }
// FIXME: Fix it same as _NPN_Invoke (HandleScope and such). bool _NPN_InvokeDefault(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { if (!npObject) return false; if (npObject->_class != npScriptObjectClass) { if (npObject->_class->invokeDefault) return npObject->_class->invokeDefault(npObject, arguments, argumentCount, result); VOID_TO_NPVARIANT(*result); return true; } V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject); VOID_TO_NPVARIANT(*result); v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); if (context.IsEmpty()) return false; v8::Context::Scope scope(context); ExceptionCatcher exceptionCatcher; // Lookup the function object and call it. v8::Handle<v8::Object> functionObject(v8NpObject->v8Object); if (!functionObject->IsFunction()) return false; v8::Local<v8::Value> resultObject; v8::Handle<v8::Function> function(v8::Function::Cast(*functionObject)); if (!function->IsNull()) { V8Proxy* proxy = toV8Proxy(npObject); ASSERT(proxy); OwnArrayPtr<v8::Handle<v8::Value> > argv(createValueListFromVariantArgs(arguments, argumentCount, npObject)); resultObject = proxy->callFunction(function, functionObject, argumentCount, argv.get()); } // If we had an error, return false. The spec is a little unclear here, but says "Returns true if the method was // successfully invoked". If we get an error return value, was that successfully invoked? if (resultObject.IsEmpty()) return false; convertV8ObjectToNPVariant(resultObject, npObject, result); return true; }
static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(parameter); // Remove the wrapper Frame* frame = listener->frame(); if (frame) { V8Proxy* proxy = V8Proxy::retrieve(frame); if (proxy) proxy->objectListeners()->remove(listener); // Because the listener is no longer in the list, it must be disconnected from the frame to avoid dangling frame pointer // in the destructor. listener->disconnectFrame(); } listener->disposeListenerObject(); }
bool ScriptController::processingUserGesture() { Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); // No script is running, so it is user-initiated unless the gesture stack // explicitly says it is not. if (!activeFrame) return UserGestureIndicator::getUserGestureState() != DefinitelyNotProcessingUserGesture; V8Proxy* activeProxy = activeFrame->script().proxy(); v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame); // FIXME: find all cases context can be empty: // 1) JS is disabled; // 2) page is NULL; if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Object> global = v8Context->Global(); v8::Handle<v8::String> eventSymbol = V8HiddenPropertyName::event(); v8::Handle<v8::Value> jsEvent = global->GetHiddenValue(eventSymbol); Event* event = V8DOMWrapper::isValidDOMObject(jsEvent) ? V8Event::toNative(v8::Handle<v8::Object>::Cast(jsEvent)) : 0; // Based on code from JSC's ScriptController::processingUserGesture. // Note: This is more liberal than Firefox's implementation. if (event) { // Event::fromUserGesture will return false when UserGestureIndicator::processingUserGesture() returns false. return event->fromUserGesture(); } // FIXME: We check the javascript anchor navigation from the last entered // frame becuase it should only be initiated on the last entered frame in // which execution began if it does happen. const String* sourceURL = activeFrame->script().sourceURL(); if (sourceURL && sourceURL->isNull() && !activeProxy->timerCallback()) { // This is the <a href="javascript:window.open('...')> case -> we let it through. return true; } if (activeFrame->script().allowPopupsFromPlugin()) return true; // This is the <script>window.open(...)</script> case or a timer callback -> block it. // Based on JSC version, use returned value of UserGestureIndicator::processingUserGesture for all other situations. return UserGestureIndicator::processingUserGesture(); }
bool _NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { if (!npObject) return false; if (npObject->_class == npScriptObjectClass) { V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); if (context.IsEmpty()) return false; v8::Context::Scope scope(context); ExceptionCatcher exceptionCatcher; // Lookup the constructor function. v8::Handle<v8::Object> ctorObj(object->v8Object); if (!ctorObj->IsFunction()) return false; // Call the constructor. v8::Local<v8::Value> resultObject; v8::Handle<v8::Function> ctor(v8::Function::Cast(*ctorObj)); if (!ctor->IsNull()) { V8Proxy* proxy = toV8Proxy(npObject); ASSERT(proxy); OwnArrayPtr<v8::Handle<v8::Value> > argv(createValueListFromVariantArgs(arguments, argumentCount, npObject)); resultObject = proxy->newInstance(ctor, argumentCount, argv.get()); } if (resultObject.IsEmpty()) return false; convertV8ObjectToNPVariant(resultObject, npObject, result); return true; } if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npObject->_class) && npObject->_class->construct) return npObject->_class->construct(npObject, arguments, argumentCount, result); return false; }
bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPString* npScript, NPVariant* result) { VOID_TO_NPVARIANT(*result); if (!npObject) return false; if (npObject->_class != npScriptObjectClass) return false; v8::HandleScope handleScope; v8::Handle<v8::Context> context = toV8Context(npp, npObject); if (context.IsEmpty()) return false; V8Proxy* proxy = toV8Proxy(npObject); ASSERT(proxy); v8::Context::Scope scope(context); ExceptionCatcher exceptionCatcher; String filename; if (!popupsAllowed) filename = "npscript"; // Set popupsAllowed flag to the current execution frame, so WebKit can get // right gesture status for popups initiated from plugins. Frame* frame = proxy->frame(); ASSERT(frame); bool oldAllowPopups = frame->script()->allowPopupsFromPlugin(); frame->script()->setAllowPopupsFromPlugin(popupsAllowed); String script = String::fromUTF8(npScript->UTF8Characters, npScript->UTF8Length); v8::Local<v8::Value> v8result = proxy->evaluate(ScriptSourceCode(script, KURL(ParsedURLString, filename)), 0); // Restore the old flag. frame->script()->setAllowPopupsFromPlugin(oldAllowPopups); if (v8result.IsEmpty()) return false; convertV8ObjectToNPVariant(v8result, npObject, result); return true; }
v8::Handle<v8::Object> V8SVGFontFaceElement::wrapSlow(SVGFontFaceElement* impl) { v8::Handle<v8::Object> wrapper; V8Proxy* proxy = 0; if (impl->document()) { proxy = V8Proxy::retrieve(impl->document()->frame()); if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) { if (proxy->windowShell()->initContextIfNeeded()) { // initContextIfNeeded may have created a wrapper for the object, retry from the start. return V8SVGFontFaceElement::wrap(impl); } } } v8::Handle<v8::Context> context; if (proxy) context = proxy->context(); // Enter the node's context and create the wrapper in that context. if (!context.IsEmpty()) context->Enter(); wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl); // Exit the node's context if it was entered. if (!context.IsEmpty()) context->Exit(); if (wrapper.IsEmpty()) return wrapper; impl->ref(); v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper); if (!hasDependentLifetime) wrapperHandle.MarkIndependent(); wrapperHandle.SetWrapperClassId(v8DOMSubtreeClassId); getDOMNodeMap().set(impl, wrapperHandle); return wrapper; }
ScriptState* mainWorldScriptState(Frame* frame) { v8::HandleScope handleScope; V8Proxy* proxy = frame->script()->proxy(); return ScriptState::forContext(proxy->mainWorldContext()); }
bool _NPN_Invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { if (!npObject) return false; if (npObject->_class != npScriptObjectClass) { if (npObject->_class->invoke) return npObject->_class->invoke(npObject, methodName, arguments, argumentCount, result); VOID_TO_NPVARIANT(*result); return true; } V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject); PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(methodName); if (!identifier->isString) return false; v8::HandleScope handleScope; // FIXME: should use the plugin's owner frame as the security context. v8::Handle<v8::Context> context = toV8Context(npp, npObject); if (context.IsEmpty()) return false; v8::Context::Scope scope(context); if (methodName == _NPN_GetStringIdentifier("eval")) { if (argumentCount != 1) return false; if (arguments[0].type != NPVariantType_String) return false; return _NPN_Evaluate(npp, npObject, const_cast<NPString*>(&arguments[0].value.stringValue), result); } v8::Handle<v8::Value> functionObject = v8NpObject->v8Object->Get(v8::String::New(identifier->value.string)); if (functionObject.IsEmpty() || functionObject->IsNull()) { NULL_TO_NPVARIANT(*result); return false; } if (functionObject->IsUndefined()) { VOID_TO_NPVARIANT(*result); return false; } V8Proxy* proxy = toV8Proxy(npObject); ASSERT(proxy); // Call the function object. v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(functionObject); OwnArrayPtr<v8::Handle<v8::Value> > argv(createValueListFromVariantArgs(arguments, argumentCount, npObject)); v8::Local<v8::Value> resultObject = proxy->callFunction(function, v8NpObject->v8Object, argumentCount, argv.get()); // If we had an error, return false. The spec is a little unclear here, but says "Returns true if the method was // successfully invoked". If we get an error return value, was that successfully invoked? if (resultObject.IsEmpty()) return false; convertV8ObjectToNPVariant(resultObject, npObject, result); return true; }
void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context) { if (hasExistingListenerObject()) return; if (context->isDocument() && !static_cast<Document*>(context)->contentSecurityPolicy()->allowInlineEventHandlers()) return; v8::HandleScope handleScope; V8Proxy* proxy = V8Proxy::retrieve(context); if (!proxy) return; // Use the outer scope to hold context. v8::Local<v8::Context> v8Context = worldContext().adjustedContext(proxy); // Bail out if we cannot get the context. if (v8Context.IsEmpty()) return; v8::Context::Scope scope(v8Context); // FIXME: cache the wrapper function. // Nodes other than the document object, when executing inline event // handlers push document, form, and the target node on the scope chain. // We do this by using 'with' statement. // See chrome/fast/forms/form-action.html // chrome/fast/forms/selected-index-value.html // base/fast/overflow/onscroll-layer-self-destruct.html // // Don't use new lines so that lines in the modified handler // have the same numbers as in the original code. // FIXME: What about m_eventParameterName from JSLazyEventListener? // FIXME: This approach is a giant hack! What if m_code escapes to run // arbitrary script? String code = "(function (evt) {" \ "with (this.ownerDocument ? this.ownerDocument : {}) {" \ "with (this.form ? this.form : {}) {" \ "with (this) {" \ "return (function(evt){"; code.append(m_code); // Insert '\n' otherwise //-style comments could break the handler. code.append( "\n}).call(this, evt);}}}})"); v8::Handle<v8::String> codeExternalString = v8ExternalString(code); v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_sourceURL, m_position); if (!script.IsEmpty()) { v8::Local<v8::Value> value = proxy->runScript(script, false); if (!value.IsEmpty()) { ASSERT(value->IsFunction()); v8::Local<v8::Function> wrappedFunction = v8::Local<v8::Function>::Cast(value); // Change the toString function on the wrapper function to avoid it // returning the source for the actual wrapper function. Instead it // returns source for a clean wrapper function with the event // argument wrapping the event source code. The reason for this is // that some web sites use toString on event functions and eval the // source returned (sometimes a RegExp is applied as well) for some // other use. That fails miserably if the actual wrapper source is // returned. v8::Persistent<v8::FunctionTemplate>& toStringTemplate = V8BindingPerIsolateData::current()->lazyEventListenerToStringTemplate(); if (toStringTemplate.IsEmpty()) toStringTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(V8LazyEventListenerToString)); v8::Local<v8::Function> toStringFunction; if (!toStringTemplate.IsEmpty()) toStringFunction = toStringTemplate->GetFunction(); if (!toStringFunction.IsEmpty()) { String toStringResult = "function "; toStringResult.append(m_functionName); toStringResult.append("("); toStringResult.append(m_isSVGEvent ? "evt" : "event"); toStringResult.append(") {\n "); toStringResult.append(m_code); toStringResult.append("\n}"); wrappedFunction->SetHiddenValue(V8HiddenPropertyName::toStringString(), v8ExternalString(toStringResult)); wrappedFunction->Set(v8::String::New("toString"), toStringFunction); } wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length())); setListenerObject(wrappedFunction); } } }