/* * Copyright 2009, The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "V8Geolocation.h" #include "V8PositionCallback.h" #include "V8PositionErrorCallback.h" #include "bindings/v8/V8Binding.h" #include "bindings/v8/V8Callback.h" #include "bindings/v8/V8Utilities.h" #include "modules/geolocation/Geolocation.h" using namespace std; using namespace WTF; namespace WebCore { static PassRefPtr createPositionOptions(v8::Local value, v8::Isolate* isolate, bool& succeeded) { succeeded = true; // Create default options. RefPtr options = PositionOptions::create(); // Argument is optional (hence undefined is allowed), and null is allowed. if (isUndefinedOrNull(value)) { // Use default options. return options.release(); } // Given the above test, this will always yield an object. v8::Local object = value->ToObject(); // For all three properties, we apply the following ... // - If the getter or the property's valueOf method throws an exception, we // quit so as not to risk overwriting the exception. // - If the value is absent or undefined, we don't override the default. v8::Local enableHighAccuracyValue = object->Get(v8AtomicString(isolate, "enableHighAccuracy")); if (enableHighAccuracyValue.IsEmpty()) { succeeded = false; return 0; } if (!enableHighAccuracyValue->IsUndefined()) { v8::Local enableHighAccuracyBoolean = enableHighAccuracyValue->ToBoolean(); if (enableHighAccuracyBoolean.IsEmpty()) { succeeded = false; return 0; } options->setEnableHighAccuracy(enableHighAccuracyBoolean->Value()); } v8::Local timeoutValue = object->Get(v8AtomicString(isolate, "timeout")); if (timeoutValue.IsEmpty()) { succeeded = false; return 0; } if (!timeoutValue->IsUndefined()) { v8::Local timeoutNumber = timeoutValue->ToNumber(); if (timeoutNumber.IsEmpty()) { succeeded = false; return 0; } double timeoutDouble = timeoutNumber->Value(); // If the value is positive infinity, there's nothing to do. if (!(std::isinf(timeoutDouble) && timeoutDouble > 0)) { v8::Local timeoutInt32 = timeoutValue->ToInt32(); if (timeoutInt32.IsEmpty()) { succeeded = false; return 0; } // Wrap to int32 and force non-negative to match behavior of window.setTimeout. options->setTimeout(max(0, timeoutInt32->Value())); } } v8::Local maximumAgeValue = object->Get(v8AtomicString(isolate, "maximumAge")); if (maximumAgeValue.IsEmpty()) { succeeded = false; return 0; } if (!maximumAgeValue->IsUndefined()) { v8::Local maximumAgeNumber = maximumAgeValue->ToNumber(); if (maximumAgeNumber.IsEmpty()) { succeeded = false; return 0; } double maximumAgeDouble = maximumAgeNumber->Value(); if (std::isinf(maximumAgeDouble) && maximumAgeDouble > 0) { // If the value is positive infinity, clear maximumAge. options->clearMaximumAge(); } else { v8::Local maximumAgeInt32 = maximumAgeValue->ToInt32(); if (maximumAgeInt32.IsEmpty()) { succeeded = false; return 0; } // Wrap to int32 and force non-negative to match behavior of window.setTimeout. options->setMaximumAge(max(0, maximumAgeInt32->Value())); } } return options.release(); } void V8Geolocation::getCurrentPositionMethodCustom(const v8::FunctionCallbackInfo& info) { bool succeeded = false; OwnPtr positionCallback = createFunctionOnlyCallback(info[0], succeeded, info.GetIsolate()); if (!succeeded) return; ASSERT(positionCallback); // Argument is optional (hence undefined is allowed), and null is allowed. OwnPtr positionErrorCallback = createFunctionOnlyCallback(info[1], succeeded, info.GetIsolate(), CallbackAllowUndefined | CallbackAllowNull); if (!succeeded) return; RefPtr positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded); if (!succeeded) return; ASSERT(positionOptions); Geolocation* geolocation = V8Geolocation::toNative(info.Holder()); geolocation->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release()); } void V8Geolocation::watchPositionMethodCustom(const v8::FunctionCallbackInfo& info) { bool succeeded = false; OwnPtr positionCallback = createFunctionOnlyCallback(info[0], succeeded, info.GetIsolate()); if (!succeeded) return; ASSERT(positionCallback); // Argument is optional (hence undefined is allowed), and null is allowed. OwnPtr positionErrorCallback = createFunctionOnlyCallback(info[1], succeeded, info.GetIsolate(), CallbackAllowUndefined | CallbackAllowNull); if (!succeeded) return; RefPtr positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded); if (!succeeded) return; ASSERT(positionOptions); Geolocation* geolocation = V8Geolocation::toNative(info.Holder()); int watchId = geolocation->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release()); v8SetReturnValue(info, watchId); } } // namespace WebCore