| Differences between
and this patch
- a/Source/WebCore/ChangeLog +35 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2012-02-10  Pablo Flouret  <pablof@motorola.com>
2
3
        PopStateEvent.state should use the same object as history.state
4
        https://bugs.webkit.org/show_bug.cgi?id=77493
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Tests: fast/loader/stateobjects/state-attribute-history-getter.html
9
               fast/loader/stateobjects/state-attribute-popstate-event.html
10
11
        * bindings/js/JSPopStateEventCustom.cpp:
12
        (WebCore):
13
        (WebCore::cacheState):
14
        (WebCore::JSPopStateEvent::state):
15
        * bindings/v8/custom/V8PopStateEventCustom.cpp:
16
        (WebCore):
17
        (WebCore::cacheState):
18
        (WebCore::V8PopStateEvent::stateAccessorGetter):
19
        * dom/Document.cpp:
20
        (WebCore::Document::enqueuePopstateEvent):
21
        * dom/PopStateEvent.cpp:
22
        (WebCore::PopStateEvent::PopStateEvent):
23
        (WebCore::PopStateEvent::create):
24
        * dom/PopStateEvent.h:
25
        (WebCore):
26
        (PopStateEvent):
27
        (WebCore::PopStateEvent::history):
28
        * dom/PopStateEvent.idl:
29
        * page/History.cpp:
30
        (WebCore::History::stateChanged):
31
        (WebCore):
32
        (WebCore::History::isSameAsCurrentState):
33
        * page/History.h:
34
        (History):
35
1
2012-02-08  Dirk Schulze  <krit@webkit.org>
36
2012-02-08  Dirk Schulze  <krit@webkit.org>
2
37
3
        viewBox on nested SVG causes wrong content size for relative values
38
        viewBox on nested SVG causes wrong content size for relative values
- a/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp -5 / +36 lines
Lines 30-50 a/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp_sec1
30
30
31
#include "config.h"
31
#include "config.h"
32
32
33
#include "History.h"
34
#include "JSHistory.h"
33
#include "JSPopStateEvent.h"
35
#include "JSPopStateEvent.h"
34
36
35
using namespace JSC;
37
using namespace JSC;
36
38
37
namespace WebCore {
39
namespace WebCore {
38
40
41
// Save the state value to the m_state member of a JSPopStateEvent, and return it, for convenience.
42
static const JSValue& cacheState(ExecState* exec, JSPopStateEvent* event, const JSValue& state)
43
{
44
    event->m_state.set(exec->globalData(), event, state);
45
    return state;
46
}
47
39
JSValue JSPopStateEvent::state(ExecState* exec) const
48
JSValue JSPopStateEvent::state(ExecState* exec) const
40
{
49
{
50
    JSValue cachedValue = m_state.get();
51
    if (!cachedValue.isEmpty())
52
        return cachedValue;
53
41
    PopStateEvent* event = static_cast<PopStateEvent*>(impl());
54
    PopStateEvent* event = static_cast<PopStateEvent*>(impl());
42
    SerializedScriptValue* serializedState = event->serializedState();
55
43
    if (serializedState)
44
        return serializedState->deserialize(exec, globalObject(), 0);
45
    if (!event->state().hasNoValue())
56
    if (!event->state().hasNoValue())
46
        return event->state().jsValue();
57
        return cacheState(exec, const_cast<JSPopStateEvent*>(this), event->state().jsValue());
47
    return jsNull();
58
59
    History* history = event->history();
60
    if (!history || !event->serializedState())
61
        return cacheState(exec, const_cast<JSPopStateEvent*>(this), jsNull());
62
63
    // There's no cached value from a previous invocation, nor a state value was provided by the
64
    // event, but there is a history object, so first we need to see if the state object has been
65
    // deserialized through the history object already.
66
    // The current history state object might've changed in the meantime, so we need to take care
67
    // of using the correct one, and always share the same deserialization with history.state.
68
69
    bool isSameState = history->isSameAsCurrentState(event->serializedState());
70
    JSValue result;
71
72
    if (isSameState) {
73
        JSHistory* jsHistory = static_cast<JSHistory*>(toJS(exec, globalObject(), history).asCell());
74
        result = jsHistory->state(exec);
75
    } else
76
        result = event->serializedState()->deserialize(exec, globalObject(), 0);
77
78
    return cacheState(exec, const_cast<JSPopStateEvent*>(this), result);
48
}
79
}
49
80
50
} // namespace WebCore
81
} // namespace WebCore
- a/Source/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp -5 / +42 lines
Lines 31-53 a/Source/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp_sec1
31
#include "config.h"
31
#include "config.h"
32
#include "V8PopStateEvent.h"
32
#include "V8PopStateEvent.h"
33
33
34
#include "History.h"
34
#include "PopStateEvent.h"
35
#include "PopStateEvent.h"
35
#include "SerializedScriptValue.h"
36
#include "SerializedScriptValue.h"
37
#include "V8History.h"
36
#include "V8Proxy.h"
38
#include "V8Proxy.h"
37
39
38
namespace WebCore {
40
namespace WebCore {
39
41
42
// Save the state value to a hidden attribute in the V8PopStateEvent, and return it, for convenience.
43
static v8::Handle<v8::Value> cacheState(v8::Handle<v8::Object> popStateEvent, v8::Handle<v8::String> propertyName, v8::Handle<v8::Value> state)
44
{
45
    popStateEvent->SetHiddenValue(propertyName, state);
46
    return state;
47
}
48
40
v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
49
v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
41
{
50
{
42
    INC_STATS("DOM.PopStateEvent.state");
51
    INC_STATS("DOM.PopStateEvent.state");
43
52
53
    v8::Handle<v8::String> propertyName = v8::String::NewSymbol("state");
54
    v8::Handle<v8::Value> result = info.Holder()->GetHiddenValue(propertyName);
55
56
    if (!result.IsEmpty())
57
        return result;
58
44
    PopStateEvent* event = V8PopStateEvent::toNative(info.Holder());
59
    PopStateEvent* event = V8PopStateEvent::toNative(info.Holder());
45
    SerializedScriptValue* serializedState = event->serializedState();
46
    if (serializedState)
47
        return serializedState->deserialize();
48
    if (!event->state().hasNoValue())
60
    if (!event->state().hasNoValue())
49
        return event->state().v8Value();
61
        return cacheState(info.Holder(), propertyName, event->state().v8Value());
50
    return v8::Null();
62
63
    History* history = event->history();
64
    if (!history || !event->serializedState())
65
        return cacheState(info.Holder(), propertyName, v8::Null());
66
67
    // There's no cached value from a previous invocation, nor a state value was provided by the
68
    // event, but there is a history object, so first we need to see if the state object has been
69
    // deserialized through the history object already.
70
    // The current history state object might've changed in the meantime, so we need to take care
71
    // of using the correct one, and always share the same deserialization with history.state.
72
73
    bool isSameState = history->isSameAsCurrentState(event->serializedState());
74
75
    if (isSameState) {
76
        v8::Handle<v8::Object> v8History = toV8(history).As<v8::Object>();
77
        if (!history->stateChanged()) {
78
            result = v8History->GetHiddenValue(propertyName);
79
            if (!result.IsEmpty())
80
                return cacheState(info.Holder(), propertyName, result);
81
        }
82
        result = event->serializedState()->deserialize();
83
        v8History->SetHiddenValue(propertyName, result);
84
    } else
85
        result = event->serializedState()->deserialize();
86
87
    return cacheState(info.Holder(), propertyName, result);
51
}
88
}
52
89
53
} // namespace WebCore
90
} // namespace WebCore
- a/Source/WebCore/dom/Document.cpp -1 / +2 lines
Lines 78-83 a/Source/WebCore/dom/Document.cpp_sec1
78
#include "GeolocationController.h"
78
#include "GeolocationController.h"
79
#include "HashChangeEvent.h"
79
#include "HashChangeEvent.h"
80
#include "HistogramSupport.h"
80
#include "HistogramSupport.h"
81
#include "History.h"
81
#include "HTMLAllCollection.h"
82
#include "HTMLAllCollection.h"
82
#include "HTMLAnchorElement.h"
83
#include "HTMLAnchorElement.h"
83
#include "HTMLBodyElement.h"
84
#include "HTMLBodyElement.h"
Lines 5013-5019 void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL a/Source/WebCore/dom/Document.cpp_sec2
5013
void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
5014
void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
5014
{
5015
{
5015
    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
5016
    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
5016
    dispatchWindowEvent(PopStateEvent::create(stateObject));
5017
    dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
5017
}
5018
}
5018
5019
5019
void Document::addMediaCanStartListener(MediaCanStartListener* listener)
5020
void Document::addMediaCanStartListener(MediaCanStartListener* listener)
- a/Source/WebCore/dom/PopStateEvent.cpp -15 / +8 lines
Lines 28-33 a/Source/WebCore/dom/PopStateEvent.cpp_sec1
28
#include "PopStateEvent.h"
28
#include "PopStateEvent.h"
29
29
30
#include "EventNames.h"
30
#include "EventNames.h"
31
#include "History.h"
32
#include "SerializedScriptValue.h"
31
33
32
namespace WebCore {
34
namespace WebCore {
33
35
Lines 38-43 PopStateEventInit::PopStateEventInit() a/Source/WebCore/dom/PopStateEvent.cpp_sec2
38
PopStateEvent::PopStateEvent()
40
PopStateEvent::PopStateEvent()
39
    : Event(eventNames().popstateEvent, false, true)
41
    : Event(eventNames().popstateEvent, false, true)
40
    , m_serializedState(0)
42
    , m_serializedState(0)
43
    , m_history(0)
41
{
44
{
42
}
45
}
43
46
Lines 45-63 PopStateEvent::PopStateEvent(const AtomicString& type, const PopStateEventInit& a/Source/WebCore/dom/PopStateEvent.cpp_sec3
45
    : Event(type, initializer)
48
    : Event(type, initializer)
46
    , m_state(initializer.state)
49
    , m_state(initializer.state)
47
    , m_serializedState(0)
50
    , m_serializedState(0)
51
    , m_history(0)
48
{
52
{
49
}
53
}
50
54
51
PopStateEvent::PopStateEvent(const ScriptValue& state)
55
PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history)
52
    : Event(eventNames().popstateEvent, false, true)
53
    , m_state(state)
54
    , m_serializedState(0)
55
{
56
}
57
58
PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState)
59
    : Event(eventNames().popstateEvent, false, true)
56
    : Event(eventNames().popstateEvent, false, true)
60
    , m_serializedState(serializedState)
57
    , m_serializedState(serializedState)
58
    , m_history(history)
61
{
59
{
62
}
60
}
63
61
Lines 70-83 PassRefPtr<PopStateEvent> PopStateEvent::create() a/Source/WebCore/dom/PopStateEvent.cpp_sec4
70
    return adoptRef(new PopStateEvent);
68
    return adoptRef(new PopStateEvent);
71
}
69
}
72
70
73
PassRefPtr<PopStateEvent> PopStateEvent::create(const ScriptValue& state)
71
PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history)
74
{
75
    return adoptRef(new PopStateEvent(state));
76
}
77
78
PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState)
79
{
72
{
80
    return adoptRef(new PopStateEvent(serializedState));
73
    return adoptRef(new PopStateEvent(serializedState, history));
81
}
74
}
82
75
83
PassRefPtr<PopStateEvent> PopStateEvent::create(const AtomicString& type, const PopStateEventInit& initializer)
76
PassRefPtr<PopStateEvent> PopStateEvent::create(const AtomicString& type, const PopStateEventInit& initializer)
- a/Source/WebCore/dom/PopStateEvent.h -5 / +7 lines
Lines 29-35 a/Source/WebCore/dom/PopStateEvent.h_sec1
29
29
30
#include "Event.h"
30
#include "Event.h"
31
#include "ScriptValue.h"
31
#include "ScriptValue.h"
32
#include "SerializedScriptValue.h"
33
32
34
namespace WebCore {
33
namespace WebCore {
35
34
Lines 39-65 struct PopStateEventInit : public EventInit { a/Source/WebCore/dom/PopStateEvent.h_sec2
39
    ScriptValue state;
38
    ScriptValue state;
40
};
39
};
41
40
41
class History;
42
class SerializedScriptValue;
43
42
class PopStateEvent : public Event {
44
class PopStateEvent : public Event {
43
public:
45
public:
44
    virtual ~PopStateEvent();
46
    virtual ~PopStateEvent();
45
    static PassRefPtr<PopStateEvent> create();
47
    static PassRefPtr<PopStateEvent> create();
46
    static PassRefPtr<PopStateEvent> create(const ScriptValue&);
48
    static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
47
    static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>);
48
    static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
49
    static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
49
50
50
    SerializedScriptValue* serializedState() const { return m_serializedState.get(); }
51
    SerializedScriptValue* serializedState() const { return m_serializedState.get(); }
51
    ScriptValue state() const { return m_state; }
52
    ScriptValue state() const { return m_state; }
53
    History* history() const { return m_history.get(); }
52
54
53
    virtual const AtomicString& interfaceName() const;
55
    virtual const AtomicString& interfaceName() const;
54
56
55
private:
57
private:
56
    PopStateEvent();
58
    PopStateEvent();
57
    PopStateEvent(const AtomicString&, const PopStateEventInit&);
59
    PopStateEvent(const AtomicString&, const PopStateEventInit&);
58
    explicit PopStateEvent(const ScriptValue&);
60
    explicit PopStateEvent(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
59
    explicit PopStateEvent(PassRefPtr<SerializedScriptValue>);
60
61
61
    ScriptValue m_state;
62
    ScriptValue m_state;
62
    RefPtr<SerializedScriptValue> m_serializedState;
63
    RefPtr<SerializedScriptValue> m_serializedState;
64
    RefPtr<History> m_history;
63
};
65
};
64
66
65
} // namespace WebCore
67
} // namespace WebCore
- a/Source/WebCore/dom/PopStateEvent.idl -1 / +1 lines
Lines 30-36 module events { a/Source/WebCore/dom/PopStateEvent.idl_sec1
30
    interface [
30
    interface [
31
        ConstructorTemplate=Event
31
        ConstructorTemplate=Event
32
    ] PopStateEvent : Event {
32
    ] PopStateEvent : Event {
33
        readonly attribute [InitializedByEventConstructor, CustomGetter] DOMObject state;
33
        readonly attribute [InitializedByEventConstructor, CachedAttribute, CustomGetter] DOMObject state;
34
    };
34
    };
35
#endif
35
#endif
36
36
- a/Source/WebCore/page/History.cpp +5 lines
Lines 77-82 bool History::stateChanged() const a/Source/WebCore/page/History.cpp_sec1
77
    return m_lastStateObjectRequested != stateInternal();
77
    return m_lastStateObjectRequested != stateInternal();
78
}
78
}
79
79
80
bool History::isSameAsCurrentState(SerializedScriptValue* state) const
81
{
82
    return state == stateInternal();
83
}
84
80
void History::back()
85
void History::back()
81
{
86
{
82
    go(-1);
87
    go(-1);
- a/Source/WebCore/page/History.h -1 / +3 lines
Lines 45-51 public: a/Source/WebCore/page/History.h_sec1
45
45
46
    unsigned length() const;
46
    unsigned length() const;
47
    SerializedScriptValue* state();
47
    SerializedScriptValue* state();
48
    bool stateChanged() const;
49
    void back();
48
    void back();
50
    void forward();
49
    void forward();
51
    void go(int distance);
50
    void go(int distance);
Lines 54-59 public: a/Source/WebCore/page/History.h_sec2
54
    void forward(ScriptExecutionContext*);
53
    void forward(ScriptExecutionContext*);
55
    void go(ScriptExecutionContext*, int distance);
54
    void go(ScriptExecutionContext*, int distance);
56
55
56
    bool stateChanged() const;
57
    bool isSameAsCurrentState(SerializedScriptValue*) const;
58
57
    enum StateObjectType {
59
    enum StateObjectType {
58
        StateObjectPush,
60
        StateObjectPush,
59
        StateObjectReplace
61
        StateObjectReplace
- a/LayoutTests/ChangeLog +14 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2012-02-10  Pablo Flouret  <pablof@motorola.com>
2
3
        PopStateEvent.state should use the same object as history.state
4
        https://bugs.webkit.org/show_bug.cgi?id=77493
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * fast/loader/stateobjects/state-attribute-history-getter-expected.txt: Added.
9
        * fast/loader/stateobjects/state-attribute-history-getter.html: Added.
10
        * fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt:
11
        * fast/loader/stateobjects/state-attribute-only-one-deserialization.html:
12
        * fast/loader/stateobjects/state-attribute-popstate-event-expected.txt: Added.
13
        * fast/loader/stateobjects/state-attribute-popstate-event.html: Added.
14
1
2012-02-08  Julien Chaffraix  <jchaffraix@webkit.org>
15
2012-02-08  Julien Chaffraix  <jchaffraix@webkit.org>
2
16
3
        Unreviewed gardening.
17
        Unreviewed gardening.
- a/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter-expected.txt +4 lines
Line 0 a/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter-expected.txt_sec1
1
Check that setting a custom getter for history.state works correctly and that PopStateEvent.state still has a correct value.
2
3
PASS
4
- a/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter.html +50 lines
Line 0 a/LayoutTests/fast/loader/stateobjects/state-attribute-history-getter.html_sec1
1
<!DOCTYPE html>
2
<p>Check that setting a custom getter for history.state works correctly and that PopStateEvent.state still has a correct value.</p>
3
<pre id=log></pre>
4
<script>
5
function log(msg) {
6
    document.querySelector("#log").innerHTML += msg + "<br>";
7
}
8
9
if (window.layoutTestController) {
10
    layoutTestController.clearBackForwardList();
11
    layoutTestController.dumpAsText();
12
    layoutTestController.waitUntilDone();
13
}
14
15
function test() {
16
    if (!("state" in history)) {
17
        log("FAIL: history.state is not defined");
18
        return;
19
    }
20
21
    try {
22
        Object.defineProperty(history, "state", { get: function () { return "oh hai" } });
23
    } catch (e) {
24
        // history.state is not configurable in JSC.
25
        log(e.name == "TypeError" ? "PASS" : ("FAIL: unexpected exception: " + e));
26
        layoutTestController.notifyDone();
27
        return;
28
    }
29
30
    if (history.state !== "oh hai") {
31
        log('FAIL: history.state != "oh hai"');
32
    }
33
34
    history.pushState(42, "", "");
35
    history.pushState(43, "", "");
36
37
    window.onpopstate = function(e) {
38
        if (e.state !== 42)
39
            log("FAIL: e.state expected 42, was " + e.state + " (of type " + typeof e.state + ")");
40
        else
41
            log("PASS");
42
        if (window.layoutTestController)
43
            layoutTestController.notifyDone();
44
    }
45
46
    history.back();
47
}
48
49
test();
50
</script>
- a/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt -1 / +1 lines
Lines 12-18 Inside popstate event a/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization-expected.txt_sec1
12
12
13
PASS history.state !== stateObject is true
13
PASS history.state !== stateObject is true
14
PASS popStateEvent.state !== stateObject is true
14
PASS popStateEvent.state !== stateObject is true
15
FAIL popStateEvent.state === history.state should be true. Was false.
15
PASS popStateEvent.state === history.state is true
16
PASS successfullyParsed is true
16
PASS successfullyParsed is true
17
17
18
TEST COMPLETE
18
TEST COMPLETE
- a/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization.html -1 / +1 lines
Lines 45-51 a/LayoutTests/fast/loader/stateobjects/state-attribute-only-one-deserialization.html_sec1
45
        // 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.
45
        // 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.
46
        shouldBeTrue("popStateEvent.state !== stateObject");
46
        shouldBeTrue("popStateEvent.state !== stateObject");
47
        // The event's state object and the current state object should match.
47
        // The event's state object and the current state object should match.
48
        shouldBeTrue("popStateEvent.state === history.state"); // This fails for now, needs to be fixed.
48
        shouldBeTrue("popStateEvent.state === history.state");
49
49
50
        var s = document.createElement("script");
50
        var s = document.createElement("script");
51
        s.src = "../../js/resources/js-test-post.js";
51
        s.src = "../../js/resources/js-test-post.js";
- a/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event-expected.txt +19 lines
Line 0 a/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event-expected.txt_sec1
1
Check that PopStateEvent.state always has a correct value.
2
3
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
4
5
6
PASS history.state is defined.
7
Push state 1
8
Push state 2
9
PASS history.state is 2
10
Go back
11
PASS popStateEvent.state is 1
12
PASS history.state is 1
13
Push state 3
14
PASS popStateEvent.state is 1
15
PASS history.state is 3
16
PASS successfullyParsed is true
17
18
TEST COMPLETE
19
- a/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event.html +45 lines
Line 0 a/LayoutTests/fast/loader/stateobjects/state-attribute-popstate-event.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
    <script src="../../js/resources/js-test-pre.js"></script>
5
</head/>
6
<body>
7
<script>
8
    description("Check that PopStateEvent.state always has a correct value.");
9
10
    window.jsTestIsAsync = true;
11
    if (window.layoutTestController) {
12
        layoutTestController.clearBackForwardList();
13
        layoutTestController.waitUntilDone();
14
    }
15
16
    shouldBeDefined("history.state");
17
18
    debug("Push state 1");
19
    history.pushState(1, "", "");
20
    debug("Push state 2");
21
    history.pushState(2, "", "");
22
    shouldEvaluateTo("history.state", 2);
23
24
    var popStateEvent;
25
    window.onpopstate = function(e) {
26
        popStateEvent = e;
27
        shouldEvaluateTo("popStateEvent.state", 1);
28
        shouldEvaluateTo("history.state", 1);
29
30
        debug("Push state 3");
31
        history.pushState(3, "", "");
32
        shouldEvaluateTo("popStateEvent.state", 1);
33
        shouldEvaluateTo("history.state", 3);
34
35
        var s = document.createElement("script");
36
        s.src = "../../js/resources/js-test-post.js";
37
        document.body.appendChild(s);
38
        setTimeout(finishJSTest, 0);
39
    }
40
41
    debug("Go back");
42
    history.back();
43
</script>
44
</body>
45
</html>

Return to Bug 77493