The spec is actually pretty quiet on whether or not a callback MUST be executed if the user simply dismisses the request for permission (as opposed to clicking the Deny button):
For both getCurrentPosition
and watchPosition
, the implementation must never invoke the successCallback
without having first obtained permission from the user to share location. Furthermore, the implementation should always obtain the user's permission to share location before executing any of the getCurrentPosition
or watchPosition
steps described above. If the user grants permission, the appropriate callback must be invoked as described above. If the user denies permission, the errorCallback
(if present) must be invoked with code PERMISSION_DENIED
, irrespective of any other errors encountered in the above steps. The time that is spent obtaining the user permission must not be included in the period covered by the timeout
attribute of the PositionOptions
parameter. The timeout
attribute must only apply to the location acquisition operation.
I'd say that dismissing the permission request is equivalent to denying the request from the standpoint of getCurrentPosition
. Clicking Deny is explicit whereas dismissal (clicking the X) is implicit.
Functionally, the difference is that clicking the Deny button means (1) the current request is denied, and (2) the site is blacklisted and the user will never be prompted to share location again for the site; simply dismissing the request only means that the current request is denied – future requests (in future BROWSINGCONTEXTs—after the page is reloaded) will prompt again.
In my opinion, Chrome, Firefox, and IE's current behavior is a bug – all three do nothing if the user dismisses the permission request by clicking the X. The errorCallback
should be called if the geolocation permission request is dismissed because any further calls to getCurrentLocation
in the current BROWSINGCONTEXT will silently fail. (Opera 11.52 behaves 'correctly' because its permission request UI only has Allow/Deny buttons – no X.)
Mozilla has a bug where they say the current behavior is correct and a newer bug open bug that's relevant; Chromuim also says the current behavior is correct. IE has a bug (registration required), but oddly, Microsoft closed it as non-reproducable.
This is really something that the W3C Working Group needs to address. The page should be able to react to the user declining the location permission request – whether permanently denied or just declined for this session by clicking the X.
The only thing you can actually do right now to address this situation is setting your own timeout. Set a timeout in the geolocation request, and then set your error timeout to be longer than that (to allow the user time to react to the request):
if (navigator.geolocation) {
var etimeout = setTimout(onError, 10000);
navigator.geolocation.getCurrentPosition(onSuccess, onError, {timeout:5000});
}
function onSuccess(pos) {
clearTimeout(etimeout);
// ...
}
function onError(err) {
clearTimeout(etimeout);
// Note `err` will actually be undefined if this is the result of our timeout
// and anything you do here should be undone by `onSuccess` (in case the user
// took longer than 5 seconds to approve the request; for that reason, you
// shouldn't display any modal UI from here.
// ...
}
errorCallback
(as if you clicked Deny). Firefox does nothing. – Pallor