]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Add geometa library, and include it.
authorCraig Andrews <candrews@integralblue.com>
Thu, 19 Nov 2009 20:15:34 +0000 (15:15 -0500)
committerCraig Andrews <candrews@integralblue.com>
Thu, 19 Nov 2009 20:17:57 +0000 (15:17 -0500)
Geometa provides a fallback for W3C geolocation so that Google Gears or Google's Client Location service can also be used

js/geometa.js [new file with mode: 0644]
lib/action.php

diff --git a/js/geometa.js b/js/geometa.js
new file mode 100644 (file)
index 0000000..ced5be0
--- /dev/null
@@ -0,0 +1,216 @@
+// 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 = '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 = {
+                    latitude: cl.latitude,
+                    longitude: cl.longitude,
+                    altitude: null,
+                    accuracy: 43000, // same as Gears accuracy over wifi?
+                    altitudeAccuracy: null,
+                    heading: null,
+                    velocity: null,
+                    timestamp: new Date(),
+                    
+                    // 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
+                    }
+                };
+
+                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;
+
+})();
index 9c7060bba831467041f554e08f6b3f2679169f32..8ad3917550ae7e09eeb112dfc8d9a24c8c557fdd 100644 (file)
@@ -259,6 +259,7 @@ class Action extends HTMLOutputter // lawsuit
                 Event::handle('StartShowLaconicaScripts', array($this))) {
                 $this->script('js/xbImportNode.js');
                 $this->script('js/util.js');
+                $this->script('js/geometa.js');
                 // Frame-busting code to avoid clickjacking attacks.
                 $this->element('script', array('type' => 'text/javascript'),
                                'if (window.top !== window.self) { window.top.location.href = window.self.location.href; }');