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())); }
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())); }
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); }