| Differences between
and this patch
- a/Source/WebCore/ChangeLog +41 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/V8HiddenPropertyName.h:
16
        (WebCore):
17
        * bindings/v8/custom/V8HistoryCustom.cpp:
18
        (WebCore::V8History::stateAccessorGetter):
19
        (WebCore::V8History::pushStateCallback):
20
        (WebCore::V8History::replaceStateCallback):
21
        * bindings/v8/custom/V8PopStateEventCustom.cpp:
22
        (WebCore):
23
        (WebCore::cacheState):
24
        (WebCore::V8PopStateEvent::stateAccessorGetter):
25
        * dom/Document.cpp:
26
        (WebCore::Document::enqueuePopstateEvent):
27
        * dom/PopStateEvent.cpp:
28
        (WebCore::PopStateEvent::PopStateEvent):
29
        (WebCore::PopStateEvent::create):
30
        * dom/PopStateEvent.h:
31
        (WebCore):
32
        (PopStateEvent):
33
        (WebCore::PopStateEvent::history):
34
        * dom/PopStateEvent.idl:
35
        * page/History.cpp:
36
        (WebCore::History::stateChanged):
37
        (WebCore):
38
        (WebCore::History::isSameAsCurrentState):
39
        * page/History.h:
40
        (History):
41
1
2012-02-08  Dirk Schulze  <krit@webkit.org>
42
2012-02-08  Dirk Schulze  <krit@webkit.org>
2
43
3
        viewBox on nested SVG causes wrong content size for relative values
44
        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/V8HiddenPropertyName.h -1 / +2 lines
Lines 43-49 namespace WebCore { a/Source/WebCore/bindings/v8/V8HiddenPropertyName.h_sec1
43
    V(devtoolsInjectedScript) \
43
    V(devtoolsInjectedScript) \
44
    V(sleepFunction) \
44
    V(sleepFunction) \
45
    V(toStringString) \
45
    V(toStringString) \
46
    V(event)
46
    V(event) \
47
    V(state)
47
48
48
49
49
    class V8HiddenPropertyName {
50
    class V8HiddenPropertyName {
- a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp -5 / +5 lines
Lines 37-42 a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp_sec1
37
#include "V8Binding.h"
37
#include "V8Binding.h"
38
#include "V8BindingState.h"
38
#include "V8BindingState.h"
39
#include "V8DOMWindow.h"
39
#include "V8DOMWindow.h"
40
#include "V8HiddenPropertyName.h"
40
#include "V8Proxy.h"
41
#include "V8Proxy.h"
41
42
42
namespace WebCore {
43
namespace WebCore {
Lines 46-60 v8::Handle<v8::Value> V8History::stateAccessorGetter(v8::Local<v8::String> name, a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp_sec2
46
    INC_STATS("DOM.History.state");
47
    INC_STATS("DOM.History.state");
47
    History* history = V8History::toNative(info.Holder());
48
    History* history = V8History::toNative(info.Holder());
48
49
49
    v8::Handle<v8::String> propertyName = v8::String::NewSymbol("state");
50
    v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(V8HiddenPropertyName::state());
50
    v8::Handle<v8::Value> value = info.Holder()->GetHiddenValue(propertyName);
51
51
52
    if (!value.IsEmpty() && !history->stateChanged())
52
    if (!value.IsEmpty() && !history->stateChanged())
53
        return value;
53
        return value;
54
54
55
    SerializedScriptValue* serialized = history->state();
55
    SerializedScriptValue* serialized = history->state();
56
    value = serialized ? serialized->deserialize() : v8::Handle<v8::Value>(v8::Null());
56
    value = serialized ? serialized->deserialize() : v8::Handle<v8::Value>(v8::Null());
57
    info.Holder()->SetHiddenValue(propertyName, value);
57
    info.Holder()->SetHiddenValue(V8HiddenPropertyName::state(), value);
58
58
59
    return value;
59
    return value;
60
}
60
}
Lines 80-86 v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args) a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp_sec3
80
    ExceptionCode ec = 0;
80
    ExceptionCode ec = 0;
81
    History* history = V8History::toNative(args.Holder());
81
    History* history = V8History::toNative(args.Holder());
82
    history->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec);
82
    history->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec);
83
    args.Holder()->DeleteHiddenValue(v8::String::NewSymbol("state"));
83
    args.Holder()->DeleteHiddenValue(V8HiddenPropertyName::state());
84
    return throwError(ec);
84
    return throwError(ec);
85
}
85
}
86
86
Lines 105-111 v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args) a/Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp_sec4
105
    ExceptionCode ec = 0;
105
    ExceptionCode ec = 0;
106
    History* history = V8History::toNative(args.Holder());
106
    History* history = V8History::toNative(args.Holder());
107
    history->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec);
107
    history->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec);
108
    args.Holder()->DeleteHiddenValue(v8::String::NewSymbol("state"));
108
    args.Holder()->DeleteHiddenValue(V8HiddenPropertyName::state());
109
    return throwError(ec);
109
    return throwError(ec);
110
}
110
}
111
111
- 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 "V8HiddenPropertyName.h"
38
#include "V8History.h"
36
#include "V8Proxy.h"
39
#include "V8Proxy.h"
37
40
38
namespace WebCore {
41
namespace WebCore {
39
42
43
// Save the state value to a hidden attribute in the V8PopStateEvent, and return it, for convenience.
44
static v8::Handle<v8::Value> cacheState(v8::Handle<v8::Object> popStateEvent, v8::Handle<v8::Value> state)
45
{
46
    popStateEvent->SetHiddenValue(V8HiddenPropertyName::state(), state);
47
    return state;
48
}
49
40
v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
50
v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
41
{
51
{
42
    INC_STATS("DOM.PopStateEvent.state");
52
    INC_STATS("DOM.PopStateEvent.state");
43
53
54
    v8::Handle<v8::Value> result = info.Holder()->GetHiddenValue(V8HiddenPropertyName::state());
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(), event->state().v8Value());
50
    return v8::Null();
62
63
    History* history = event->history();
64
    if (!history || !event->serializedState())
65
        return cacheState(info.Holder(), 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(V8HiddenPropertyName::state());
79
            if (!result.IsEmpty())
80
                return cacheState(info.Holder(), result);
81
        }
82
        result = event->serializedState()->deserialize();
83
        v8History->SetHiddenValue(V8HiddenPropertyName::state(), result);
84
    } else
85
        result = event->serializedState()->deserialize();
86
87
    return cacheState(info.Holder(), 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