Home | History | Annotate | Download | only in custom
      1 /*
      2  * Copyright 2009, The Android Open Source Project
      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 #include "bindings/modules/v8/V8Geolocation.h"
     28 
     29 #include "bindings/modules/v8/V8PositionCallback.h"
     30 #include "bindings/modules/v8/V8PositionErrorCallback.h"
     31 #include "bindings/v8/V8Binding.h"
     32 #include "bindings/v8/V8Callback.h"
     33 #include "modules/geolocation/Geolocation.h"
     34 
     35 using namespace WTF;
     36 
     37 namespace WebCore {
     38 
     39 static PositionOptions* createPositionOptions(v8::Local<v8::Value> value, v8::Isolate* isolate, bool& succeeded, ExceptionState& exceptionState)
     40 {
     41     succeeded = true;
     42 
     43     // Create default options.
     44     PositionOptions* options = PositionOptions::create();
     45 
     46     // Argument is optional (hence undefined is allowed), and null is allowed.
     47     if (isUndefinedOrNull(value)) {
     48         // Use default options.
     49         return options;
     50     }
     51 
     52     // Given the above test, this will always yield an object.
     53     v8::Local<v8::Object> object = value->ToObject();
     54 
     55     // For all three properties, we apply the following ...
     56     // - If the getter or the property's valueOf method throws an exception, we
     57     //   quit so as not to risk overwriting the exception.
     58     // - If the value is absent or undefined, we don't override the default.
     59     v8::Local<v8::Value> enableHighAccuracyValue = object->Get(v8AtomicString(isolate, "enableHighAccuracy"));
     60     if (enableHighAccuracyValue.IsEmpty()) {
     61         succeeded = false;
     62         return nullptr;
     63     }
     64     if (!enableHighAccuracyValue->IsUndefined()) {
     65         v8::Local<v8::Boolean> enableHighAccuracyBoolean = enableHighAccuracyValue->ToBoolean();
     66         if (enableHighAccuracyBoolean.IsEmpty()) {
     67             succeeded = false;
     68             return nullptr;
     69         }
     70         options->setEnableHighAccuracy(enableHighAccuracyBoolean->Value());
     71     }
     72 
     73     v8::Local<v8::Value> timeoutValue = object->Get(v8AtomicString(isolate, "timeout"));
     74     if (timeoutValue.IsEmpty()) {
     75         succeeded = false;
     76         return nullptr;
     77     }
     78     if (!timeoutValue->IsUndefined()) {
     79         v8::Local<v8::Number> timeoutNumber = timeoutValue->ToNumber();
     80         if (timeoutNumber.IsEmpty()) {
     81             succeeded = false;
     82             return nullptr;
     83         }
     84         if (timeoutNumber->Value() <= 0)
     85             options->setTimeout(0);
     86         else
     87             options->setTimeout(toUInt32(timeoutValue, Clamp, exceptionState));
     88     }
     89 
     90     v8::Local<v8::Value> maximumAgeValue = object->Get(v8AtomicString(isolate, "maximumAge"));
     91     if (maximumAgeValue.IsEmpty()) {
     92         succeeded = false;
     93         return nullptr;
     94     }
     95     if (!maximumAgeValue->IsUndefined()) {
     96         v8::Local<v8::Number> maximumAgeNumber = maximumAgeValue->ToNumber();
     97         if (maximumAgeNumber.IsEmpty()) {
     98             succeeded = false;
     99             return nullptr;
    100         }
    101         if (maximumAgeNumber->Value() <= 0)
    102             options->setMaximumAge(0);
    103         else
    104             options->setMaximumAge(toUInt32(maximumAgeValue, Clamp, exceptionState));
    105     }
    106 
    107     return options;
    108 }
    109 
    110 void V8Geolocation::getCurrentPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    111 {
    112     bool succeeded = false;
    113 
    114     ExceptionState exceptionState(ExceptionState::ExecutionContext, "getCurrentPosition", "Geolocation", info.Holder(), info.GetIsolate());
    115 
    116     OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], 1, succeeded, info.GetIsolate(), exceptionState);
    117     if (!succeeded)
    118         return;
    119     ASSERT(positionCallback);
    120 
    121     // Argument is optional (hence undefined is allowed), and null is allowed.
    122     OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], 2, succeeded, info.GetIsolate(), exceptionState, CallbackAllowUndefined | CallbackAllowNull);
    123     if (!succeeded)
    124         return;
    125 
    126     PositionOptions* positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded, exceptionState);
    127     if (!succeeded)
    128         return;
    129     ASSERT(positionOptions);
    130 
    131     Geolocation* geolocation = V8Geolocation::toNative(info.Holder());
    132     geolocation->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions);
    133 }
    134 
    135 void V8Geolocation::watchPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    136 {
    137     bool succeeded = false;
    138 
    139     ExceptionState exceptionState(ExceptionState::ExecutionContext, "watchCurrentPosition", "Geolocation", info.Holder(), info.GetIsolate());
    140 
    141     OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], 1, succeeded, info.GetIsolate(), exceptionState);
    142     if (!succeeded)
    143         return;
    144     ASSERT(positionCallback);
    145 
    146     // Argument is optional (hence undefined is allowed), and null is allowed.
    147     OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], 2, succeeded, info.GetIsolate(), exceptionState, CallbackAllowUndefined | CallbackAllowNull);
    148     if (!succeeded)
    149         return;
    150 
    151     PositionOptions* positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded, exceptionState);
    152     if (!succeeded)
    153         return;
    154     ASSERT(positionOptions);
    155 
    156     Geolocation* geolocation = V8Geolocation::toNative(info.Holder());
    157     int watchId = geolocation->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions);
    158     v8SetReturnValue(info, watchId);
    159 }
    160 
    161 } // namespace WebCore
    162