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') && navigator.mimeTypes["application/x-googlegears"]) {
27 factory = document.createElement("object");
28 factory.style.display = "none";
31 factory.type = "application/x-googlegears";
32 document.documentElement.appendChild(factory);
37 // *Do not* define any objects if Gears is not installed. This mimics the
38 // behavior of Gears defining the objects in the future.
43 // Now set up the objects, being careful not to overwrite anything.
45 // Note: In Internet Explorer for Windows Mobile, you can't add properties to
46 // the window object. However, global objects are automatically added as
47 // properties of the window object in all browsers.
53 google.gears = {factory: factory};
58 var GearsGeoLocation = (function() {
60 var geo = google.gears.factory.create('beta.geolocation');
62 var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
63 return function(position) {
65 self.lastPosition = position;
77 getCurrentPosition: function(successCallback, errorCallback, options) {
79 var sc = wrapSuccess(successCallback, self);
80 geo.getCurrentPosition(sc, errorCallback, options);
83 watchPosition: function(successCallback, errorCallback, options) {
84 geo.watchPosition(successCallback, errorCallback, options);
87 clearWatch: function(watchId) {
88 geo.clearWatch(watchId);
91 getPermission: function(siteName, imageUrl, extraMessage) {
92 geo.getPermission(siteName, imageUrl, extraMessage);
98 var AjaxGeoLocation = (function() {
101 var loadGoogleLoader = function() {
102 if (!hasGoogleLoader() && !loading) {
104 var s = document.createElement('script');
105 s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
106 s.type = "text/javascript";
107 document.getElementsByTagName('body')[0].appendChild(s);
112 var addLocationQueue = function(callback) {
113 queue.push(callback);
116 var runLocationQueue = function() {
117 if (hasGoogleLoader()) {
118 while (queue.length > 0) {
119 var call = queue.pop();
125 window['_google_loader_apiLoaded'] = function() {
129 var hasGoogleLoader = function() {
130 return (window['google'] && google['loader']);
133 var checkGoogleLoader = function(callback) {
134 if (hasGoogleLoader()) { return true; }
136 addLocationQueue(callback);
143 loadGoogleLoader(); // start to load as soon as possible just in case
149 type: "ClientLocation",
153 getCurrentPosition: function(successCallback, errorCallback, options) {
155 if (!checkGoogleLoader(function() {
156 self.getCurrentPosition(successCallback, errorCallback, options);
159 if (google.loader.ClientLocation) {
160 var cl = google.loader.ClientLocation;
164 latitude: cl.latitude,
165 longitude: cl.longitude,
167 accuracy: 43000, // same as Gears accuracy over wifi?
168 altitudeAccuracy: null,
172 // extra info that is outside of the bounds of the core API
174 city: cl.address.city,
175 country: cl.address.country,
176 country_code: cl.address.country_code,
177 region: cl.address.region
179 timestamp: new Date()
182 successCallback(position);
184 this.lastPosition = position;
185 } else if (errorCallback === "function") {
186 errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
190 watchPosition: function(successCallback, errorCallback, options) {
191 this.getCurrentPosition(successCallback, errorCallback, options);
194 var watchId = setInterval(function() {
195 self.getCurrentPosition(successCallback, errorCallback, options);
201 clearWatch: function(watchId) {
202 clearInterval(watchId);
205 getPermission: function(siteName, imageUrl, extraMessage) {
206 // for now just say yes :)
213 // If you have Gears installed use that, else use Ajax ClientLocation
214 navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();