mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 493615 - Allow Addons to use the DOM Geolocation API. r=smaug
--HG-- extra : rebase_source : a48f85c5940252a87bfef879663b2d50daed5686
This commit is contained in:
parent
f91be4b13e
commit
172e2f77f5
@ -9913,12 +9913,27 @@ nsNavigator::MozIsLocallyAvailable(const nsAString &aURI,
|
||||
NS_IMETHODIMP nsNavigator::GetGeolocation(nsIDOMGeoGeolocation **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nsnull;
|
||||
|
||||
if (!mGeolocation && mDocShell) {
|
||||
nsCOMPtr<nsIDOMWindow> contentDOMWindow(do_GetInterface(mDocShell));
|
||||
mGeolocation = new nsGeolocation(contentDOMWindow);
|
||||
if (mGeolocation) {
|
||||
NS_ADDREF(*_retval = mGeolocation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*_retval = mGeolocation);
|
||||
return NS_OK;
|
||||
if (!mDocShell)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> contentDOMWindow(do_GetInterface(mDocShell));
|
||||
if (!contentDOMWindow)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mGeolocation = new nsGeolocation();
|
||||
if (!mGeolocation)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_FAILED(mGeolocation->Init(contentDOMWindow)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(*_retval = mGeolocation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -712,24 +712,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGeolocation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWatchingCallbacks[i], nsIGeolocationRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
nsGeolocation::nsGeolocation(nsIDOMWindow* aContentDom)
|
||||
nsGeolocation::nsGeolocation()
|
||||
: mUpdateInProgress(PR_FALSE)
|
||||
{
|
||||
// Remember the window
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aContentDom);
|
||||
if (window)
|
||||
mOwner = do_GetWeakReference(window->GetCurrentInnerWindow());
|
||||
|
||||
// Grab the uri of the document
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
aContentDom->GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (doc)
|
||||
doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
|
||||
|
||||
mService = nsGeolocationService::GetInstance();
|
||||
if (mService)
|
||||
mService->AddLocator(this);
|
||||
}
|
||||
|
||||
nsGeolocation::~nsGeolocation()
|
||||
@ -738,6 +723,40 @@ nsGeolocation::~nsGeolocation()
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGeolocation::Init(nsIDOMWindow* aContentDom)
|
||||
{
|
||||
// Remember the window
|
||||
if (aContentDom) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aContentDom);
|
||||
if (!window)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mOwner = do_GetWeakReference(window->GetCurrentInnerWindow());
|
||||
if (!mOwner)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Grab the uri of the document
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
aContentDom->GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (!doc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
|
||||
|
||||
if (!mURI)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// If no aContentDom was passed into us, we are being used
|
||||
// by chrome/c++ and have no mOwner, no mURI, and no need
|
||||
// to prompt.
|
||||
mService = nsGeolocationService::GetInstance();
|
||||
if (mService)
|
||||
mService->AddLocator(this);
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocation::Shutdown()
|
||||
{
|
||||
@ -791,7 +810,7 @@ nsGeolocation::Update(nsIDOMGeoPosition *aSomewhere)
|
||||
|
||||
mUpdateInProgress = PR_TRUE;
|
||||
|
||||
if (!OwnerStillExists())
|
||||
if (!WindowOwnerStillExists())
|
||||
{
|
||||
Shutdown();
|
||||
return;
|
||||
@ -819,8 +838,48 @@ nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
|
||||
if (sGeoEnabled == PR_FALSE)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
|
||||
if (prompt == nsnull)
|
||||
if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsRefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this, callback, errorCallback, options);
|
||||
if (!request)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_FAILED(request->Init()))
|
||||
return NS_ERROR_FAILURE; // this as OKAY. not sure why we wouldn't throw. xxx dft
|
||||
|
||||
if (mOwner) {
|
||||
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
|
||||
if (prompt == nsnull)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
prompt->Prompt(request);
|
||||
|
||||
mPendingCallbacks.AppendElement(request);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsCallerChrome())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
request->Allow();
|
||||
|
||||
mPendingCallbacks.AppendElement(request);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocation::WatchPosition(nsIDOMGeoPositionCallback *callback,
|
||||
nsIDOMGeoPositionErrorCallback *errorCallback,
|
||||
nsIDOMGeoPositionOptions *options,
|
||||
PRInt32 *_retval NS_OUTPARAM)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(callback);
|
||||
|
||||
if (sGeoEnabled == PR_FALSE)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW)
|
||||
@ -831,45 +890,31 @@ nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_FAILED(request->Init()))
|
||||
return NS_ERROR_FAILURE; // this as OKAY. not sure why we wouldn't throw. xxx dft
|
||||
|
||||
if (mOwner) {
|
||||
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
|
||||
if (prompt == nsnull)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
prompt->Prompt(request);
|
||||
|
||||
// need to hand back an index/reference.
|
||||
mWatchingCallbacks.AppendElement(request);
|
||||
*_retval = mWatchingCallbacks.Length() - 1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
prompt->Prompt(request);
|
||||
if (!nsContentUtils::IsCallerChrome())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// What if you have a location provider that only sends a location once, then stops.? fix.
|
||||
mPendingCallbacks.AppendElement(request);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback,
|
||||
nsIDOMGeoPositionErrorCallback *aErrorCallback,
|
||||
nsIDOMGeoPositionOptions *aOptions,
|
||||
PRInt32 *_retval NS_OUTPARAM)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
|
||||
if (sGeoEnabled == PR_FALSE)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
|
||||
if (prompt == nsnull)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsRefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this, aCallback, aErrorCallback, aOptions);
|
||||
if (!request)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_FAILED(request->Init()))
|
||||
return NS_OK;
|
||||
|
||||
prompt->Prompt(request);
|
||||
request->Allow();
|
||||
|
||||
// need to hand back an index/reference.
|
||||
mWatchingCallbacks.AppendElement(request);
|
||||
*_retval = mWatchingCallbacks.Length() - 1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -885,12 +930,15 @@ nsGeolocation::ClearWatch(PRInt32 aWatchId)
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGeolocation::OwnerStillExists()
|
||||
nsGeolocation::WindowOwnerStillExists()
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mOwner);
|
||||
// an owner was never set when nsGeolocation
|
||||
// was created, which means that this object
|
||||
// is being used without a window.
|
||||
if (mOwner == nsnull)
|
||||
return PR_TRUE;
|
||||
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mOwner);
|
||||
|
||||
if (window)
|
||||
{
|
||||
@ -898,11 +946,11 @@ nsGeolocation::OwnerStillExists()
|
||||
window->GetClosed(&closed);
|
||||
if (closed)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsPIDOMWindow* outer = window->GetOuterWindow();
|
||||
if (!outer || outer->GetCurrentInnerWindow() != window)
|
||||
return PR_FALSE;
|
||||
nsPIDOMWindow* outer = window->GetOuterWindow();
|
||||
if (!outer || outer->GetCurrentInnerWindow() != window)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -175,7 +175,9 @@ public:
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsGeolocation)
|
||||
|
||||
nsGeolocation(nsIDOMWindow* contentDom);
|
||||
nsGeolocation();
|
||||
|
||||
nsresult Init(nsIDOMWindow* contentDom=nsnull);
|
||||
|
||||
// Called by the geolocation device to notify that a location has changed.
|
||||
void Update(nsIDOMGeoPosition* aPosition);
|
||||
@ -196,7 +198,7 @@ public:
|
||||
nsIWeakReference* GetOwner() { return mOwner; }
|
||||
|
||||
// Check to see if the widnow still exists
|
||||
PRBool OwnerStillExists();
|
||||
PRBool WindowOwnerStillExists();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -59,6 +59,7 @@ _TEST_FILES = \
|
||||
test_focus.xul \
|
||||
window_focus.xul \
|
||||
test_focused_link_scroll.xul \
|
||||
test_geolocation.xul \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
39
dom/tests/mochitest/chrome/test_geolocation.xul
Normal file
39
dom/tests/mochitest/chrome/test_geolocation.xul
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
Test for Geolocation in chrome
|
||||
-->
|
||||
<window id="sample-window" width="400" height="400"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
|
||||
var geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsIDOMGeoGeolocation);
|
||||
geolocation.getCurrentPosition(done, error);
|
||||
|
||||
function error(error)
|
||||
{
|
||||
ok(0, "error occured trying to get geolocation from chrome");
|
||||
SimpleTest.finish();
|
||||
newwindow.close();
|
||||
}
|
||||
function done(position)
|
||||
{
|
||||
ok(position, "geolocation was found from chrome");
|
||||
SimpleTest.finish();
|
||||
newwindow.close();
|
||||
}
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
|
||||
|
||||
</window>
|
@ -58,6 +58,8 @@ _TEST_FILES = \
|
||||
test_clearWatch.html \
|
||||
test_clearWatch_invalid.html \
|
||||
test_timeoutWatch.html \
|
||||
test_windowClose.html \
|
||||
windowTest.html \
|
||||
geolocation_common.js \
|
||||
geolocation.html \
|
||||
test_optional_api_params.html \
|
||||
|
35
dom/tests/mochitest/geolocation/test_windowClose.html
Normal file
35
dom/tests/mochitest/geolocation/test_windowClose.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=493615
|
||||
-->
|
||||
<head>
|
||||
<title>Test for geolocation in chrome </title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="geolocation_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=493615">Mozilla Bug 493615</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function done() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.open("windowTest.html");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
40
dom/tests/mochitest/geolocation/windowTest.html
Normal file
40
dom/tests/mochitest/geolocation/windowTest.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=493615
|
||||
-->
|
||||
<head>
|
||||
<title>Test for closing a window while it is doing a geolocation request </title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="geolocation_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=493615">Mozilla Bug 493615</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function successCallback(position) {
|
||||
var opener = window.opener;
|
||||
window.close();
|
||||
opener.wrappedJSObject.done();
|
||||
}
|
||||
|
||||
function accept() {
|
||||
clickNotificationButton(kAcceptButton);
|
||||
}
|
||||
|
||||
navigator.geolocation.watchPosition(successCallback, null, null);
|
||||
setTimeout(accept, 50);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -842,6 +842,11 @@ CreateWindowControllerWithSingletonCommandTable(nsISupports *aOuter,
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMScriptObjectFactory)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBaseDOMException)
|
||||
|
||||
#define NS_GEOLOCATION_CID \
|
||||
{ 0x1E1C3FF, 0x94A, 0xD048, { 0x44, 0xB4, 0x62, 0xD2, 0x9C, 0x7B, 0x4F, 0x39 } }
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGeolocation, Init)
|
||||
|
||||
#define NS_GEOLOCATION_SERVICE_CID \
|
||||
{ 0x404d02a, 0x1CA, 0xAAAB, { 0x47, 0x62, 0x94, 0x4b, 0x1b, 0xf2, 0xf7, 0xb5 } }
|
||||
|
||||
@ -1452,6 +1457,11 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||
"@mozilla.org/geolocation/service;1",
|
||||
nsGeolocationServiceConstructor },
|
||||
|
||||
{ "Geolocation",
|
||||
NS_GEOLOCATION_CID,
|
||||
"@mozilla.org/geolocation;1",
|
||||
nsGeolocationConstructor },
|
||||
|
||||
{ "Focus Manager",
|
||||
NS_FOCUSMANAGER_CID,
|
||||
"@mozilla.org/focus-manager;1",
|
||||
|
Loading…
Reference in New Issue
Block a user