1 // A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API
2 if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) (function(){
6 // We are already defined. Hooray!
7 if (window.google && google.gears) {
14 if (typeof GearsFactory != 'undefined') {
15 factory = new GearsFactory();
19 factory = new ActiveXObject('Gears.Factory');
20 // privateSetGlobalObject is only required and supported on WinCE.
21 if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
22 factory.privateSetGlobalObject(this);
26 if ((typeof navigator.mimeTypes != 'undefined')
27 && navigator.mimeTypes["application/x-googlegears"]) {
28 factory = document.createElement("object");
29 factory.style.display = "none";
32 factory.type = "application/x-googlegears";
33 document.documentElement.appendChild(factory);
38 // *Do not* define any objects if Gears is not installed. This mimics the
39 // behavior of Gears defining the objects in the future.
44 // Now set up the objects, being careful not to overwrite anything.
46 // Note: In Internet Explorer for Windows Mobile, you can't add properties to
47 // the window object. However, global objects are automatically added as
48 // properties of the window object in all browsers.
54 google.gears = {factory: factory};
59 var GearsGeoLocation = (function() {
61 var geo = google.gears.factory.create('beta.geolocation');
63 var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
64 return function(position) {
66 self.lastPosition = position;
78 getCurrentPosition: function(successCallback, errorCallback, options) {
80 var sc = wrapSuccess(successCallback, self);
81 geo.getCurrentPosition(sc, errorCallback, options);
84 watchPosition: function(successCallback, errorCallback, options) {
85 geo.watchPosition(successCallback, errorCallback, options);
88 clearWatch: function(watchId) {
89 geo.clearWatch(watchId);
92 getPermission: function(siteName, imageUrl, extraMessage) {
93 geo.getPermission(siteName, imageUrl, extraMessage);
99 var AjaxGeoLocation = (function() {
102 var loadGoogleLoader = function() {
103 if (!hasGoogleLoader() && !loading) {
105 var s = document.createElement('script');
106 s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
107 s.type = "text/javascript";
108 document.getElementsByTagName('body')[0].appendChild(s);
113 var addLocationQueue = function(callback) {
114 queue.push(callback);
117 var runLocationQueue = function() {
118 if (hasGoogleLoader()) {
119 while (queue.length > 0) {
120 var call = queue.pop();
126 window['_google_loader_apiLoaded'] = function() {
130 var hasGoogleLoader = function() {
131 return (window['google'] && google['loader']);
134 var checkGoogleLoader = function(callback) {
135 if (hasGoogleLoader()) return true;
137 addLocationQueue(callback);
144 loadGoogleLoader(); // start to load as soon as possible just in case
150 type: "ClientLocation",
154 getCurrentPosition: function(successCallback, errorCallback, options) {
156 if (!checkGoogleLoader(function() {
157 self.getCurrentPosition(successCallback, errorCallback, options);
160 if (google.loader.ClientLocation) {
161 var cl = google.loader.ClientLocation;
165 latitude: cl.latitude,
166 longitude: cl.longitude,
168 accuracy: 43000, // same as Gears accuracy over wifi?
169 altitudeAccuracy: null,
173 // extra info that is outside of the bounds of the core API
175 city: cl.address.city,
176 country: cl.address.country,
177 country_code: cl.address.country_code,
178 region: cl.address.region
180 timestamp: new Date()
183 successCallback(position);
185 this.lastPosition = position;
186 } else if (errorCallback === "function") {
187 errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
191 watchPosition: function(successCallback, errorCallback, options) {
192 this.getCurrentPosition(successCallback, errorCallback, options);
195 var watchId = setInterval(function() {
196 self.getCurrentPosition(successCallback, errorCallback, options);
202 clearWatch: function(watchId) {
203 clearInterval(watchId);
206 getPermission: function(siteName, imageUrl, extraMessage) {
207 // for now just say yes :)
214 // If you have Gears installed use that, else use Ajax ClientLocation
215 navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();