зеркало из https://github.com/mozilla/pjs.git
Bug 459893. Geolocation prompt stops working if initializer window is closed. r=smaug/gavin. relanding with leak in tests fixed
This commit is contained in:
Родитель
b01fc785a9
Коммит
295cfaa5ec
|
@ -1052,61 +1052,6 @@ function prepareForStartup() {
|
|||
gGestureSupport.init(true);
|
||||
}
|
||||
|
||||
function setupGeolocationPrompt()
|
||||
{
|
||||
var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
|
||||
|
||||
if (geolocationService.prompt)
|
||||
return;
|
||||
|
||||
geolocationService.prompt = function(request) {
|
||||
|
||||
function getChromeWindow(aWindow) {
|
||||
var chromeWin = aWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
return chromeWin;
|
||||
}
|
||||
|
||||
var requestingWindow = request.requestingWindow.top;
|
||||
var tabbrowser = getChromeWindow(requestingWindow).wrappedJSObject.gBrowser;
|
||||
var browser = tabbrowser.getBrowserForDocument(requestingWindow.document);
|
||||
var notificationBox = tabbrowser.getNotificationBox(browser);
|
||||
|
||||
var notification = notificationBox.getNotificationWithValue("geolocation");
|
||||
if (!notification) {
|
||||
|
||||
var buttons = [{
|
||||
label: gNavigatorBundle.getString("geolocation.exactLocation"),
|
||||
accessKey: gNavigatorBundle.getString("geolocation.exactLocationKey"),
|
||||
callback: function() request.allow() ,
|
||||
},
|
||||
{
|
||||
label: gNavigatorBundle.getString("geolocation.neighborhoodLocation"),
|
||||
accessKey: gNavigatorBundle.getString("geolocation.neighborhoodLocationKey"),
|
||||
callback: function() request.allowButFuzz() ,
|
||||
},
|
||||
{
|
||||
label: gNavigatorBundle.getString("geolocation.nothingLocation"),
|
||||
accessKey: gNavigatorBundle.getString("geolocation.nothingLocationKey"),
|
||||
callback: function() request.cancel() ,
|
||||
}];
|
||||
|
||||
var message = gNavigatorBundle.getFormattedString("geolocation.requestMessage", [request.requestingURI.spec]);
|
||||
notificationBox.appendNotification(message,
|
||||
"geolocation",
|
||||
"chrome://browser/skin/Info.png",
|
||||
notificationBox.PRIORITY_INFO_HIGH,
|
||||
buttons);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
|
||||
|
@ -1302,9 +1247,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
|||
placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
|
||||
#endif
|
||||
|
||||
// hook up the geolocation prompt to our notificationBox
|
||||
setupGeolocationPrompt();
|
||||
|
||||
}
|
||||
|
||||
function BrowserShutdown()
|
||||
|
|
|
@ -784,7 +784,68 @@ BrowserGlue.prototype = {
|
|||
]
|
||||
}
|
||||
|
||||
function GeolocationPrompt() {}
|
||||
|
||||
GeolocationPrompt.prototype = {
|
||||
classDescription: "Geolocation Prompting Component",
|
||||
classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"),
|
||||
contractID: "@mozilla.org/geolocation/prompt;1",
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationPrompt]),
|
||||
|
||||
prompt: function(request) {
|
||||
|
||||
function getChromeWindow(aWindow) {
|
||||
var chromeWin = aWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
return chromeWin;
|
||||
}
|
||||
|
||||
var requestingWindow = request.requestingWindow.top;
|
||||
var tabbrowser = getChromeWindow(requestingWindow).wrappedJSObject.gBrowser;
|
||||
var browser = tabbrowser.getBrowserForDocument(requestingWindow.document);
|
||||
var notificationBox = tabbrowser.getNotificationBox(browser);
|
||||
|
||||
var notification = notificationBox.getNotificationWithValue("geolocation");
|
||||
if (!notification) {
|
||||
var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
|
||||
var browserBundle = bundleService.createBundle("chrome://browser/locale/browser.properties");
|
||||
|
||||
var buttons = [{
|
||||
label: browserBundle.GetStringFromName("geolocation.exactLocation"),
|
||||
accessKey: browserBundle.GetStringFromName("geolocation.exactLocationKey"),
|
||||
callback: function() request.allow() ,
|
||||
},
|
||||
{
|
||||
label: browserBundle.GetStringFromName("geolocation.neighborhoodLocation"),
|
||||
accessKey: browserBundle.GetStringFromName("geolocation.neighborhoodLocationKey"),
|
||||
callback: function() request.allowButFuzz() ,
|
||||
},
|
||||
{
|
||||
label: browserBundle.GetStringFromName("geolocation.nothingLocation"),
|
||||
accessKey: browserBundle.GetStringFromName("geolocation.nothingLocationKey"),
|
||||
callback: function() request.cancel() ,
|
||||
}];
|
||||
|
||||
var message = browserBundle.formatStringFromName("geolocation.requestMessage",
|
||||
[request.requestingURI.spec], 1);
|
||||
notificationBox.appendNotification(message,
|
||||
"geolocation",
|
||||
"chrome://browser/skin/Info.png",
|
||||
notificationBox.PRIORITY_INFO_HIGH,
|
||||
buttons);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
//module initialization
|
||||
function NSGetModule(aCompMgr, aFileSpec) {
|
||||
return XPCOMUtils.generateModule([BrowserGlue]);
|
||||
return XPCOMUtils.generateModule([BrowserGlue, GeolocationPrompt]);
|
||||
}
|
||||
|
|
|
@ -43,14 +43,6 @@ interface nsIDOMWindow;
|
|||
interface nsIDOMGeoPosition;
|
||||
interface nsIGeolocationPrompt;
|
||||
|
||||
/**
|
||||
* nsIGeolocationService
|
||||
*/
|
||||
[scriptable, uuid(68300FFD-802C-431B-BF92-0A657696B853)]
|
||||
interface nsIGeolocationService : nsISupports {
|
||||
attribute nsIGeolocationPrompt prompt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface allows access to a geolocation and is passed to
|
||||
* the nsIGeolocationPrompt so that the application can approve
|
||||
|
@ -136,6 +128,15 @@ interface nsIGeolocationProvider : nsISupports {
|
|||
};
|
||||
|
||||
%{C++
|
||||
#define NS_GEOLOCATION_SERVICE_CONTRACTID "@mozilla.org/geolocation/service;1"
|
||||
/*
|
||||
This must be implemented by geolocation providers. It
|
||||
must support nsIGeolocationProvider.
|
||||
*/
|
||||
#define NS_GEOLOCATION_PROVIDER_CONTRACTID "@mozilla.org/geolocation/provider;1"
|
||||
|
||||
/*
|
||||
This must be implemented by embedders. It must support
|
||||
nsIGeolocationPrompt.
|
||||
*/
|
||||
#define NS_GEOLOCATION_PROMPT_CONTRACTID "@mozilla.org/geolocation/prompt;1"
|
||||
%}
|
||||
|
|
|
@ -395,7 +395,6 @@ nsGeoPosition::GetTimestamp(DOMTimeStamp* aTimestamp)
|
|||
NS_INTERFACE_MAP_BEGIN(nsGeolocationService)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGeolocationUpdate)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIGeolocationUpdate)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIGeolocationService)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -433,8 +432,6 @@ nsGeolocationService::Observe(nsISupports* aSubject,
|
|||
|
||||
StopDevice();
|
||||
|
||||
// Remove our reference to any prompt that may have been set.
|
||||
mPrompt = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -457,22 +454,6 @@ nsGeolocationService::Observe(nsISupports* aSubject,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::GetPrompt(nsIGeolocationPrompt * *aPrompt)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrompt);
|
||||
*aPrompt = mPrompt;
|
||||
NS_IF_ADDREF(*aPrompt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::SetPrompt(nsIGeolocationPrompt * aPrompt)
|
||||
{
|
||||
mPrompt = aPrompt;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
|
||||
{
|
||||
|
@ -719,7 +700,8 @@ nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
|
|||
nsIDOMGeoPositionErrorCallback *errorCallback,
|
||||
nsIDOMGeoPositionOptions *options)
|
||||
{
|
||||
nsIGeolocationPrompt* prompt = mService->GetPrompt();
|
||||
|
||||
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
|
||||
if (prompt == nsnull)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
@ -740,7 +722,7 @@ nsGeolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback,
|
|||
nsIDOMGeoPositionOptions *aOptions,
|
||||
PRUint16 *_retval NS_OUTPARAM)
|
||||
{
|
||||
nsIGeolocationPrompt* prompt = mService->GetPrompt();
|
||||
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
|
||||
if (prompt == nsnull)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ private:
|
|||
/**
|
||||
* Singleton that manages the geolocation provider
|
||||
*/
|
||||
class nsGeolocationService : public nsIGeolocationService, public nsIGeolocationUpdate, public nsIObserver
|
||||
class nsGeolocationService : public nsIGeolocationUpdate, public nsIObserver
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -131,7 +131,6 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIGEOLOCATIONUPDATE
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIGEOLOCATIONSERVICE
|
||||
|
||||
nsGeolocationService();
|
||||
|
||||
|
@ -142,9 +141,6 @@ public:
|
|||
// Returns the last geolocation we have seen since calling StartDevice()
|
||||
already_AddRefed<nsIDOMGeoPosition> GetLastKnownPosition();
|
||||
|
||||
// Returns the application defined UI prompt
|
||||
nsIGeolocationPrompt* GetPrompt() { return mPrompt; } // does not addref.
|
||||
|
||||
// Returns true if the we have successfully found and started a
|
||||
// geolocation device
|
||||
PRBool IsDeviceReady();
|
||||
|
@ -177,9 +173,6 @@ private:
|
|||
// addes them to this list, and their destructor removes
|
||||
// them from this list.
|
||||
nsTArray<nsGeolocation*> mGeolocators;
|
||||
|
||||
// prompt callback, if any
|
||||
nsCOMPtr<nsIGeolocationPrompt> mPrompt;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -107,21 +107,46 @@ function delayed_prompt(request) {
|
|||
setTimeout(geolocation_prompt, prompt_delay, request);
|
||||
}
|
||||
|
||||
var TestPromptFactory = {
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) || iid.equals(Components.interfaces.nsIFactory))
|
||||
return this;
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
createInstance: function(outer, iid) {
|
||||
if (outer)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
if(DELAYED_PROMPT)
|
||||
return delayed_prompt;
|
||||
else
|
||||
return geolocation_prompt;
|
||||
},
|
||||
|
||||
lockFactory: function(lock) {
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
};
|
||||
|
||||
function attachPrompt() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var geolocationService = Components.classes["@mozilla.org/geolocation/service;1"]
|
||||
.getService(Components.interfaces.nsIGeolocationService);
|
||||
old_prompt = geolocationService.prompt;
|
||||
old_prompt = Components.manager.nsIComponentRegistrar.contractIDToCID("@mozilla.org/geolocation/prompt;1");
|
||||
old_factory = Components.manager.getClassObjectByContractID("@mozilla.org/geolocation/prompt;1", Components.interfaces.nsIFactory)
|
||||
|
||||
if(DELAYED_PROMPT)
|
||||
geolocationService.prompt = delayed_prompt;
|
||||
else
|
||||
geolocationService.prompt = geolocation_prompt;
|
||||
const testing_prompt_cid = Components.ID("{20C27ECF-A22E-4022-9757-2CFDA88EAEAA}");
|
||||
Components.manager.nsIComponentRegistrar.registerFactory(testing_prompt_cid,
|
||||
"Test Geolocation Prompt",
|
||||
"@mozilla.org/geolocation/prompt;1",
|
||||
TestPromptFactory);
|
||||
}
|
||||
|
||||
function removePrompt() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var geolocationService = Components.classes["@mozilla.org/geolocation/service;1"]
|
||||
.getService(Components.interfaces.nsIGeolocationService);
|
||||
geolocationService.prompt = old_prompt;
|
||||
const testing_prompt_cid = Components.ID("{20C27ECF-A22E-4022-9757-2CFDA88EAEAA}");
|
||||
Components.manager.nsIComponentRegistrar.unregisterFactory(testing_prompt_cid, TestPromptFactory);
|
||||
Components.manager.nsIComponentRegistrar.registerFactory(old_prompt,
|
||||
"Geolocation Prompt restored!",
|
||||
"@mozilla.org/geolocation/prompt;1",
|
||||
old_factory);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче