Implement a PageTransitionEvent constructor for JSC
[WebKit-https.git] / Source / WebCore / bindings / js / JSEventConstructors.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "EventConstructors.h"
28
29 #include "CustomEvent.h"
30 #include "Event.h"
31 #include "HashChangeEvent.h"
32 #include "JSCustomEvent.h"
33 #include "JSDictionary.h"
34 #include "JSEvent.h"
35 #include "JSHashChangeEvent.h"
36 #include "JSPageTransitionEvent.h"
37 #include "JSProgressEvent.h"
38 #include "JSWebKitAnimationEvent.h"
39 #include "PageTransitionEvent.h"
40 #include "ProgressEvent.h"
41 #include "WebKitAnimationEvent.h"
42 #include <runtime/Error.h>
43
44 using namespace JSC;
45
46 namespace WebCore {
47
48 template<typename Constructor, typename EventType, typename EventInitType>
49 static EncodedJSValue constructJSEventWithInitializer(ExecState* exec, bool (*filler)(EventInitType&, JSDictionary&))
50 {
51     Constructor* jsConstructor = static_cast<Constructor*>(exec->callee());
52
53     ScriptExecutionContext* executionContext = jsConstructor->scriptExecutionContext();
54     if (!executionContext)
55         return throwVMError(exec, createReferenceError(exec, "Constructor associated execution context is unavailable"));
56
57     AtomicString eventType = ustringToAtomicString(exec->argument(0).toString(exec));
58     if (exec->hadException())
59         return JSValue::encode(jsUndefined());
60
61     EventInitType eventInit;
62
63     JSValue initializerValue = exec->argument(1);
64     if (!initializerValue.isUndefinedOrNull()) {
65         // Given the above test, this will always yield an object.
66         JSObject* initializerObject = initializerValue.toObject(exec);
67
68         // Create the dictionary wrapper from the initializer object.
69         JSDictionary dictionary(exec, initializerObject);
70
71         // Attempt to fill in the EventInit.
72         if (!filler(eventInit, dictionary))
73             return JSValue::encode(jsUndefined());
74     }
75
76     RefPtr<EventType> event = EventType::create(eventType, eventInit);
77     return JSValue::encode(toJS(exec, jsConstructor->globalObject(), event.get()));
78 }
79
80
81 #define DICTIONARY_START(Event) \
82     static bool fill##Event##Init(Event##Init& eventInit, JSDictionary& dictionary) \
83     {
84
85 #define DICTIONARY_END(Event) \
86         return true; \
87     } \
88     \
89     EncodedJSValue JSC_HOST_CALL JS##Event##Constructor::constructJS##Event(ExecState* exec) \
90     { \
91         return constructJSEventWithInitializer<JS##Event##Constructor, Event, Event##Init>(exec, fill##Event##Init); \
92     }
93
94 #define FILL_PARENT_PROPERTIES(parent) \
95     if (!fill##parent##Init(eventInit, dictionary)) \
96         return false;
97
98 #define FILL_PROPERTY(propertyName) \
99     if (!dictionary.tryGetProperty(#propertyName, eventInit.propertyName)) \
100         return false;
101
102 INSTANTIATE_ALL_EVENT_INITIALIZING_CONSTRUCTORS(DICTIONARY_START, DICTIONARY_END, FILL_PARENT_PROPERTIES, FILL_PROPERTY)
103
104 } // namespace WebCore