Title: [108596] trunk
Revision
108596
Author
commit-qu...@webkit.org
Date
2012-02-22 19:05:55 -0800 (Wed, 22 Feb 2012)

Log Message

PopStateEvent.state should use the same object as history.state
https://bugs.webkit.org/show_bug.cgi?id=77493

Patch by Pablo Flouret <pab...@motorola.com> on 2012-02-22
Reviewed by Kentaro Hara.

Source/WebCore:

Tests: fast/loader/stateobjects/state-attribute-history-getter.html
       fast/loader/stateobjects/state-attribute-popstate-event.html

* bindings/js/JSPopStateEventCustom.cpp:
(WebCore):
(WebCore::cacheState):
(WebCore::JSPopStateEvent::state):
* bindings/v8/V8HiddenPropertyName.h:
(WebCore):
* bindings/v8/custom/V8HistoryCustom.cpp:
(WebCore::V8History::stateAccessorGetter):
(WebCore::V8History::pushStateCallback):
(WebCore::V8History::replaceStateCallback):
* bindings/v8/custom/V8PopStateEventCustom.cpp:
(WebCore):
(WebCore::cacheState):
(WebCore::V8PopStateEvent::stateAccessorGetter):
* dom/Document.cpp:
(WebCore::Document::enqueuePopstateEvent):
* dom/PopStateEvent.cpp:
(WebCore::PopStateEvent::PopStateEvent):
(WebCore::PopStateEvent::create):
* dom/PopStateEvent.h:
(WebCore):
(PopStateEvent):
(WebCore::PopStateEvent::history):
* dom/PopStateEvent.idl:
* page/History.cpp:
(WebCore::History::stateChanged):
(WebCore):
(WebCore::History::isSameAsCurrentState):
* page/History.h:
(History):

LayoutTests:

* fast/loader/stateobjects/state-attribute-history-getter-expected.txt: Added.
* fast/loader/stateobjects/state-attribute-history-getter.html: Added.
* fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt:
* fast/loader/stateobjects/state-attribute-only-one-deserialization.html:
* fast/loader/stateobjects/state-attribute-popstate-event-expected.txt: Added.
* fast/loader/stateobjects/state-attribute-popstate-event.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (108595 => 108596)


--- trunk/LayoutTests/ChangeLog	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/LayoutTests/ChangeLog	2012-02-23 03:05:55 UTC (rev 108596)
@@ -1,3 +1,17 @@
+2012-02-22  Pablo Flouret  <pab...@motorola.com>
+
+        PopStateEvent.state should use the same object as history.state
+        https://bugs.webkit.org/show_bug.cgi?id=77493
+
+        Reviewed by Kentaro Hara.
+
+        * fast/loader/stateobjects/state-attribute-history-getter-expected.txt: Added.
+        * fast/loader/stateobjects/state-attribute-history-getter.html: Added.
+        * fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt:
+        * fast/loader/stateobjects/state-attribute-only-one-deserialization.html:
+        * fast/loader/stateobjects/state-attribute-popstate-event-expected.txt: Added.
+        * fast/loader/stateobjects/state-attribute-popstate-event.html: Added.
+
 2012-02-22  Dmitry Lomov  <dslo...@google.com>
 
         [JSC] Implement ArrayBuffer and typed array cloning in JSC

Added: trunk/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter-expected.txt (0 => 108596)


--- trunk/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter-expected.txt	2012-02-23 03:05:55 UTC (rev 108596)
@@ -0,0 +1,4 @@
+Check that setting a custom getter for history.state works correctly and that PopStateEvent.state still has a correct value.
+
+PASS
+

Added: trunk/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter.html (0 => 108596)


--- trunk/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter.html	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter.html	2012-02-23 03:05:55 UTC (rev 108596)
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<p>Check that setting a custom getter for history.state works correctly and that PopStateEvent.state still has a correct value.</p>
+<pre id=log></pre>
+<script>
+function log(msg) {
+    document.querySelector("#log").innerHTML += msg + "<br>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.clearBackForwardList();
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+function test() {
+    if (!("state" in history)) {
+        log("FAIL: history.state is not defined");
+        return;
+    }
+
+    try {
+        Object.defineProperty(history, "state", { get: function () { return "oh hai" } });
+    } catch (e) {
+        // history.state is not configurable in JSC.
+        log(e.name == "TypeError" ? "PASS" : ("FAIL: unexpected exception: " + e));
+        layoutTestController.notifyDone();
+        return;
+    }
+
+    if (history.state !== "oh hai") {
+        log('FAIL: history.state != "oh hai"');
+    }
+
+    history.pushState(42, "", "");
+    history.pushState(43, "", "");
+
+    window._onpopstate_ = function(e) {
+        if (e.state !== 42)
+            log("FAIL: e.state expected 42, was " + e.state + " (of type " + typeof e.state + ")");
+        else
+            log("PASS");
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
+
+    history.back();
+}
+
+test();
+</script>

Modified: trunk/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt (108595 => 108596)


--- trunk/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt	2012-02-23 03:05:55 UTC (rev 108596)
@@ -12,7 +12,7 @@
 
 PASS history.state !== stateObject is true
 PASS popStateEvent.state !== stateObject is true
-FAIL popStateEvent.state === history.state should be true. Was false.
+PASS popStateEvent.state === history.state is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization.html (108595 => 108596)


--- trunk/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization.html	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization.html	2012-02-23 03:05:55 UTC (rev 108596)
@@ -45,7 +45,7 @@
         // Our stored reference to stateObject will not match the state object in this pop state event, as it is the same as history.state which is a structured clone of the history item's state object.
         shouldBeTrue("popStateEvent.state !== stateObject");
         // The event's state object and the current state object should match.
-        shouldBeTrue("popStateEvent.state === history.state"); // This fails for now, needs to be fixed.
+        shouldBeTrue("popStateEvent.state === history.state");
 
         var s = document.createElement("script");
         s.src = ""

Added: trunk/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event-expected.txt (0 => 108596)


--- trunk/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event-expected.txt	2012-02-23 03:05:55 UTC (rev 108596)
@@ -0,0 +1,19 @@
+Check that PopStateEvent.state always has a correct value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS history.state is defined.
+Push state 1
+Push state 2
+PASS history.state is 2
+Go back
+PASS popStateEvent.state is 1
+PASS history.state is 1
+Push state 3
+PASS popStateEvent.state is 1
+PASS history.state is 3
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event.html (0 => 108596)


--- trunk/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event.html	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event.html	2012-02-23 03:05:55 UTC (rev 108596)
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+</head/>
+<body>
+<script>
+    description("Check that PopStateEvent.state always has a correct value.");
+
+    window.jsTestIsAsync = true;
+    if (window.layoutTestController) {
+        layoutTestController.clearBackForwardList();
+        layoutTestController.waitUntilDone();
+    }
+
+    shouldBeDefined("history.state");
+
+    debug("Push state 1");
+    history.pushState(1, "", "");
+    debug("Push state 2");
+    history.pushState(2, "", "");
+    shouldEvaluateTo("history.state", 2);
+
+    var popStateEvent;
+    window._onpopstate_ = function(e) {
+        popStateEvent = e;
+        shouldEvaluateTo("popStateEvent.state", 1);
+        shouldEvaluateTo("history.state", 1);
+
+        debug("Push state 3");
+        history.pushState(3, "", "");
+        shouldEvaluateTo("popStateEvent.state", 1);
+        shouldEvaluateTo("history.state", 3);
+
+        var s = document.createElement("script");
+        s.src = ""
+        document.body.appendChild(s);
+        setTimeout(finishJSTest, 0);
+    }
+
+    debug("Go back");
+    history.back();
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (108595 => 108596)


--- trunk/Source/WebCore/ChangeLog	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/ChangeLog	2012-02-23 03:05:55 UTC (rev 108596)
@@ -1,3 +1,44 @@
+2012-02-22  Pablo Flouret  <pab...@motorola.com>
+
+        PopStateEvent.state should use the same object as history.state
+        https://bugs.webkit.org/show_bug.cgi?id=77493
+
+        Reviewed by Kentaro Hara.
+
+        Tests: fast/loader/stateobjects/state-attribute-history-getter.html
+               fast/loader/stateobjects/state-attribute-popstate-event.html
+
+        * bindings/js/JSPopStateEventCustom.cpp:
+        (WebCore):
+        (WebCore::cacheState):
+        (WebCore::JSPopStateEvent::state):
+        * bindings/v8/V8HiddenPropertyName.h:
+        (WebCore):
+        * bindings/v8/custom/V8HistoryCustom.cpp:
+        (WebCore::V8History::stateAccessorGetter):
+        (WebCore::V8History::pushStateCallback):
+        (WebCore::V8History::replaceStateCallback):
+        * bindings/v8/custom/V8PopStateEventCustom.cpp:
+        (WebCore):
+        (WebCore::cacheState):
+        (WebCore::V8PopStateEvent::stateAccessorGetter):
+        * dom/Document.cpp:
+        (WebCore::Document::enqueuePopstateEvent):
+        * dom/PopStateEvent.cpp:
+        (WebCore::PopStateEvent::PopStateEvent):
+        (WebCore::PopStateEvent::create):
+        * dom/PopStateEvent.h:
+        (WebCore):
+        (PopStateEvent):
+        (WebCore::PopStateEvent::history):
+        * dom/PopStateEvent.idl:
+        * page/History.cpp:
+        (WebCore::History::stateChanged):
+        (WebCore):
+        (WebCore::History::isSameAsCurrentState):
+        * page/History.h:
+        (History):
+
 2012-02-22  Adam Klein  <ad...@chromium.org>
 
         Remove obsolete FIXMEs from ContainerNode

Modified: trunk/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp (108595 => 108596)


--- trunk/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp	2012-02-23 03:05:55 UTC (rev 108596)
@@ -30,21 +30,52 @@
 
 #include "config.h"
 
+#include "History.h"
+#include "JSHistory.h"
 #include "JSPopStateEvent.h"
 
 using namespace JSC;
 
 namespace WebCore {
 
+// Save the state value to the m_state member of a JSPopStateEvent, and return it, for convenience.
+static const JSValue& cacheState(ExecState* exec, JSPopStateEvent* event, const JSValue& state)
+{
+    event->m_state.set(exec->globalData(), event, state);
+    return state;
+}
+
 JSValue JSPopStateEvent::state(ExecState* exec) const
 {
+    JSValue cachedValue = m_state.get();
+    if (!cachedValue.isEmpty())
+        return cachedValue;
+
     PopStateEvent* event = static_cast<PopStateEvent*>(impl());
-    SerializedScriptValue* serializedState = event->serializedState();
-    if (serializedState)
-        return serializedState->deserialize(exec, globalObject(), 0);
+
     if (!event->state().hasNoValue())
-        return event->state().jsValue();
-    return jsNull();
+        return cacheState(exec, const_cast<JSPopStateEvent*>(this), event->state().jsValue());
+
+    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());
+    JSValue result;
+
+    if (isSameState) {
+        JSHistory* jsHistory = static_cast<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);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/v8/V8HiddenPropertyName.h (108595 => 108596)


--- trunk/Source/WebCore/bindings/v8/V8HiddenPropertyName.h	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/bindings/v8/V8HiddenPropertyName.h	2012-02-23 03:05:55 UTC (rev 108596)
@@ -43,7 +43,8 @@
     V(devtoolsInjectedScript) \
     V(sleepFunction) \
     V(toStringString) \
-    V(event)
+    V(event) \
+    V(state)
 
 
     class V8HiddenPropertyName {

Modified: trunk/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp (108595 => 108596)


--- trunk/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp	2012-02-23 03:05:55 UTC (rev 108596)
@@ -37,6 +37,7 @@
 #include "V8Binding.h"
 #include "V8BindingState.h"
 #include "V8DOMWindow.h"
+#include "V8HiddenPropertyName.h"
 #include "V8Proxy.h"
 
 namespace WebCore {
@@ -46,15 +47,14 @@
     INC_STATS("DOM.History.state");
     History* history = V8History::toNative(info.Holder());
 
-    v8::Handle<v8::String> propertyName = v8::String::NewSymbol("state");
-    v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(propertyName);
+    v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(V8HiddenPropertyName::state());
 
     if (!value.IsEmpty() && !history->stateChanged())
         return value;
 
     SerializedScriptValue* serialized = history->state();
     value = serialized ? serialized->deserialize() : v8::Handle<v8::Value>(v8::Null());
-    info.Holder()->SetHiddenValue(propertyName, value);
+    info.Holder()->SetHiddenValue(V8HiddenPropertyName::state(), value);
 
     return value;
 }
@@ -80,7 +80,7 @@
     ExceptionCode ec = 0;
     History* history = V8History::toNative(args.Holder());
     history->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec);
-    args.Holder()->DeleteHiddenValue(v8::String::NewSymbol("state"));
+    args.Holder()->DeleteHiddenValue(V8HiddenPropertyName::state());
     return throwError(ec);
 }
 
@@ -105,7 +105,7 @@
     ExceptionCode ec = 0;
     History* history = V8History::toNative(args.Holder());
     history->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec);
-    args.Holder()->DeleteHiddenValue(v8::String::NewSymbol("state"));
+    args.Holder()->DeleteHiddenValue(V8HiddenPropertyName::state());
     return throwError(ec);
 }
 

Modified: trunk/Source/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp (108595 => 108596)


--- trunk/Source/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp	2012-02-23 03:05:55 UTC (rev 108596)
@@ -31,23 +31,60 @@
 #include "config.h"
 #include "V8PopStateEvent.h"
 
+#include "History.h"
 #include "PopStateEvent.h"
 #include "SerializedScriptValue.h"
+#include "V8HiddenPropertyName.h"
+#include "V8History.h"
 #include "V8Proxy.h"
 
 namespace WebCore {
 
+// Save the state value to a hidden attribute in the V8PopStateEvent, and return it, for convenience.
+static v8::Handle<v8::Value> cacheState(v8::Handle<v8::Object> popStateEvent, v8::Handle<v8::Value> state)
+{
+    popStateEvent->SetHiddenValue(V8HiddenPropertyName::state(), state);
+    return state;
+}
+
 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());
-    SerializedScriptValue* serializedState = event->serializedState();
-    if (serializedState)
-        return serializedState->deserialize();
     if (!event->state().hasNoValue())
-        return event->state().v8Value();
-    return v8::Null();
+        return cacheState(info.Holder(), event->state().v8Value());
+
+    History* history = event->history();
+    if (!history || !event->serializedState())
+        return cacheState(info.Holder(), v8::Null());
+
+    // 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).As<v8::Object>();
+        if (!history->stateChanged()) {
+            result = v8History->GetHiddenValue(V8HiddenPropertyName::state());
+            if (!result.IsEmpty())
+                return cacheState(info.Holder(), result);
+        }
+        result = event->serializedState()->deserialize();
+        v8History->SetHiddenValue(V8HiddenPropertyName::state(), result);
+    } else
+        result = event->serializedState()->deserialize();
+
+    return cacheState(info.Holder(), result);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/Document.cpp (108595 => 108596)


--- trunk/Source/WebCore/dom/Document.cpp	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-02-23 03:05:55 UTC (rev 108596)
@@ -79,6 +79,7 @@
 #include "GeolocationController.h"
 #include "HashChangeEvent.h"
 #include "HistogramSupport.h"
+#include "History.h"
 #include "HTMLAllCollection.h"
 #include "HTMLAnchorElement.h"
 #include "HTMLBodyElement.h"
@@ -5027,7 +5028,7 @@
 void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
 {
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
-    dispatchWindowEvent(PopStateEvent::create(stateObject));
+    dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
 }
 
 void Document::addMediaCanStartListener(MediaCanStartListener* listener)

Modified: trunk/Source/WebCore/dom/PopStateEvent.cpp (108595 => 108596)


--- trunk/Source/WebCore/dom/PopStateEvent.cpp	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/dom/PopStateEvent.cpp	2012-02-23 03:05:55 UTC (rev 108596)
@@ -28,6 +28,8 @@
 #include "PopStateEvent.h"
 
 #include "EventNames.h"
+#include "History.h"
+#include "SerializedScriptValue.h"
 
 namespace WebCore {
 
@@ -38,6 +40,7 @@
 PopStateEvent::PopStateEvent()
     : Event(eventNames().popstateEvent, false, true)
     , m_serializedState(0)
+    , m_history(0)
 {
 }
 
@@ -45,19 +48,14 @@
     : Event(type, initializer)
     , m_state(initializer.state)
     , m_serializedState(0)
+    , m_history(0)
 {
 }
 
-PopStateEvent::PopStateEvent(const ScriptValue& state)
+PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history)
     : Event(eventNames().popstateEvent, false, true)
-    , m_state(state)
-    , m_serializedState(0)
-{
-}
-
-PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState)
-    : Event(eventNames().popstateEvent, false, true)
     , m_serializedState(serializedState)
+    , m_history(history)
 {
 }
 
@@ -70,16 +68,11 @@
     return adoptRef(new PopStateEvent);
 }
 
-PassRefPtr<PopStateEvent> PopStateEvent::create(const ScriptValue& state)
+PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history)
 {
-    return adoptRef(new PopStateEvent(state));
+    return adoptRef(new PopStateEvent(serializedState, history));
 }
 
-PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState)
-{
-    return adoptRef(new PopStateEvent(serializedState));
-}
-
 PassRefPtr<PopStateEvent> PopStateEvent::create(const AtomicString& type, const PopStateEventInit& initializer)
 {
     return adoptRef(new PopStateEvent(type, initializer));

Modified: trunk/Source/WebCore/dom/PopStateEvent.h (108595 => 108596)


--- trunk/Source/WebCore/dom/PopStateEvent.h	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/dom/PopStateEvent.h	2012-02-23 03:05:55 UTC (rev 108596)
@@ -29,7 +29,6 @@
 
 #include "Event.h"
 #include "ScriptValue.h"
-#include "SerializedScriptValue.h"
 
 namespace WebCore {
 
@@ -39,27 +38,30 @@
     ScriptValue state;
 };
 
+class History;
+class SerializedScriptValue;
+
 class PopStateEvent : public Event {
 public:
     virtual ~PopStateEvent();
     static PassRefPtr<PopStateEvent> create();
-    static PassRefPtr<PopStateEvent> create(const ScriptValue&);
-    static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>);
+    static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
     static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
 
     SerializedScriptValue* serializedState() const { return m_serializedState.get(); }
     ScriptValue state() const { return m_state; }
+    History* history() const { return m_history.get(); }
 
     virtual const AtomicString& interfaceName() const;
 
 private:
     PopStateEvent();
     PopStateEvent(const AtomicString&, const PopStateEventInit&);
-    explicit PopStateEvent(const ScriptValue&);
-    explicit PopStateEvent(PassRefPtr<SerializedScriptValue>);
+    explicit PopStateEvent(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
 
     ScriptValue m_state;
     RefPtr<SerializedScriptValue> m_serializedState;
+    RefPtr<History> m_history;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/PopStateEvent.idl (108595 => 108596)


--- trunk/Source/WebCore/dom/PopStateEvent.idl	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/dom/PopStateEvent.idl	2012-02-23 03:05:55 UTC (rev 108596)
@@ -30,7 +30,7 @@
     interface [
         ConstructorTemplate=Event
     ] PopStateEvent : Event {
-        readonly attribute [InitializedByEventConstructor, CustomGetter] DOMObject state;
+        readonly attribute [InitializedByEventConstructor, CachedAttribute, CustomGetter] DOMObject state;
     };
 #endif
 

Modified: trunk/Source/WebCore/page/History.cpp (108595 => 108596)


--- trunk/Source/WebCore/page/History.cpp	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/page/History.cpp	2012-02-23 03:05:55 UTC (rev 108596)
@@ -77,6 +77,11 @@
     return m_lastStateObjectRequested != stateInternal();
 }
 
+bool History::isSameAsCurrentState(SerializedScriptValue* state) const
+{
+    return state == stateInternal();
+}
+
 void History::back()
 {
     go(-1);

Modified: trunk/Source/WebCore/page/History.h (108595 => 108596)


--- trunk/Source/WebCore/page/History.h	2012-02-23 03:01:11 UTC (rev 108595)
+++ trunk/Source/WebCore/page/History.h	2012-02-23 03:05:55 UTC (rev 108596)
@@ -45,7 +45,6 @@
 
     unsigned length() const;
     SerializedScriptValue* state();
-    bool stateChanged() const;
     void back();
     void forward();
     void go(int distance);
@@ -54,6 +53,9 @@
     void forward(ScriptExecutionContext*);
     void go(ScriptExecutionContext*, int distance);
 
+    bool stateChanged() const;
+    bool isSameAsCurrentState(SerializedScriptValue*) const;
+
     enum StateObjectType {
         StateObjectPush,
         StateObjectReplace
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to