Exemple #1
0
v8::Local<v8::Value> V8ErrorHandler::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
{
    if (!event->hasInterface(EventNames::ErrorEvent))
        return V8EventListener::callListenerFunction(jsEvent, event);

    ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);

    if (errorEvent->world() && errorEvent->world() != &world())
        return v8::Null(isolate());

    v8::Local<v8::Object> listener = getListenerObject(scriptState()->executionContext());
    v8::Local<v8::Value> returnValue;
    if (!listener.IsEmpty() && listener->IsFunction()) {
        v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
        v8::Local<v8::Object> thisValue = scriptState()->context()->Global();

        v8::Local<v8::Value> error = V8HiddenValue::getHiddenValue(isolate(), jsEvent->ToObject(), V8HiddenValue::error(isolate()));
        if (error.IsEmpty())
            error = v8::Null(isolate());

        v8::Handle<v8::Value> parameters[5] = { v8String(isolate(), errorEvent->message()), v8String(isolate(), errorEvent->filename()), v8::Integer::New(isolate(), errorEvent->lineno()), v8::Integer::New(isolate(), errorEvent->colno()), error };
        v8::TryCatch tryCatch;
        tryCatch.SetVerbose(true);
        returnValue = ScriptController::callFunction(scriptState()->executionContext(), callFunction, thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate());
    }
    return returnValue;
}
v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptState* scriptState, v8::Local<v8::Value> jsEvent, Event* event)
{
    ASSERT(!jsEvent.IsEmpty());
    v8::Local<v8::Object> listenerObject = getListenerObject(scriptState->executionContext());
    if (listenerObject.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Local<v8::Function> handlerFunction = listenerObject.As<v8::Function>();
    v8::Local<v8::Object> receiver = getReceiverObject(scriptState, event);
    if (handlerFunction.IsEmpty() || receiver.IsEmpty())
        return v8::Local<v8::Value>();

    if (!scriptState->executionContext()->isDocument())
        return v8::Local<v8::Value>();

    LocalFrame* frame = toDocument(scriptState->executionContext())->frame();
    if (!frame)
        return v8::Local<v8::Value>();

    if (!frame->script().canExecuteScripts(AboutToExecuteScript))
        return v8::Local<v8::Value>();

    v8::Local<v8::Value> parameters[1] = { jsEvent };
    v8::Local<v8::Value> result;
    if (!frame->script().callFunction(handlerFunction, receiver, WTF_ARRAY_LENGTH(parameters), parameters).ToLocal(&result))
        return v8::Local<v8::Value>();
    return result;
}
Exemple #3
0
v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
    v8::Local<v8::Object> listenerObject = getListenerObject(context);
    if (listenerObject.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Local<v8::Function> handlerFunction = listenerObject.As<v8::Function>();
    v8::Local<v8::Object> receiver = getReceiverObject(event);
    if (handlerFunction.IsEmpty() || receiver.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Handle<v8::Value> parameters[1] = { jsEvent };

    // FIXME: Can |context| be 0 here?
    if (!context)
        return v8::Local<v8::Value>();

    if (!context->isDocument())
        return v8::Local<v8::Value>();

    Frame* frame = static_cast<Document*>(context)->frame();
    if (!frame)
        return v8::Local<v8::Value>();

    if (!frame->script()->canExecuteScripts(AboutToExecuteScript))
        return v8::Local<v8::Value>();

    return frame->script()->callFunction(handlerFunction, receiver, 1, parameters);
}
Exemple #4
0
v8::Local<v8::Value> V8ErrorHandler::callListenerFunction(
    ScriptState* scriptState,
    v8::Local<v8::Value> jsEvent,
    Event* event) {
  ASSERT(!jsEvent.IsEmpty());
  if (!event->hasInterface(EventNames::ErrorEvent))
    return V8EventListener::callListenerFunction(scriptState, jsEvent, event);

  ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
  if (errorEvent->world() && errorEvent->world() != &world())
    return v8::Null(isolate());

  v8::Local<v8::Object> listener =
      getListenerObject(scriptState->getExecutionContext());
  if (listener.IsEmpty() || !listener->IsFunction())
    return v8::Null(isolate());

  v8::Local<v8::Function> callFunction =
      v8::Local<v8::Function>::Cast(listener);
  v8::Local<v8::Object> thisValue = scriptState->context()->Global();

  v8::Local<v8::Object> eventObject;
  if (!jsEvent->ToObject(scriptState->context()).ToLocal(&eventObject))
    return v8::Null(isolate());
  auto privateError = V8PrivateProperty::getErrorEventError(isolate());
  v8::Local<v8::Value> error =
      privateError.getOrUndefined(scriptState->context(), eventObject);
  if (error->IsUndefined())
    error = v8::Null(isolate());

  v8::Local<v8::Value> parameters[5] = {
      v8String(isolate(), errorEvent->message()),
      v8String(isolate(), errorEvent->filename()),
      v8::Integer::New(isolate(), errorEvent->lineno()),
      v8::Integer::New(isolate(), errorEvent->colno()), error};
  v8::TryCatch tryCatch(isolate());
  tryCatch.SetVerbose(true);
  v8::MaybeLocal<v8::Value> result;
  if (scriptState->getExecutionContext()->isWorkerGlobalScope()) {
    result = V8ScriptRunner::callFunction(
        callFunction, scriptState->getExecutionContext(), thisValue,
        WTF_ARRAY_LENGTH(parameters), parameters, isolate());
  } else {
    result = V8ScriptRunner::callFunction(
        callFunction, scriptState->getExecutionContext(), thisValue,
        WTF_ARRAY_LENGTH(parameters), parameters, isolate());
  }
  v8::Local<v8::Value> returnValue;
  if (!result.ToLocal(&returnValue))
    return v8::Null(isolate());

  return returnValue;
}
v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(ScriptExecutionContext* context, Event* event)
{
    v8::Local<v8::Object> listener = getListenerObject(context);

    if (!listener.IsEmpty() && !listener->IsFunction())
        return listener;

    EventTarget* target = event->currentTarget();
    v8::Handle<v8::Value> value = V8DOMWrapper::convertEventTargetToV8Object(target);
    if (value.IsEmpty())
        return v8::Local<v8::Object>();
    return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
}
// FIXME: Remove getReceiverObject().
// This is almost identical to V8AbstractEventListener::getReceiverObject().
v8::Local<v8::Object> V8WorkerGlobalScopeEventListener::getReceiverObject(ScriptState* scriptState, Event* event)
{
    v8::Local<v8::Object> listener = getListenerObject(scriptState->executionContext());

    if (!listener.IsEmpty() && !listener->IsFunction())
        return listener;

    EventTarget* target = event->currentTarget();
    v8::Local<v8::Value> value = toV8(target, scriptState->context()->Global(), isolate());
    if (value.IsEmpty())
        return v8::Local<v8::Object>();
    return v8::Local<v8::Object>::New(isolate(), v8::Local<v8::Object>::Cast(value));
}
v8::Local<v8::Value> V8WorkerContextErrorHandler::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
    ASSERT(event->isErrorEvent());
    v8::Local<v8::Object> listener = getListenerObject(context);
    v8::Local<v8::Value> returnValue;
    if (!listener.IsEmpty() && listener->IsFunction()) {
        ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
        v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
        v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
        v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8::Integer::New(errorEvent->lineno()) };
        returnValue = callFunction->Call(thisValue, 3, parameters);
    }
    return returnValue;
}
v8::Local<v8::Object> V8WorkerGlobalScopeEventListener::getReceiverObject(ExecutionContext* context, Event* event)
{
    v8::Local<v8::Object> listener = getListenerObject(context);

    if (!listener.IsEmpty() && !listener->IsFunction())
        return listener;

    EventTarget* target = event->currentTarget();
    v8::Isolate* isolate = toIsolate(context);
    v8::Handle<v8::Value> value = toV8(target, v8::Handle<v8::Object>(), isolate);
    if (value.IsEmpty())
        return v8::Local<v8::Object>();
    return v8::Local<v8::Object>::New(isolate, v8::Handle<v8::Object>::Cast(value));
}
bool V8WorkerContextEventListener::reportError(const String& message, const String& url, int lineNumber)
{
    // Is the EventListener disconnected?
    if (disconnected())
        return false;

    // The callback function can clear the event listener and destroy 'this' object. Keep a local reference to it.
    RefPtr<V8AbstractEventListener> protect(this);

    v8::HandleScope handleScope;

    v8::Handle<v8::Context> context = m_proxy->context();
    if (context.IsEmpty())
        return false;

    // Enter the V8 context in which to perform the event handling.
    v8::Context::Scope scope(context);

    v8::Local<v8::Object> listener = getListenerObject();
    v8::Local<v8::Value> returnValue;
    {
        // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire.
        v8::TryCatch tryCatch;
        tryCatch.SetVerbose(true);

        // Call the function.
        if (!listener.IsEmpty() && listener->IsFunction()) {
            v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
            v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();

            v8::Handle<v8::Value> parameters[3] = { v8String(message), v8String(url), v8::Integer::New(lineNumber) };
            returnValue = callFunction->Call(thisValue, 3, parameters);
        }

        // If an error occurs while handling the script error, it should be bubbled up.
        if (tryCatch.HasCaught()) {
            tryCatch.Reset();
            return false;
        }
    }

    // If the function returns false, then the error is handled. Otherwise, the error is not handled.
    bool errorHandled = returnValue->IsBoolean() && !returnValue->BooleanValue();

    return errorHandled;
}
Exemple #10
0
v8::Local<v8::Value> V8WindowErrorHandler::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
    if (!event->hasInterface(eventNames().interfaceForErrorEvent))
        return V8EventListener::callListenerFunction(context, jsEvent, event);

    ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
    v8::Local<v8::Object> listener = getListenerObject(context);
    v8::Local<v8::Value> returnValue;
    if (!listener.IsEmpty() && listener->IsFunction()) {
        v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
        v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
        v8::Handle<v8::Value> parameters[3] = { v8String(errorEvent->message()), v8String(errorEvent->filename()), v8Integer(errorEvent->lineno()) };
        v8::TryCatch tryCatch;
        tryCatch.SetVerbose(true);
        returnValue = V8Proxy::instrumentedCallFunction(0 /* frame */, callFunction, thisValue, 3, parameters);
    }
    return returnValue;
}
Exemple #11
0
v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
    v8::Local<v8::Object> listenerObject = getListenerObject(context);
    if (listenerObject.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(listenerObject);
    v8::Local<v8::Object> receiver = getReceiverObject(event);
    if (handlerFunction.IsEmpty() || receiver.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Handle<v8::Value> parameters[1] = { jsEvent };

    if (V8Proxy* proxy = V8Proxy::retrieve(context))
        return proxy->callFunction(handlerFunction, receiver, 1, parameters);

    return v8::Local<v8::Value>();
}
v8::Local<v8::Function> V8EventListener::getListenerFunction(ScriptExecutionContext* context)
{
    v8::Local<v8::Object> listener = getListenerObject(context);

    // Has the listener been disposed?
    if (listener.IsEmpty())
        return v8::Local<v8::Function>();

    if (listener->IsFunction())
        return v8::Local<v8::Function>::Cast(listener);

    if (listener->IsObject()) {
        v8::Local<v8::Value> property = listener->Get(v8::String::NewSymbol("handleEvent"));
        if (property->IsFunction())
            return v8::Local<v8::Function>::Cast(property);
    }

    return v8::Local<v8::Function>();
}
Exemple #13
0
v8::Local<v8::Function> V8EventListener::getListenerFunction(ScriptExecutionContext* context)
{
    v8::Local<v8::Object> listener = getListenerObject(context);

    // Has the listener been disposed?
    if (listener.IsEmpty())
        return v8::Local<v8::Function>();

    if (listener->IsFunction())
        return v8::Local<v8::Function>::Cast(listener);

    if (listener->IsObject()) {
        v8::Local<v8::Value> property = listener->Get(v8::String::NewSymbol("handleEvent"));
        // Check that no exceptions were thrown when getting the
        // handleEvent property and that the value is a function.
        if (!property.IsEmpty() && property->IsFunction())
            return v8::Local<v8::Function>::Cast(property);
    }

    return v8::Local<v8::Function>();
}
Exemple #14
0
v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
    v8::Local<v8::Object> listenerObject = getListenerObject(context);
    if (listenerObject.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Local<v8::Function> handlerFunction = listenerObject.As<v8::Function>();
    v8::Local<v8::Object> receiver = getReceiverObject(event);
    if (handlerFunction.IsEmpty() || receiver.IsEmpty())
        return v8::Local<v8::Value>();

    v8::Handle<v8::Value> parameters[1] = { jsEvent };

    if (V8Proxy* proxy = V8Proxy::retrieve(context)) {
        Frame* frame = static_cast<Document*>(context)->frame();
        if (frame->script()->canExecuteScripts(AboutToExecuteScript))
            return proxy->callFunction(handlerFunction, receiver, 1, parameters);
    }

    return v8::Local<v8::Value>();
}
Exemple #15
0
v8::Local<v8::Function> V8EventListener::getListenerFunction(
    ScriptState* scriptState) {
    v8::Local<v8::Object> listener =
        getListenerObject(scriptState->getExecutionContext());

    // Has the listener been disposed?
    if (listener.IsEmpty())
        return v8::Local<v8::Function>();

    if (listener->IsFunction())
        return v8::Local<v8::Function>::Cast(listener);

    // The EventHandler callback function type (used for event handler
    // attributes in HTML) has [TreatNonObjectAsNull], which implies that
    // non-function objects should be treated as no-op functions that return
    // undefined.
    if (isAttribute())
        return v8::Local<v8::Function>();

    // Getting the handleEvent property can runs script in the getter.
    if (ScriptForbiddenScope::isScriptForbidden()) {
        V8ThrowException::throwError(isolate(), "Script execution is forbidden.");
        return v8::Local<v8::Function>();
    }

    if (listener->IsObject()) {
        // Check that no exceptions were thrown when getting the
        // handleEvent property and that the value is a function.
        v8::Local<v8::Value> property;
        if (listener
                ->Get(scriptState->context(),
                      v8AtomicString(isolate(), "handleEvent"))
                .ToLocal(&property) &&
                property->IsFunction())
            return v8::Local<v8::Function>::Cast(property);
    }

    return v8::Local<v8::Function>();
}
v8::Local<v8::Function> V8EventListener::getListenerFunction(ScriptState* scriptState)
{
    v8::Local<v8::Object> listener = getListenerObject(scriptState->executionContext());

    // Has the listener been disposed?
    if (listener.IsEmpty())
        return v8::Local<v8::Function>();

    if (listener->IsFunction())
        return v8::Local<v8::Function>::Cast(listener);

    if (listener->IsObject()) {
        ASSERT_WITH_MESSAGE(!isAttribute(), "EventHandler attributes should only accept JS Functions as input.");
        v8::Local<v8::Value> property = listener->Get(v8AtomicString(isolate(), "handleEvent"));
        // Check that no exceptions were thrown when getting the
        // handleEvent property and that the value is a function.
        if (!property.IsEmpty() && property->IsFunction())
            return v8::Local<v8::Function>::Cast(property);
    }

    return v8::Local<v8::Function>();
}