diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index e30bc519a4ab..ef1031c6cddc 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -910,61 +910,6 @@ function prepareForStartup() { gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false); } -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); @@ -1160,9 +1105,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) { placesContext.addEventListener("popuphiding", updateEditUIVisibility, false); #endif - // hook up the geolocation prompt to our notificationBox - setupGeolocationPrompt(); - } function BrowserShutdown() diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 5b89921a778f..0f3aef219ce5 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -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]); } diff --git a/dom/public/idl/geolocation/nsIGeolocationProvider.idl b/dom/public/idl/geolocation/nsIGeolocationProvider.idl index 432603ece872..5096cab6fd7e 100644 --- a/dom/public/idl/geolocation/nsIGeolocationProvider.idl +++ b/dom/public/idl/geolocation/nsIGeolocationProvider.idl @@ -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" %} diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp index eaa8ff8c3cc8..0ffd4906a0bd 100644 --- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -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 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 prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID); if (prompt == nsnull) return NS_ERROR_NOT_AVAILABLE; diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h index 2267688bf3de..df62de2975a1 100644 --- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -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 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 mGeolocators; - - // prompt callback, if any - nsCOMPtr mPrompt; }; diff --git a/dom/tests/mochitest/geolocation/geolocation_common.js b/dom/tests/mochitest/geolocation/geolocation_common.js index f1b58b8bee97..417192228581 100644 --- a/dom/tests/mochitest/geolocation/geolocation_common.js +++ b/dom/tests/mochitest/geolocation/geolocation_common.js @@ -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; + + Components.manager.nsIComponentRegistrar.registerFactory(old_prompt, + "Geolocation Prompt restored!", + "@mozilla.org/geolocation/prompt;1", + old_factory); }