summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-08-11 13:09:00 +0100
committerSteve Block <steveblock@google.com>2009-08-11 16:53:47 +0100
commit6453d21822fbf87a3fec6a6351a56933d2d9d730 (patch)
tree9ad6420777eff5fd9d62e3e437d5f3d4946172d3
parent97ad1840093def16a278af16f603f3d308b761d7 (diff)
downloadexternal_webkit-6453d21822fbf87a3fec6a6351a56933d2d9d730.zip
external_webkit-6453d21822fbf87a3fec6a6351a56933d2d9d730.tar.gz
external_webkit-6453d21822fbf87a3fec6a6351a56933d2d9d730.tar.bz2
Correctly sets default values for Geolocation PositionOptions.
This will be submitted to WebKit in bug 27254. This was first commited in change 20268, but this caused problems in the automated build and was subsequently rolled back in change 20415. This change includes the latest comments from the WebKit review.
-rw-r--r--WebCore/bindings/js/JSGeolocationCustom.cpp150
-rw-r--r--WebCore/page/Geolocation.cpp6
-rw-r--r--WebCore/page/PositionOptions.h33
3 files changed, 105 insertions, 84 deletions
diff --git a/WebCore/bindings/js/JSGeolocationCustom.cpp b/WebCore/bindings/js/JSGeolocationCustom.cpp
index 493166c..7636a44 100644
--- a/WebCore/bindings/js/JSGeolocationCustom.cpp
+++ b/WebCore/bindings/js/JSGeolocationCustom.cpp
@@ -39,109 +39,115 @@ using namespace JSC;
namespace WebCore {
-static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValue value)
+static PassRefPtr<PositionCallback> createPositionCallback(ExecState* exec, JSValue value)
{
- if (!value.isObject())
+ // FIXME: We should check that the argument is a Function object, as
+ // the spec specifies 'FunctionOnly'.
+ JSObject* object = value.getObject();
+ if (!object) {
+ setDOMException(exec, TYPE_MISMATCH_ERR);
return 0;
+ }
- JSObject* object = asObject(value);
+ Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame();
+ return JSCustomPositionCallback::create(object, frame);
+}
- JSValue enableHighAccuracyValue = object->get(exec, Identifier(exec, "enableHighAccuracy"));
- if (exec->hadException())
+static PassRefPtr<PositionErrorCallback> createPositionErrorCallback(ExecState* exec, JSValue value)
+{
+ // Argument is optional, and null is allowed.
+ if (value.isUndefinedOrNull())
return 0;
- bool enableHighAccuracy = enableHighAccuracyValue.toBoolean(exec);
- if (exec->hadException())
+
+ // FIXME: We should check that the argument is a Function object, as
+ // the spec specifies 'FunctionOnly'.
+ JSObject* object = value.getObject();
+ if (!object) {
+ setDOMException(exec, TYPE_MISMATCH_ERR);
return 0;
+ }
+
+ Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame();
+ return JSCustomPositionErrorCallback::create(object, frame);
+}
+
+static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValue value)
+{
+ // Create default options.
+ RefPtr<PositionOptions> options = PositionOptions::create();
+
+ // Argument is optional, and null is allowed.
+ if (value.isUndefinedOrNull()) {
+ // Use default options.
+ return options.release();
+ }
+
+ // This will always yield an object.
+ JSObject* object = value.toObject(exec);
+
+ JSValue enableHighAccuracyValue = object->get(exec, Identifier(exec, "enableHighAccuracy"));
+ // If undefined, don't override default.
+ if (!enableHighAccuracyValue.isUndefined())
+ options->setEnableHighAccuracy(enableHighAccuracyValue.toBoolean(exec));
JSValue timeoutValue = object->get(exec, Identifier(exec, "timeout"));
- if (exec->hadException())
- return 0;
- unsigned timeout = timeoutValue.toUInt32(exec);
- if (exec->hadException())
- return 0;
+ // If undefined, don't override default.
+ if (!timeoutValue.isUndefined()) {
+ // Wrap to int32 and force non-negative to match behavior of window.setTimeout.
+ int timeout = timeoutValue.toInt32(exec);
+ options->setTimeout(timeout >= 0 ? timeout : 0);
+ }
JSValue maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge"));
- if (exec->hadException())
- return 0;
- unsigned maximumAge = maximumAgeValue.toUInt32(exec);
- if (exec->hadException())
- return 0;
+ // If undefined, don't override default.
+ if (!maximumAgeValue.isUndefined()) {
+ // Wrap to int32 and force non-negative to match behavior of window.setTimeout.
+ int maximumAge = maximumAgeValue.toInt32(exec);
+ options->setTimeout(maximumAge >= 0 ? maximumAge : 0);
+ }
- return PositionOptions::create(enableHighAccuracy, timeout, maximumAge);
+ return options.release();
}
JSValue JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& args)
{
// Arguments: PositionCallback, (optional)PositionErrorCallback, (optional)PositionOptions
- RefPtr<PositionCallback> positionCallback;
- JSObject* object = args.at(0).getObject();
+
+ RefPtr<PositionCallback> positionCallback = createPositionCallback(exec, args.at(0));
if (exec->hadException())
return jsUndefined();
- if (!object) {
- setDOMException(exec, TYPE_MISMATCH_ERR);
+ ASSERT(positionCallback);
+
+ RefPtr<PositionErrorCallback> positionErrorCallback = createPositionErrorCallback(exec, args.at(1));
+ if (exec->hadException())
return jsUndefined();
- }
- if (Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame())
- positionCallback = JSCustomPositionCallback::create(object, frame);
-
- RefPtr<PositionErrorCallback> positionErrorCallback;
- if (!args.at(1).isUndefinedOrNull()) {
- JSObject* object = args.at(1).getObject();
- if (!object) {
- setDOMException(exec, TYPE_MISMATCH_ERR);
- return jsUndefined();
- }
-
- if (Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame())
- positionErrorCallback = JSCustomPositionErrorCallback::create(object, frame);
- }
-
- RefPtr<PositionOptions> positionOptions;
- if (!args.at(2).isUndefinedOrNull()) {
- positionOptions = createPositionOptions(exec, args.at(2));
- if (exec->hadException())
- return jsUndefined();
- }
+ RefPtr<PositionOptions> positionOptions = createPositionOptions(exec, args.at(2));
+ if (exec->hadException())
+ return jsUndefined();
+ ASSERT(positionOptions);
m_impl->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release());
-
return jsUndefined();
}
JSValue JSGeolocation::watchPosition(ExecState* exec, const ArgList& args)
{
// Arguments: PositionCallback, (optional)PositionErrorCallback, (optional)PositionOptions
- RefPtr<PositionCallback> positionCallback;
- JSObject* object = args.at(0).getObject();
+
+ RefPtr<PositionCallback> positionCallback = createPositionCallback(exec, args.at(0));
if (exec->hadException())
return jsUndefined();
- if (!object) {
- setDOMException(exec, TYPE_MISMATCH_ERR);
+ ASSERT(positionCallback);
+
+ RefPtr<PositionErrorCallback> positionErrorCallback = createPositionErrorCallback(exec, args.at(1));
+ if (exec->hadException())
return jsUndefined();
- }
-
- if (Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame())
- positionCallback = JSCustomPositionCallback::create(object, frame);
-
- RefPtr<PositionErrorCallback> positionErrorCallback;
- if (!args.at(1).isUndefinedOrNull()) {
- JSObject* object = args.at(1).getObject();
- if (!object) {
- setDOMException(exec, TYPE_MISMATCH_ERR);
- return jsUndefined();
- }
-
- if (Frame* frame = toJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame())
- positionErrorCallback = JSCustomPositionErrorCallback::create(object, frame);
- }
-
- RefPtr<PositionOptions> positionOptions;
- if (!args.at(2).isUndefinedOrNull()) {
- positionOptions = createPositionOptions(exec, args.at(2));
- if (exec->hadException())
- return jsUndefined();
- }
+
+ RefPtr<PositionOptions> positionOptions = createPositionOptions(exec, args.at(2));
+ if (exec->hadException())
+ return jsUndefined();
+ ASSERT(positionOptions);
int watchID = m_impl->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release());
return jsNumber(exec, watchID);
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 7010339..fd429c4 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -40,11 +40,15 @@ Geolocation::GeoNotifier::GeoNotifier(PassRefPtr<PositionCallback> successCallba
, m_options(options)
, m_timer(this, &Geolocation::GeoNotifier::timerFired)
{
+ ASSERT(m_successCallback);
+ // If no options were supplied from JS, we should have created a default set
+ // of options in JSGeolocationCustom.cpp.
+ ASSERT(m_options);
}
void Geolocation::GeoNotifier::startTimer()
{
- if (m_errorCallback && m_options)
+ if (m_errorCallback && m_options->hasTimeout())
m_timer.startOneShot(m_options->timeout() / 1000.0);
}
diff --git a/WebCore/page/PositionOptions.h b/WebCore/page/PositionOptions.h
index 10845d3..d714902 100644
--- a/WebCore/page/PositionOptions.h
+++ b/WebCore/page/PositionOptions.h
@@ -33,26 +33,37 @@ namespace WebCore {
class PositionOptions : public RefCounted<PositionOptions> {
public:
- static PassRefPtr<PositionOptions> create(bool highAccuracy, unsigned timeout, unsigned maximumAge) { return adoptRef(new PositionOptions(highAccuracy, timeout, maximumAge)); }
+ static PassRefPtr<PositionOptions> create() { return adoptRef(new PositionOptions()); }
bool enableHighAccuracy() const { return m_highAccuracy; }
void setEnableHighAccuracy(bool enable) { m_highAccuracy = enable; }
- unsigned timeout() const { return m_timeout; }
- void setTimeout(unsigned t) { m_timeout = t; }
- unsigned maximumAge() const { return m_maximumAge; }
- void setMaximumAge(unsigned a) { m_maximumAge = a; }
+ bool hasTimeout() { return m_hasTimeout; }
+ int timeout() const { return m_timeout; }
+ void setTimeout(int t)
+ {
+ ASSERT(t >= 0);
+ m_hasTimeout = true;
+ m_timeout = t;
+ }
+ int maximumAge() const { return m_maximumAge; }
+ void setMaximumAge(int a)
+ {
+ ASSERT(a >= 0);
+ m_maximumAge = a;
+ }
private:
- PositionOptions(bool highAccuracy, unsigned timeout, unsigned maximumAge)
- : m_highAccuracy(highAccuracy)
- , m_timeout(timeout)
- , m_maximumAge(maximumAge)
+ PositionOptions()
+ : m_highAccuracy(false)
+ , m_hasTimeout(false)
+ , m_maximumAge(0)
{
}
bool m_highAccuracy;
- unsigned m_timeout;
- unsigned m_maximumAge;
+ bool m_hasTimeout;
+ int m_timeout;
+ int m_maximumAge;
};
} // namespace WebCore