Changeset 96073 in webkit


Ignore:
Timestamp:
Sep 26, 2011 11:27:02 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

Implement PopStateEvent.state with SerializedScriptValue and ScriptValue
https://bugs.webkit.org/show_bug.cgi?id=68345

Patch by Kentaro Hara <haraken@chromium.org> on 2011-09-26
Reviewed by Adam Barth.

Source/WebCore:

Previously, the following test cases fail or crash:

  • shouldBe("new PopStateEvent('eventType', { state: object1 }).state", "object1") -> FAIL
  • new PopStateEvent('eventType', { state: document }).state -> CRASH in DRT

This is because PopStateEvent.state is implemented not as ScriptValue but as SerializedScriptValue.
However, we cannot simply change the type of PopStateEvent.state to ScriptValue,
since PopStateEvent can be constructed in the context that does not know ScriptValue.
For example, Document.cpp calls PopStateEvent::create() with SerializedScriptValue
popped from HistoryItem, but we cannot deserialize the SerializedScriptValue into
the corresponding ScriptValue here because the deserialization requires ExecState.
In other words, although we want to store PopStateEvent.state by ScriptValue internally,
PopStateEvent still needs to provide an API to construct it with SerializedScriptValue.
With these observations, this patch makes the following changes:

  • If PopStateEvent is constructed with ScriptValue, it is stored as ScriptValue internally.

When PopStateEvent.state is called, the ScriptValue is returned.

  • If PopStateEvent is constructed with SerializedScriptValue, it is stored as

SerializedScriptValue internally (since we cannot deserialize it into ScriptValue
at this point). When PopStateEvent.state is called, the SerializedScriptValue is
deserialized into the corresponding ScriptValue, and the ScriptValue is returned.

Tests: fast/events/constructors/pop-state-event-constructor.html

fast/events/fire-popstate-event.html

  • GNUmakefile.list.am: Added JSPopStateEventCustom.cpp.
  • UseJSC.cmake: Ditto.
  • WebCore.gypi: Ditto.
  • WebCore.pro: Ditto.
  • WebCore.xcodeproj/project.pbxproj: Ditto.
  • bindings/js/JSBindingsAllInOne.cpp: Ditto.
  • bindings/js/JSPopStateEventCustom.cpp:

(WebCore::JSPopStateEvent::state): Custom getter for PopStateEvent.state.

  • bindings/v8/custom/V8PopStateEventCustom.cpp:

(WebCore::V8PopStateEvent::stateAccessorGetter): Custom getter for PopStateEvent.state.

  • dom/PopStateEvent.cpp:

(WebCore::PopStateEventInit::PopStateEventInit): Added initialization code for PopStateEvent.m_state.
(WebCore::PopStateEvent::PopStateEvent): Ditto.
(WebCore::PopStateEvent::create): Ditto.
(WebCore::PopStateEvent::initPopStateEvent): Ditto.

  • dom/PopStateEvent.h:

(WebCore::PopStateEvent::serializedState): Getter.
(WebCore::PopStateEvent::state): Getter.

  • dom/PopStateEvent.idl: Change the type of 'stateArg' and 'state' to DOMObject. Added [CustomGetter] to 'state'.

LayoutTests:

  • fast/events/constructors/pop-state-event-constructor-expected.txt:
  • fast/events/constructors/pop-state-event-constructor.html: Removed failures and crashes. Added one test case.
Location:
trunk
Files:
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r96069 r96073  
     12011-09-26  Kentaro Hara  <haraken@chromium.org>
     2
     3        Implement PopStateEvent.state with SerializedScriptValue and ScriptValue
     4        https://bugs.webkit.org/show_bug.cgi?id=68345
     5
     6        Reviewed by Adam Barth.
     7
     8        * fast/events/constructors/pop-state-event-constructor-expected.txt:
     9        * fast/events/constructors/pop-state-event-constructor.html: Removed failures and crashes. Added one test case.
     10
    1112011-09-09  Simon Fraser  <simon.fraser@apple.com>
    212
  • trunk/LayoutTests/fast/events/constructors/pop-state-event-constructor-expected.txt

    r95262 r96073  
    1111PASS new PopStateEvent('eventType', { cancelable: false }).cancelable is false
    1212PASS new PopStateEvent('eventType', { cancelable: true }).cancelable is true
    13 FAIL new PopStateEvent('eventType', { state: object1 }).state should be [object Object]. Was [object Object].
     13PASS new PopStateEvent('eventType', { state: object1 }).state is object1
     14PASS new PopStateEvent('eventType', { state: document }).state is document
    1415PASS new PopStateEvent('eventType', { state: undefined }).state is undefined
    1516PASS new PopStateEvent('eventType', { state: null }).state is null
    1617PASS new PopStateEvent('eventType', { state: false }).state is false
    1718PASS new PopStateEvent('eventType', { state: true }).state is true
    18 FAIL new PopStateEvent('eventType', { state: '' }).state should be undefined (of type undefined). Was  (of type string).
     19PASS new PopStateEvent('eventType', { state: '' }).state is ""
     20PASS new PopStateEvent('eventType', { state: 'doremi' }).state is "doremi"
    1921PASS new PopStateEvent('eventType', { state: 12345 }).state is 12345
    2022PASS new PopStateEvent('eventType', { state: 18446744073709551615 }).state is 18446744073709552000
    2123PASS new PopStateEvent('eventType', { state: NaN }).state is NaN
    22 FAIL new PopStateEvent('eventType', { state: {valueOf: function () { return object2; } } }).state should be [object Object]. Was [object Object].
     24PASS new PopStateEvent('eventType', { state: {valueOf: function () { return object2; } } }).state == object2 is false
    2325PASS new PopStateEvent('eventType', { get state() { return 123; } }).state is 123
    2426PASS new PopStateEvent('eventType', { get state() { throw 'PopState Error'; } }) threw exception PopState Error.
    2527PASS new PopStateEvent('eventType', { bubbles: true, cancelable: true, state: object3 }).bubbles is true
    2628PASS new PopStateEvent('eventType', { bubbles: true, cancelable: true, state: object3 }).cancelable is true
    27 FAIL new PopStateEvent('eventType', { bubbles: true, cancelable: true, state: object3 }).state should be [object Object]. Was [object Object].
     29PASS new PopStateEvent('eventType', { bubbles: true, cancelable: true, state: object3 }).state is object3
    2830PASS successfullyParsed is true
    2931
  • trunk/LayoutTests/fast/events/constructors/pop-state-event-constructor.html

    r95262 r96073  
    2828var object1 = {nyannyan: 123};
    2929shouldBe("new PopStateEvent('eventType', { state: object1 }).state", "object1");
    30 // FIXME(haraken): When we pass a DOM object, it crashes.
    31 // shouldBe("new PopStateEvent('eventType', { state: document }).state", "document");
     30shouldBe("new PopStateEvent('eventType', { state: document }).state", "document");
    3231shouldBe("new PopStateEvent('eventType', { state: undefined }).state", "undefined");
    3332shouldBe("new PopStateEvent('eventType', { state: null }).state", "null");
    3433shouldBe("new PopStateEvent('eventType', { state: false }).state", "false");
    3534shouldBe("new PopStateEvent('eventType', { state: true }).state", "true");
    36 shouldBe("new PopStateEvent('eventType', { state: '' }).state", "");
     35shouldBeEqualToString("new PopStateEvent('eventType', { state: '' }).state", "");
     36shouldBeEqualToString("new PopStateEvent('eventType', { state: 'doremi' }).state", "doremi");
    3737shouldBe("new PopStateEvent('eventType', { state: 12345 }).state", "12345");
    3838shouldBe("new PopStateEvent('eventType', { state: 18446744073709551615 }).state", "18446744073709552000");
    3939shouldBe("new PopStateEvent('eventType', { state: NaN }).state", "NaN");
    4040var object2 = {nyannyan: 456};
    41 shouldBe("new PopStateEvent('eventType', { state: {valueOf: function () { return object2; } } }).state", "object2");
     41// Note that valueOf() is not called when the left hand side is evaluated.
     42shouldBeFalse("new PopStateEvent('eventType', { state: {valueOf: function () { return object2; } } }).state == object2");
    4243shouldBe("new PopStateEvent('eventType', { get state() { return 123; } }).state", "123");
    4344shouldThrow("new PopStateEvent('eventType', { get state() { throw 'PopState Error'; } })");
  • trunk/Source/WebCore/ChangeLog

    r96070 r96073  
     12011-09-26  Kentaro Hara  <haraken@chromium.org>
     2
     3        Implement PopStateEvent.state with SerializedScriptValue and ScriptValue
     4        https://bugs.webkit.org/show_bug.cgi?id=68345
     5
     6        Reviewed by Adam Barth.
     7
     8        Previously, the following test cases fail or crash:
     9
     10        - shouldBe("new PopStateEvent('eventType', { state: object1 }).state", "object1") -> FAIL
     11        - new PopStateEvent('eventType', { state: document }).state -> CRASH in DRT
     12
     13        This is because PopStateEvent.state is implemented not as ScriptValue but as SerializedScriptValue.
     14        However, we cannot simply change the type of PopStateEvent.state to ScriptValue,
     15        since PopStateEvent can be constructed in the context that does not know ScriptValue.
     16        For example, Document.cpp calls PopStateEvent::create() with SerializedScriptValue
     17        popped from HistoryItem, but we cannot deserialize the SerializedScriptValue into
     18        the corresponding ScriptValue here because the deserialization requires ExecState.
     19        In other words, although we want to store PopStateEvent.state by ScriptValue internally,
     20        PopStateEvent still needs to provide an API to construct it with SerializedScriptValue.
     21        With these observations, this patch makes the following changes:
     22
     23        - If PopStateEvent is constructed with ScriptValue, it is stored as ScriptValue internally.
     24        When PopStateEvent.state is called, the ScriptValue is returned.
     25        - If PopStateEvent is constructed with SerializedScriptValue, it is stored as
     26        SerializedScriptValue internally (since we cannot deserialize it into ScriptValue
     27        at this point). When PopStateEvent.state is called, the SerializedScriptValue is
     28        deserialized into the corresponding ScriptValue, and the ScriptValue is returned.
     29
     30        Tests: fast/events/constructors/pop-state-event-constructor.html
     31               fast/events/fire-popstate-event.html
     32
     33        * GNUmakefile.list.am: Added JSPopStateEventCustom.cpp.
     34        * UseJSC.cmake: Ditto.
     35        * WebCore.gypi: Ditto.
     36        * WebCore.pro: Ditto.
     37        * WebCore.xcodeproj/project.pbxproj: Ditto.
     38        * bindings/js/JSBindingsAllInOne.cpp: Ditto.
     39        * bindings/js/JSPopStateEventCustom.cpp:
     40        (WebCore::JSPopStateEvent::state): Custom getter for PopStateEvent.state.
     41        * bindings/v8/custom/V8PopStateEventCustom.cpp:
     42        (WebCore::V8PopStateEvent::stateAccessorGetter): Custom getter for PopStateEvent.state.
     43        * dom/PopStateEvent.cpp:
     44        (WebCore::PopStateEventInit::PopStateEventInit): Added initialization code for PopStateEvent.m_state.
     45        (WebCore::PopStateEvent::PopStateEvent): Ditto.
     46        (WebCore::PopStateEvent::create): Ditto.
     47        (WebCore::PopStateEvent::initPopStateEvent): Ditto.
     48        * dom/PopStateEvent.h:
     49        (WebCore::PopStateEvent::serializedState): Getter.
     50        (WebCore::PopStateEvent::state): Getter.
     51        * dom/PopStateEvent.idl: Change the type of 'stateArg' and 'state' to DOMObject. Added [CustomGetter] to 'state'.
     52
    1532011-09-09  Simon Fraser  <simon.fraser@apple.com>
    254
  • trunk/Source/WebCore/GNUmakefile.list.am

    r96064 r96073  
    794794        Source/WebCore/bindings/js/JSPluginElementFunctions.cpp \
    795795        Source/WebCore/bindings/js/JSPluginElementFunctions.h \
     796        Source/WebCore/bindings/js/JSPopStateEventCustom.cpp \
    796797        Source/WebCore/bindings/js/JSProcessingInstructionCustom.cpp \
    797798        Source/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp \
  • trunk/Source/WebCore/UseJSC.cmake

    r95486 r96073  
    106106    bindings/js/JSPeerConnectionCustom.cpp
    107107    bindings/js/JSPluginElementFunctions.cpp
     108    bindings/js/JSPopStateEventCustom.cpp
    108109    bindings/js/JSProcessingInstructionCustom.cpp
    109110    bindings/js/JSScriptProfileNodeCustom.cpp
  • trunk/Source/WebCore/WebCore.gypi

    r96064 r96073  
    18981898            'bindings/js/JSPeerConnectionCustom.cpp',
    18991899            'bindings/js/JSPluginElementFunctions.cpp',
     1900            'bindings/js/JSPopStateEventCustom.cpp',
    19001901            'bindings/js/JSProcessingInstructionCustom.cpp',
    19011902            'bindings/js/JSSQLResultSetRowListCustom.cpp',
  • trunk/Source/WebCore/WebCore.pro

    r96064 r96073  
    324324        bindings/js/JSOptionConstructor.cpp \
    325325        bindings/js/JSPluginElementFunctions.cpp \
     326        bindings/js/JSPopStateEventCustom.cpp \
    326327        bindings/js/JSProcessingInstructionCustom.cpp \
    327328        bindings/js/JSScriptProfileNodeCustom.cpp \
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r96064 r96073  
    37313731                A84EBD840CB8C97700079609 /* JSStyleSheetList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A84EBD820CB8C97700079609 /* JSStyleSheetList.cpp */; };
    37323732                A853123D11D0471B00D4D077 /* FragmentScriptingPermission.h in Headers */ = {isa = PBXBuildFile; fileRef = A853123C11D0471B00D4D077 /* FragmentScriptingPermission.h */; settings = {ATTRIBUTES = (Private, ); }; };
     3733                A85F22091430377D007CC884 /* JSPopStateEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A85F22081430377D007CC884 /* JSPopStateEventCustom.cpp */; };
    37333734                A863E2011343412000274926 /* UnicodeBidi.h in Headers */ = {isa = PBXBuildFile; fileRef = A863E2001343412000274926 /* UnicodeBidi.h */; settings = {ATTRIBUTES = (Private, ); }; };
    37343735                A86629CF09DA2B47009633A5 /* JSUIEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A86629C909DA2B47009633A5 /* JSUIEvent.h */; };
     
    1025310254                A853123C11D0471B00D4D077 /* FragmentScriptingPermission.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FragmentScriptingPermission.h; sourceTree = "<group>"; };
    1025410255                A85D7A2F0879EBA9006A9172 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
     10256                A85F22081430377D007CC884 /* JSPopStateEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPopStateEventCustom.cpp; sourceTree = "<group>"; };
    1025510257                A863E2001343412000274926 /* UnicodeBidi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeBidi.h; sourceTree = "<group>"; };
    1025610258                A86629C909DA2B47009633A5 /* JSUIEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSUIEvent.h; sourceTree = "<group>"; };
     
    1871818720                        isa = PBXGroup;
    1871918721                        children = (
     18722                                A85F22081430377D007CC884 /* JSPopStateEventCustom.cpp */,
    1872018723                                BC275CB211C5E85C00C9206C /* JSArrayBufferCustom.cpp */,
    1872118724                                86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */,
     
    2635326356                                0FE71405142170B800DB33BA /* ScrollbarThemeMock.cpp in Sources */,
    2635426357                                5D8C4DBF1428222C0026CE72 /* DisplaySleepDisabler.cpp in Sources */,
     26358                                A85F22091430377D007CC884 /* JSPopStateEventCustom.cpp in Sources */,
    2635526359                        );
    2635626360                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp

    r96023 r96073  
    127127#include "JSPeerConnectionCustom.cpp"
    128128#include "JSPluginElementFunctions.cpp"
     129#include "JSPopStateEventCustom.cpp"
    129130#include "JSProcessingInstructionCustom.cpp"
    130131#include "JSRequestAnimationFrameCallbackCustom.cpp"
  • trunk/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp

    r96071 r96073  
    11/*
    2  * Copyright (C) 2010 Google Inc. All rights reserved.
     2 * Copyright (C) 2011 Google Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "config.h"
    32 #include "V8PopStateEvent.h"
    3332
    34 #include "PopStateEvent.h"
    35 #include "SerializedScriptValue.h"
    36 #include "V8Proxy.h"
     33#include "JSPopStateEvent.h"
     34
     35using namespace JSC;
    3736
    3837namespace WebCore {
    3938
    40 v8::Handle<v8::Value> V8PopStateEvent::stateAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
     39JSValue JSPopStateEvent::state(ExecState* exec) const
    4140{
    42     INC_STATS("DOM.PopStateEvent.state");
    43 
    44     PopStateEvent* event = V8PopStateEvent::toNative(info.Holder());
    45     SerializedScriptValue* state = event->state();
    46     if (!state)
    47         return v8::Null();
    48 
    49     return state->deserialize();
     41    PopStateEvent* event = static_cast<PopStateEvent*>(impl());
     42    SerializedScriptValue* serializedState = event->serializedState();
     43    if (serializedState)
     44        return serializedState->deserialize(exec, globalObject());
     45    if (!event->state().hasNoValue())
     46        return event->state().jsValue();
     47    return jsNull();
    5048}
    5149
  • trunk/Source/WebCore/bindings/v8/custom/V8PopStateEventCustom.cpp

    r95901 r96073  
    4343
    4444    PopStateEvent* event = V8PopStateEvent::toNative(info.Holder());
    45     SerializedScriptValue* state = event->state();
    46     if (!state)
    47         return v8::Null();
    48 
    49     return state->deserialize();
     45    SerializedScriptValue* serializedState = event->serializedState();
     46    if (serializedState)
     47        return serializedState->deserialize();
     48    if (!event->state().hasNoValue())
     49        return event->state().v8Value();
     50    return v8::Null();
    5051}
    5152
  • trunk/Source/WebCore/dom/PopStateEvent.cpp

    r95901 r96073  
    3434PopStateEventInit::PopStateEventInit()
    3535{
    36     state = SerializedScriptValue::create();
    3736}
    3837
    3938PopStateEvent::PopStateEvent()
    4039    : Event(eventNames().popstateEvent, false, true)
     40    , m_serializedState(0)
    4141{
    4242}
     
    4444PopStateEvent::PopStateEvent(const AtomicString& type, const PopStateEventInit& initializer)
    4545    : Event(type, initializer)
    46     , m_stateObject(initializer.state)
     46    , m_state(initializer.state)
     47    , m_serializedState(0)
    4748{
    4849}
    4950
    50 PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> stateObject)
     51PopStateEvent::PopStateEvent(ScriptValue state)
    5152    : Event(eventNames().popstateEvent, false, true)
    52     , m_stateObject(stateObject)
     53    , m_state(state)
     54    , m_serializedState(0)
     55{
     56}
     57
     58PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState)
     59    : Event(eventNames().popstateEvent, false, true)
     60    , m_serializedState(serializedState)
    5361{
    5462}
     
    6371}
    6472
    65 PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> stateObject)
     73PassRefPtr<PopStateEvent> PopStateEvent::create(ScriptValue state)
    6674{
    67     return adoptRef(new PopStateEvent(stateObject));
     75    return adoptRef(new PopStateEvent(state));
     76}
     77
     78PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState)
     79{
     80    return adoptRef(new PopStateEvent(serializedState));
    6881}
    6982
     
    7386}
    7487
    75 void PopStateEvent::initPopStateEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> stateObject)
     88void PopStateEvent::initPopStateEvent(const AtomicString& type, bool canBubble, bool cancelable, ScriptValue state)
    7689{
    7790    if (dispatched())
    7891        return;
    79    
     92
    8093    initEvent(type, canBubble, cancelable);
    8194
    82     m_stateObject = stateObject;
     95    m_state = state;
    8396}
    8497
  • trunk/Source/WebCore/dom/PopStateEvent.h

    r95901 r96073  
    2929
    3030#include "Event.h"
     31#include "ScriptValue.h"
    3132#include "SerializedScriptValue.h"
    3233
    3334namespace WebCore {
    3435
    35 class SerializedScriptValue;
    36 
    3736struct PopStateEventInit : public EventInit {
    3837    PopStateEventInit();
    3938
    40     RefPtr<SerializedScriptValue> state;
     39    ScriptValue state;
    4140};
    4241
     
    4544    virtual ~PopStateEvent();
    4645    static PassRefPtr<PopStateEvent> create();
     46    static PassRefPtr<PopStateEvent> create(ScriptValue);
    4747    static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>);
    4848    static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
    49     void initPopStateEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue>);
     49    void initPopStateEvent(const AtomicString& type, bool canBubble, bool cancelable, ScriptValue);
    5050    bool isPopStateEvent() const { return true; }
    5151
    52     SerializedScriptValue* state() const { return m_stateObject.get(); }   
     52    SerializedScriptValue* serializedState() const { return m_serializedState.get(); }
     53    ScriptValue state() const { return m_state; }
    5354
    5455private:
    5556    PopStateEvent();
    5657    PopStateEvent(const AtomicString&, const PopStateEventInit&);
     58    explicit PopStateEvent(ScriptValue);
    5759    explicit PopStateEvent(PassRefPtr<SerializedScriptValue>);
    5860
    59     RefPtr<SerializedScriptValue> m_stateObject;
     61    ScriptValue m_state;
     62    RefPtr<SerializedScriptValue> m_serializedState;
    6063};
    6164
  • trunk/Source/WebCore/dom/PopStateEvent.idl

    r95262 r96073  
    3535                               in [Optional=CallWithDefaultValue] boolean canBubbleArg,
    3636                               in [Optional=CallWithDefaultValue] boolean cancelableArg,
    37                                in [Optional=CallWithDefaultValue] SerializedScriptValue stateArg);
     37                               in [Optional=CallWithDefaultValue] DOMObject stateArg);
    3838
    39         readonly attribute [V8CustomGetter] any state;
     39        readonly attribute [CustomGetter] DOMObject state;
    4040    };
    4141#endif
Note: See TracChangeset for help on using the changeset viewer.