Ejemplo n.º 1
0
void V8CustomEvent::detailAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
    CustomEvent* event = V8CustomEvent::toNative(info.Holder());

    v8::Handle<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::detail(info.GetIsolate()));

    if (!result.IsEmpty()) {
        v8SetReturnValue(info, result);
        return;
    }

    if (!event->serializedDetail()) {
        // If we're in an isolated world and the event was created in the main world,
        // we need to find the 'detail' property on the main world wrapper and clone it.
        v8::Local<v8::Value> mainWorldDetail = V8HiddenValue::getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenValue::detail(info.GetIsolate()));
        if (!mainWorldDetail.IsEmpty())
            event->setSerializedDetail(SerializedScriptValue::createAndSwallowExceptions(mainWorldDetail, info.GetIsolate()));
    }

    if (event->serializedDetail()) {
        result = event->serializedDetail()->deserialize();
        v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
        return;
    }

    v8SetReturnValue(info, cacheState(info.Holder(), v8::Null(info.GetIsolate()), info.GetIsolate()));
}
void V8PopStateEvent::stateAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()));

    if (!result.IsEmpty()) {
        v8SetReturnValue(info, result);
        return;
    }

    PopStateEvent* event = V8PopStateEvent::toImpl(info.Holder());
    History* history = event->history();
    if (!history || !event->serializedState()) {
        if (!event->serializedState()) {
            // If we're in an isolated world and the event was created in the main world,
            // we need to find the 'state' property on the main world wrapper and clone it.
            v8::Local<v8::Value> mainWorldState = V8HiddenValue::getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenValue::state(info.GetIsolate()));
            if (!mainWorldState.IsEmpty())
                event->setSerializedState(SerializedScriptValueFactory::instance().createAndSwallowExceptions(info.GetIsolate(), mainWorldState));
        }
        if (event->serializedState())
            result = event->serializedState()->deserialize();
        else
            result = v8::Null(info.GetIsolate());
        v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
        return;
    }

    // There's no cached value from a previous invocation, nor a state value was provided by the
    // event, but there is a history object, so first we need to see if the state object has been
    // deserialized through the history object already.
    // The current history state object might've changed in the meantime, so we need to take care
    // of using the correct one, and always share the same deserialization with history.state.

    bool isSameState = history->isSameAsCurrentState(event->serializedState());

    if (isSameState) {
        v8::Local<v8::Value> v8HistoryValue = toV8(history, info.Holder(), info.GetIsolate());
        if (v8HistoryValue.IsEmpty())
            return;
        v8::Local<v8::Object> v8History = v8HistoryValue.As<v8::Object>();
        if (!history->stateChanged()) {
            result = V8HiddenValue::getHiddenValue(info.GetIsolate(), v8History, V8HiddenValue::state(info.GetIsolate()));
            if (!result.IsEmpty()) {
                v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
                return;
            }
        }
        result = event->serializedState()->deserialize(info.GetIsolate());
        V8HiddenValue::setHiddenValue(info.GetIsolate(), v8History, V8HiddenValue::state(info.GetIsolate()), result);
    } else {
        result = event->serializedState()->deserialize(info.GetIsolate());
    }

    v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
}
Ejemplo n.º 3
0
void V8PopStateEvent::stateAttributeGetterCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::state(info.GetIsolate()));

    if (!result.IsEmpty()) {
        v8SetReturnValue(info, result);
        return;
    }

    PopStateEvent* event = V8PopStateEvent::toImpl(info.Holder());
    History* history = event->history();
    if (!history || !event->serializedState()) {
        // If the event doesn't have serializedState(), it means that the
        // event was initialized with PopStateEventInit. In such case, we need
        // to get a v8 value for the current world from state().
        if (event->serializedState())
            result = event->serializedState()->deserialize();
        else
            result = event->state().v8ValueFor(ScriptState::current(info.GetIsolate()));
        if (result.IsEmpty())
            result = v8::Null(info.GetIsolate());
        v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
        return;
    }

    // There's no cached value from a previous invocation, nor a state value was provided by the
    // event, but there is a history object, so first we need to see if the state object has been
    // deserialized through the history object already.
    // The current history state object might've changed in the meantime, so we need to take care
    // of using the correct one, and always share the same deserialization with history.state.

    bool isSameState = history->isSameAsCurrentState(event->serializedState());

    if (isSameState) {
        v8::Local<v8::Value> v8HistoryValue = toV8(history, info.Holder(), info.GetIsolate());
        if (v8HistoryValue.IsEmpty())
            return;
        v8::Local<v8::Object> v8History = v8HistoryValue.As<v8::Object>();
        if (!history->stateChanged()) {
            result = V8HiddenValue::getHiddenValue(info.GetIsolate(), v8History, V8HiddenValue::state(info.GetIsolate()));
            if (!result.IsEmpty()) {
                v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
                return;
            }
        }
        result = event->serializedState()->deserialize(info.GetIsolate());
        V8HiddenValue::setHiddenValue(info.GetIsolate(), v8History, V8HiddenValue::state(info.GetIsolate()), result);
    } else {
        result = event->serializedState()->deserialize(info.GetIsolate());
    }

    v8SetReturnValue(info, cacheState(info.Holder(), result, info.GetIsolate()));
}
Ejemplo n.º 4
0
JSValue JSPopStateEvent::state(ExecState* exec) const
{
    JSValue cachedValue = m_state.get();
    if (!cachedValue.isEmpty()) {
        // We cannot use a cached object if we are in a different world than the one it was created in.
        if (!cachedValue.isObject() || &worldForDOMObject(cachedValue.getObject()) == &currentWorld(exec))
            return cachedValue;
        ASSERT_NOT_REACHED();
    }

    PopStateEvent& event = impl();

    if (!event.state().hasNoValue()) {
        // We need to make sure a PopStateEvent does not leak objects in its state property across isolated DOM worlds.
        // Ideally, we would check that the worlds have different privileges but that's not possible yet.
        JSValue state = event.state().jsValue();
        if (state.isObject() && &worldForDOMObject(state.getObject()) != &currentWorld(exec)) {
            if (RefPtr<SerializedScriptValue> serializedValue = event.trySerializeState(exec))
                state = serializedValue->deserialize(exec, globalObject(), nullptr);
            else
                state = jsNull();
        }

        return cacheState(exec, const_cast<JSPopStateEvent*>(this), state);
    }

    History* history = event.history();
    if (!history || !event.serializedState())
        return cacheState(exec, const_cast<JSPopStateEvent*>(this), jsNull());

    // There's no cached value from a previous invocation, nor a state value was provided by the
    // event, but there is a history object, so first we need to see if the state object has been
    // deserialized through the history object already.
    // The current history state object might've changed in the meantime, so we need to take care
    // of using the correct one, and always share the same deserialization with history.state.

    bool isSameState = history->isSameAsCurrentState(event.serializedState().get());
    JSValue result;

    if (isSameState) {
        JSHistory* jsHistory = jsCast<JSHistory*>(toJS(exec, globalObject(), history).asCell());
        result = jsHistory->state(exec);
    } else
        result = event.serializedState()->deserialize(exec, globalObject(), 0);

    return cacheState(exec, const_cast<JSPopStateEvent*>(this), result);
}
Ejemplo n.º 5
0
v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.PopStateEvent.state");

    v8::Handle<v8::Value> result = info.Holder()->GetHiddenValue(V8HiddenPropertyName::state());

    if (!result.IsEmpty())
        return result;

    PopStateEvent* event = V8PopStateEvent::toNative(info.Holder());
    if (!event->state().hasNoValue())
        return cacheState(info.Holder(), event->state().v8Value());

    History* history = event->history();
    if (!history || !event->serializedState())
        return cacheState(info.Holder(), v8::Null(info.GetIsolate()));

    // There's no cached value from a previous invocation, nor a state value was provided by the
    // event, but there is a history object, so first we need to see if the state object has been
    // deserialized through the history object already.
    // The current history state object might've changed in the meantime, so we need to take care
    // of using the correct one, and always share the same deserialization with history.state.

    bool isSameState = history->isSameAsCurrentState(event->serializedState());

    if (isSameState) {
        v8::Handle<v8::Object> v8History = toV8(history, info.Holder()->CreationContext(), info.GetIsolate()).As<v8::Object>();
        if (!history->stateChanged()) {
            result = v8History->GetHiddenValue(V8HiddenPropertyName::state());
            if (!result.IsEmpty())
                return cacheState(info.Holder(), result);
        }
        result = event->serializedState()->deserialize(0, info.GetIsolate());
        v8History->SetHiddenValue(V8HiddenPropertyName::state(), result);
    } else
        result = event->serializedState()->deserialize(0, info.GetIsolate());

    return cacheState(info.Holder(), result);
}
void V8CustomEvent::detailAttributeGetterCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    CustomEvent* event = V8CustomEvent::toImpl(info.Holder());

    v8::Local<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::detail(info.GetIsolate()));

    if (!result.IsEmpty()) {
        v8SetReturnValue(info, result);
        return;
    }

    // Be careful not to return a V8 value which is created in different world.
    v8::Local<v8::Value> detail;
    if (SerializedScriptValue* serializedValue = event->serializedDetail())
        detail = serializedValue->deserialize();
    else
        detail = event->detail().v8ValueFor(ScriptState::current(info.GetIsolate()));
    // |detail| should be null when it is an empty handle because its default value is null.
    if (detail.IsEmpty())
        detail = v8::Null(info.GetIsolate());
    v8SetReturnValue(info, cacheState(info.GetIsolate(), info.Holder(), detail));
}