initial import
[vuplus_webkit] / Source / WebCore / bindings / js / JSDeviceMotionEventCustom.cpp
1 /*
2  * Copyright (C) 2010 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  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * 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 THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if ENABLE(DEVICE_ORIENTATION)
29
30 #include "JSDeviceMotionEvent.h"
31
32 #include "DeviceMotionData.h"
33 #include "DeviceMotionEvent.h"
34
35 using namespace JSC;
36
37 namespace WebCore {
38
39 static PassRefPtr<DeviceMotionData::Acceleration> readAccelerationArgument(JSValue value, ExecState* exec)
40 {
41     if (value.isUndefinedOrNull())
42         return 0;
43
44     // Given the above test, this will always yield an object.
45     JSObject* object = value.toObject(exec);
46
47     JSValue xValue = object->get(exec, Identifier(exec, "x"));
48     if (exec->hadException())
49         return 0;
50     bool canProvideX = !xValue.isUndefinedOrNull();
51     double x = xValue.toNumber(exec);
52     if (exec->hadException())
53         return 0;
54
55     JSValue yValue = object->get(exec, Identifier(exec, "y"));
56     if (exec->hadException())
57         return 0;
58     bool canProvideY = !yValue.isUndefinedOrNull();
59     double y = yValue.toNumber(exec);
60     if (exec->hadException())
61         return 0;
62
63     JSValue zValue = object->get(exec, Identifier(exec, "z"));
64     if (exec->hadException())
65         return 0;
66     bool canProvideZ = !zValue.isUndefinedOrNull();
67     double z = zValue.toNumber(exec);
68     if (exec->hadException())
69         return 0;
70
71     if (!canProvideX && !canProvideY && !canProvideZ)
72         return 0;
73
74     return DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z);
75 }
76
77 static PassRefPtr<DeviceMotionData::RotationRate> readRotationRateArgument(JSValue value, ExecState* exec)
78 {
79     if (value.isUndefinedOrNull())
80         return 0;
81
82     // Given the above test, this will always yield an object.
83     JSObject* object = value.toObject(exec);
84
85     JSValue alphaValue = object->get(exec, Identifier(exec, "alpha"));
86     if (exec->hadException())
87         return 0;
88     bool canProvideAlpha = !alphaValue.isUndefinedOrNull();
89     double alpha = alphaValue.toNumber(exec);
90     if (exec->hadException())
91         return 0;
92
93     JSValue betaValue = object->get(exec, Identifier(exec, "beta"));
94     if (exec->hadException())
95         return 0;
96     bool canProvideBeta = !betaValue.isUndefinedOrNull();
97     double beta = betaValue.toNumber(exec);
98     if (exec->hadException())
99         return 0;
100
101     JSValue gammaValue = object->get(exec, Identifier(exec, "gamma"));
102     if (exec->hadException())
103         return 0;
104     bool canProvideGamma = !gammaValue.isUndefinedOrNull();
105     double gamma = gammaValue.toNumber(exec);
106     if (exec->hadException())
107         return 0;
108
109     if (!canProvideAlpha && !canProvideBeta && !canProvideGamma)
110         return 0;
111
112     return DeviceMotionData::RotationRate::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
113 }
114
115 static JSObject* createAccelerationObject(const DeviceMotionData::Acceleration* acceleration, ExecState* exec)
116 {
117     JSObject* object = constructEmptyObject(exec);
118     object->putDirect(exec->globalData(), Identifier(exec, "x"), acceleration->canProvideX() ? jsNumber(acceleration->x()) : jsNull());
119     object->putDirect(exec->globalData(), Identifier(exec, "y"), acceleration->canProvideY() ? jsNumber(acceleration->y()) : jsNull());
120     object->putDirect(exec->globalData(), Identifier(exec, "z"), acceleration->canProvideZ() ? jsNumber(acceleration->z()) : jsNull());
121     return object;
122 }
123
124 static JSObject* createRotationRateObject(const DeviceMotionData::RotationRate* rotationRate, ExecState* exec)
125 {
126     JSObject* object = constructEmptyObject(exec);
127     object->putDirect(exec->globalData(), Identifier(exec, "alpha"), rotationRate->canProvideAlpha() ? jsNumber(rotationRate->alpha()) : jsNull());
128     object->putDirect(exec->globalData(), Identifier(exec, "beta"),  rotationRate->canProvideBeta()  ? jsNumber(rotationRate->beta())  : jsNull());
129     object->putDirect(exec->globalData(), Identifier(exec, "gamma"), rotationRate->canProvideGamma() ? jsNumber(rotationRate->gamma()) : jsNull());
130     return object;
131 }
132
133 JSValue JSDeviceMotionEvent::acceleration(ExecState* exec) const
134 {
135     DeviceMotionEvent* imp = static_cast<DeviceMotionEvent*>(impl());
136     if (!imp->deviceMotionData()->acceleration())
137         return jsNull();
138     return createAccelerationObject(imp->deviceMotionData()->acceleration(), exec);
139 }
140
141 JSValue JSDeviceMotionEvent::accelerationIncludingGravity(ExecState* exec) const
142 {
143     DeviceMotionEvent* imp = static_cast<DeviceMotionEvent*>(impl());
144     if (!imp->deviceMotionData()->accelerationIncludingGravity())
145         return jsNull();
146     return createAccelerationObject(imp->deviceMotionData()->accelerationIncludingGravity(), exec);
147 }
148
149 JSValue JSDeviceMotionEvent::rotationRate(ExecState* exec) const
150 {
151     DeviceMotionEvent* imp = static_cast<DeviceMotionEvent*>(impl());
152     if (!imp->deviceMotionData()->rotationRate())
153         return jsNull();
154     return createRotationRateObject(imp->deviceMotionData()->rotationRate(), exec);
155 }
156
157 JSValue JSDeviceMotionEvent::interval(ExecState*) const
158 {
159     DeviceMotionEvent* imp = static_cast<DeviceMotionEvent*>(impl());
160     if (!imp->deviceMotionData()->canProvideInterval())
161         return jsNull();
162     return jsNumber(imp->deviceMotionData()->interval());
163 }
164
165 JSValue JSDeviceMotionEvent::initDeviceMotionEvent(ExecState* exec)
166 {
167     const String& type = ustringToString(exec->argument(0).toString(exec));
168     bool bubbles = exec->argument(1).toBoolean(exec);
169     bool cancelable = exec->argument(2).toBoolean(exec);
170
171     // If any of the parameters are null or undefined, mark them as not provided.
172     // Otherwise, use the standard JavaScript conversion.
173     RefPtr<DeviceMotionData::Acceleration> acceleration = readAccelerationArgument(exec->argument(3), exec);
174     if (exec->hadException())
175         return jsUndefined();
176
177     RefPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = readAccelerationArgument(exec->argument(4), exec);
178     if (exec->hadException())
179         return jsUndefined();
180
181     RefPtr<DeviceMotionData::RotationRate> rotationRate = readRotationRateArgument(exec->argument(5), exec);
182     if (exec->hadException())
183         return jsUndefined();
184
185     bool intervalProvided = !exec->argument(6).isUndefinedOrNull();
186     double interval = exec->argument(6).toNumber(exec);
187     RefPtr<DeviceMotionData> deviceMotionData = DeviceMotionData::create(acceleration, accelerationIncludingGravity, rotationRate, intervalProvided, interval);
188     DeviceMotionEvent* imp = static_cast<DeviceMotionEvent*>(impl());
189     imp->initDeviceMotionEvent(type, bubbles, cancelable, deviceMotionData.get());
190     return jsUndefined();
191 }
192
193 } // namespace WebCore
194
195 #endif // ENABLE(DEVICE_ORIENTATION)