2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #if ENABLE(DEVICE_ORIENTATION)
30 #include "JSDeviceMotionEvent.h"
32 #include "DeviceMotionData.h"
33 #include "DeviceMotionEvent.h"
34 #include <runtime/ObjectConstructor.h>
40 static PassRefPtr<DeviceMotionData::Acceleration> readAccelerationArgument(JSValue value, ExecState* exec)
42 if (value.isUndefinedOrNull())
45 // Given the above test, this will always yield an object.
46 JSObject* object = value.toObject(exec);
48 JSValue xValue = object->get(exec, Identifier(exec, "x"));
49 if (exec->hadException())
51 bool canProvideX = !xValue.isUndefinedOrNull();
52 double x = xValue.toNumber(exec);
53 if (exec->hadException())
56 JSValue yValue = object->get(exec, Identifier(exec, "y"));
57 if (exec->hadException())
59 bool canProvideY = !yValue.isUndefinedOrNull();
60 double y = yValue.toNumber(exec);
61 if (exec->hadException())
64 JSValue zValue = object->get(exec, Identifier(exec, "z"));
65 if (exec->hadException())
67 bool canProvideZ = !zValue.isUndefinedOrNull();
68 double z = zValue.toNumber(exec);
69 if (exec->hadException())
72 if (!canProvideX && !canProvideY && !canProvideZ)
75 return DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z);
78 static PassRefPtr<DeviceMotionData::RotationRate> readRotationRateArgument(JSValue value, ExecState* exec)
80 if (value.isUndefinedOrNull())
83 // Given the above test, this will always yield an object.
84 JSObject* object = value.toObject(exec);
86 JSValue alphaValue = object->get(exec, Identifier(exec, "alpha"));
87 if (exec->hadException())
89 bool canProvideAlpha = !alphaValue.isUndefinedOrNull();
90 double alpha = alphaValue.toNumber(exec);
91 if (exec->hadException())
94 JSValue betaValue = object->get(exec, Identifier(exec, "beta"));
95 if (exec->hadException())
97 bool canProvideBeta = !betaValue.isUndefinedOrNull();
98 double beta = betaValue.toNumber(exec);
99 if (exec->hadException())
102 JSValue gammaValue = object->get(exec, Identifier(exec, "gamma"));
103 if (exec->hadException())
105 bool canProvideGamma = !gammaValue.isUndefinedOrNull();
106 double gamma = gammaValue.toNumber(exec);
107 if (exec->hadException())
110 if (!canProvideAlpha && !canProvideBeta && !canProvideGamma)
113 return DeviceMotionData::RotationRate::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
116 static JSObject* createAccelerationObject(const DeviceMotionData::Acceleration* acceleration, ExecState* exec)
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());
125 static JSObject* createRotationRateObject(const DeviceMotionData::RotationRate* rotationRate, ExecState* exec)
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());
134 JSValue JSDeviceMotionEvent::acceleration(ExecState* exec) const
136 DeviceMotionEvent& imp = impl();
137 if (!imp.deviceMotionData()->acceleration())
139 return createAccelerationObject(imp.deviceMotionData()->acceleration(), exec);
142 JSValue JSDeviceMotionEvent::accelerationIncludingGravity(ExecState* exec) const
144 DeviceMotionEvent& imp = impl();
145 if (!imp.deviceMotionData()->accelerationIncludingGravity())
147 return createAccelerationObject(imp.deviceMotionData()->accelerationIncludingGravity(), exec);
150 JSValue JSDeviceMotionEvent::rotationRate(ExecState* exec) const
152 DeviceMotionEvent& imp = impl();
153 if (!imp.deviceMotionData()->rotationRate())
155 return createRotationRateObject(imp.deviceMotionData()->rotationRate(), exec);
158 JSValue JSDeviceMotionEvent::interval(ExecState*) const
160 DeviceMotionEvent& imp = impl();
161 if (!imp.deviceMotionData()->canProvideInterval())
163 return jsNumber(imp.deviceMotionData()->interval());
166 JSValue JSDeviceMotionEvent::initDeviceMotionEvent(ExecState* exec)
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);
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();
178 RefPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = readAccelerationArgument(exec->argument(4), exec);
179 if (exec->hadException())
180 return jsUndefined();
182 RefPtr<DeviceMotionData::RotationRate> rotationRate = readRotationRateArgument(exec->argument(5), exec);
183 if (exec->hadException())
184 return jsUndefined();
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();
193 } // namespace WebCore
195 #endif // ENABLE(DEVICE_ORIENTATION)