Unreviewed build fix with ENABLE_DEVICE_ORIENTATION after r157215
[WebKit-https.git] / 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 #include <runtime/ObjectConstructor.h>
35
36 using namespace JSC;
37
38 namespace WebCore {
39
40 static PassRefPtr<DeviceMotionData::Acceleration> readAccelerationArgument(JSValue value, ExecState* exec)
41 {
42     if (value.isUndefinedOrNull())
43         return 0;
44
45     // Given the above test, this will always yield an object.
46     JSObject* object = value.toObject(exec);
47
48     JSValue xValue = object->get(exec, Identifier(exec, "x"));
49     if (exec->hadException())
50         return 0;
51     bool canProvideX = !xValue.isUndefinedOrNull();
52     double x = xValue.toNumber(exec);
53     if (exec->hadException())
54         return 0;
55
56     JSValue yValue = object->get(exec, Identifier(exec, "y"));
57     if (exec->hadException())
58         return 0;
59     bool canProvideY = !yValue.isUndefinedOrNull();
60     double y = yValue.toNumber(exec);
61     if (exec->hadException())
62         return 0;
63
64     JSValue zValue = object->get(exec, Identifier(exec, "z"));
65     if (exec->hadException())
66         return 0;
67     bool canProvideZ = !zValue.isUndefinedOrNull();
68     double z = zValue.toNumber(exec);
69     if (exec->hadException())
70         return 0;
71
72     if (!canProvideX && !canProvideY && !canProvideZ)
73         return 0;
74
75     return DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z);
76 }
77
78 static PassRefPtr<DeviceMotionData::RotationRate> readRotationRateArgument(JSValue value, ExecState* exec)
79 {
80     if (value.isUndefinedOrNull())
81         return 0;
82
83     // Given the above test, this will always yield an object.
84     JSObject* object = value.toObject(exec);
85
86     JSValue alphaValue = object->get(exec, Identifier(exec, "alpha"));
87     if (exec->hadException())
88         return 0;
89     bool canProvideAlpha = !alphaValue.isUndefinedOrNull();
90     double alpha = alphaValue.toNumber(exec);
91     if (exec->hadException())
92         return 0;
93
94     JSValue betaValue = object->get(exec, Identifier(exec, "beta"));
95     if (exec->hadException())
96         return 0;
97     bool canProvideBeta = !betaValue.isUndefinedOrNull();
98     double beta = betaValue.toNumber(exec);
99     if (exec->hadException())
100         return 0;
101
102     JSValue gammaValue = object->get(exec, Identifier(exec, "gamma"));
103     if (exec->hadException())
104         return 0;
105     bool canProvideGamma = !gammaValue.isUndefinedOrNull();
106     double gamma = gammaValue.toNumber(exec);
107     if (exec->hadException())
108         return 0;
109
110     if (!canProvideAlpha && !canProvideBeta && !canProvideGamma)
111         return 0;
112
113     return DeviceMotionData::RotationRate::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
114 }
115
116 static JSObject* createAccelerationObject(const DeviceMotionData::Acceleration* acceleration, ExecState* exec)
117 {
118     JSObject* object = constructEmptyObject(exec);
119     object->putDirect(exec->vm(), Identifier(exec, "x"), acceleration->canProvideX() ? jsNumber(acceleration->x()) : jsNull());
120     object->putDirect(exec->vm(), Identifier(exec, "y"), acceleration->canProvideY() ? jsNumber(acceleration->y()) : jsNull());
121     object->putDirect(exec->vm(), Identifier(exec, "z"), acceleration->canProvideZ() ? jsNumber(acceleration->z()) : jsNull());
122     return object;
123 }
124
125 static JSObject* createRotationRateObject(const DeviceMotionData::RotationRate* rotationRate, ExecState* exec)
126 {
127     JSObject* object = constructEmptyObject(exec);
128     object->putDirect(exec->vm(), Identifier(exec, "alpha"), rotationRate->canProvideAlpha() ? jsNumber(rotationRate->alpha()) : jsNull());
129     object->putDirect(exec->vm(), Identifier(exec, "beta"),  rotationRate->canProvideBeta()  ? jsNumber(rotationRate->beta())  : jsNull());
130     object->putDirect(exec->vm(), Identifier(exec, "gamma"), rotationRate->canProvideGamma() ? jsNumber(rotationRate->gamma()) : jsNull());
131     return object;
132 }
133
134 JSValue JSDeviceMotionEvent::acceleration(ExecState* exec) const
135 {
136     DeviceMotionEvent& imp = impl();
137     if (!imp.deviceMotionData()->acceleration())
138         return jsNull();
139     return createAccelerationObject(imp.deviceMotionData()->acceleration(), exec);
140 }
141
142 JSValue JSDeviceMotionEvent::accelerationIncludingGravity(ExecState* exec) const
143 {
144     DeviceMotionEvent& imp = impl();
145     if (!imp.deviceMotionData()->accelerationIncludingGravity())
146         return jsNull();
147     return createAccelerationObject(imp.deviceMotionData()->accelerationIncludingGravity(), exec);
148 }
149
150 JSValue JSDeviceMotionEvent::rotationRate(ExecState* exec) const
151 {
152     DeviceMotionEvent& imp = impl();
153     if (!imp.deviceMotionData()->rotationRate())
154         return jsNull();
155     return createRotationRateObject(imp.deviceMotionData()->rotationRate(), exec);
156 }
157
158 JSValue JSDeviceMotionEvent::interval(ExecState*) const
159 {
160     DeviceMotionEvent& imp = impl();
161     if (!imp.deviceMotionData()->canProvideInterval())
162         return jsNull();
163     return jsNumber(imp.deviceMotionData()->interval());
164 }
165
166 JSValue JSDeviceMotionEvent::initDeviceMotionEvent(ExecState* exec)
167 {
168     const String type = exec->argument(0).toString(exec)->value(exec);
169     bool bubbles = exec->argument(1).toBoolean(exec);
170     bool cancelable = exec->argument(2).toBoolean(exec);
171
172     // If any of the parameters are null or undefined, mark them as not provided.
173     // Otherwise, use the standard JavaScript conversion.
174     RefPtr<DeviceMotionData::Acceleration> acceleration = readAccelerationArgument(exec->argument(3), exec);
175     if (exec->hadException())
176         return jsUndefined();
177
178     RefPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = readAccelerationArgument(exec->argument(4), exec);
179     if (exec->hadException())
180         return jsUndefined();
181
182     RefPtr<DeviceMotionData::RotationRate> rotationRate = readRotationRateArgument(exec->argument(5), exec);
183     if (exec->hadException())
184         return jsUndefined();
185
186     bool intervalProvided = !exec->argument(6).isUndefinedOrNull();
187     double interval = exec->argument(6).toNumber(exec);
188     RefPtr<DeviceMotionData> deviceMotionData = DeviceMotionData::create(acceleration, accelerationIncludingGravity, rotationRate, intervalProvided, interval);
189     impl().initDeviceMotionEvent(type, bubbles, cancelable, deviceMotionData.get());
190     return jsUndefined();
191 }
192
193 } // namespace WebCore
194
195 #endif // ENABLE(DEVICE_ORIENTATION)