218 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API
 | 
						|
if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) { (function(){
 | 
						|
 | 
						|
// -- BEGIN GEARS_INIT
 | 
						|
(function() {
 | 
						|
  // We are already defined. Hooray!
 | 
						|
  if (window.google && google.gears) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  var factory = null;
 | 
						|
 | 
						|
  // Firefox
 | 
						|
  if (typeof GearsFactory != 'undefined') {
 | 
						|
    factory = new GearsFactory();
 | 
						|
  } else {
 | 
						|
    // IE
 | 
						|
    try {
 | 
						|
      factory = new ActiveXObject('Gears.Factory');
 | 
						|
      // privateSetGlobalObject is only required and supported on WinCE.
 | 
						|
      if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
 | 
						|
        factory.privateSetGlobalObject(this);
 | 
						|
      }
 | 
						|
    } catch (e) {
 | 
						|
      // Safari
 | 
						|
      if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
 | 
						|
        factory = document.createElement("object");
 | 
						|
        factory.style.display = "none";
 | 
						|
        factory.width = 0;
 | 
						|
        factory.height = 0;
 | 
						|
        factory.type = "application/x-googlegears";
 | 
						|
        document.documentElement.appendChild(factory);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // *Do not* define any objects if Gears is not installed. This mimics the
 | 
						|
  // behavior of Gears defining the objects in the future.
 | 
						|
  if (!factory) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // Now set up the objects, being careful not to overwrite anything.
 | 
						|
  //
 | 
						|
  // Note: In Internet Explorer for Windows Mobile, you can't add properties to
 | 
						|
  // the window object. However, global objects are automatically added as
 | 
						|
  // properties of the window object in all browsers.
 | 
						|
  if (!window.google) {
 | 
						|
    google = {};
 | 
						|
  }
 | 
						|
 | 
						|
  if (!google.gears) {
 | 
						|
    google.gears = {factory: factory};
 | 
						|
  }
 | 
						|
})();
 | 
						|
// -- END GEARS_INIT
 | 
						|
 | 
						|
var GearsGeoLocation = (function() {
 | 
						|
    // -- PRIVATE
 | 
						|
    var geo = google.gears.factory.create('beta.geolocation');
 | 
						|
    
 | 
						|
    var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
 | 
						|
        return function(position) {
 | 
						|
            callback(position);
 | 
						|
            self.lastPosition = position;
 | 
						|
        };
 | 
						|
    };
 | 
						|
    
 | 
						|
    // -- PUBLIC
 | 
						|
    return {
 | 
						|
        shim: true,
 | 
						|
        
 | 
						|
        type: "Gears",
 | 
						|
        
 | 
						|
        lastPosition: null,
 | 
						|
        
 | 
						|
        getCurrentPosition: function(successCallback, errorCallback, options) {
 | 
						|
            var self = this;
 | 
						|
            var sc = wrapSuccess(successCallback, self);
 | 
						|
            geo.getCurrentPosition(sc, errorCallback, options);
 | 
						|
        },
 | 
						|
        
 | 
						|
        watchPosition: function(successCallback, errorCallback, options) {
 | 
						|
            geo.watchPosition(successCallback, errorCallback, options);
 | 
						|
        },
 | 
						|
        
 | 
						|
        clearWatch: function(watchId) {
 | 
						|
            geo.clearWatch(watchId);
 | 
						|
        },
 | 
						|
        
 | 
						|
        getPermission: function(siteName, imageUrl, extraMessage) {
 | 
						|
            geo.getPermission(siteName, imageUrl, extraMessage);
 | 
						|
        }
 | 
						|
 | 
						|
    };
 | 
						|
});
 | 
						|
 | 
						|
var AjaxGeoLocation = (function() {
 | 
						|
    // -- PRIVATE
 | 
						|
    var loading = false;
 | 
						|
    var loadGoogleLoader = function() {
 | 
						|
        if (!hasGoogleLoader() && !loading) {
 | 
						|
            loading = true;
 | 
						|
            var s = document.createElement('script');
 | 
						|
            s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
 | 
						|
            s.type = "text/javascript";
 | 
						|
            document.getElementsByTagName('body')[0].appendChild(s);
 | 
						|
        }
 | 
						|
    };
 | 
						|
    
 | 
						|
    var queue = [];
 | 
						|
    var addLocationQueue = function(callback) {
 | 
						|
        queue.push(callback);
 | 
						|
    };
 | 
						|
    
 | 
						|
    var runLocationQueue = function() {
 | 
						|
        if (hasGoogleLoader()) {
 | 
						|
            while (queue.length > 0) {
 | 
						|
                var call = queue.pop();
 | 
						|
                call();
 | 
						|
            }
 | 
						|
        }
 | 
						|
    };
 | 
						|
    
 | 
						|
    window['_google_loader_apiLoaded'] = function() {
 | 
						|
        runLocationQueue();
 | 
						|
    };
 | 
						|
    
 | 
						|
    var hasGoogleLoader = function() {
 | 
						|
        return (window['google'] && google['loader']);
 | 
						|
    };
 | 
						|
    
 | 
						|
    var checkGoogleLoader = function(callback) {
 | 
						|
        if (hasGoogleLoader()) { return true; }
 | 
						|
 | 
						|
        addLocationQueue(callback);
 | 
						|
                
 | 
						|
        loadGoogleLoader();
 | 
						|
        
 | 
						|
        return false;
 | 
						|
    };
 | 
						|
    
 | 
						|
    loadGoogleLoader(); // start to load as soon as possible just in case
 | 
						|
    
 | 
						|
    // -- PUBLIC
 | 
						|
    return {
 | 
						|
        shim: true,
 | 
						|
        
 | 
						|
        type: "ClientLocation",
 | 
						|
        
 | 
						|
        lastPosition: null,
 | 
						|
        
 | 
						|
        getCurrentPosition: function(successCallback, errorCallback, options) {
 | 
						|
            var self = this;
 | 
						|
            if (!checkGoogleLoader(function() {
 | 
						|
                self.getCurrentPosition(successCallback, errorCallback, options);
 | 
						|
            })) { return; }
 | 
						|
            
 | 
						|
            if (google.loader.ClientLocation) {
 | 
						|
                var cl = google.loader.ClientLocation;
 | 
						|
                
 | 
						|
                var position = {
 | 
						|
                    coords: {
 | 
						|
                        latitude: cl.latitude,
 | 
						|
                        longitude: cl.longitude,
 | 
						|
                        altitude: null,
 | 
						|
                        accuracy: 43000, // same as Gears accuracy over wifi?
 | 
						|
                        altitudeAccuracy: null,
 | 
						|
                        heading: null,
 | 
						|
                        speed: null
 | 
						|
                    },
 | 
						|
                    // extra info that is outside of the bounds of the core API
 | 
						|
                    address: {
 | 
						|
                        city: cl.address.city,
 | 
						|
                        country: cl.address.country,
 | 
						|
                        country_code: cl.address.country_code,
 | 
						|
                        region: cl.address.region
 | 
						|
                    },
 | 
						|
                    timestamp: new Date()
 | 
						|
                };
 | 
						|
 | 
						|
                successCallback(position);
 | 
						|
                
 | 
						|
                this.lastPosition = position;
 | 
						|
            } else if (errorCallback === "function")  {
 | 
						|
                errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
 | 
						|
            }
 | 
						|
        },
 | 
						|
        
 | 
						|
        watchPosition: function(successCallback, errorCallback, options) {
 | 
						|
            this.getCurrentPosition(successCallback, errorCallback, options);
 | 
						|
            
 | 
						|
            var self = this;
 | 
						|
            var watchId = setInterval(function() {
 | 
						|
                self.getCurrentPosition(successCallback, errorCallback, options);
 | 
						|
            }, 10000);
 | 
						|
            
 | 
						|
            return watchId;
 | 
						|
        },
 | 
						|
        
 | 
						|
        clearWatch: function(watchId) {
 | 
						|
            clearInterval(watchId);
 | 
						|
        },
 | 
						|
        
 | 
						|
        getPermission: function(siteName, imageUrl, extraMessage) {
 | 
						|
            // for now just say yes :)
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
    };
 | 
						|
});
 | 
						|
 | 
						|
// If you have Gears installed use that, else use Ajax ClientLocation
 | 
						|
navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();
 | 
						|
 | 
						|
})();
 | 
						|
}
 |