]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - js/geometa.js
Merge remote-tracking branch 'origin/1.0.x' into 1.0.x
[quix0rs-gnu-social.git] / js / geometa.js
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(){
3
4 // -- BEGIN GEARS_INIT
5 (function() {
6   // We are already defined. Hooray!
7   if (window.google && google.gears) {
8     return;
9   }
10
11   var factory = null;
12
13   // Firefox
14   if (typeof GearsFactory != 'undefined') {
15     factory = new GearsFactory();
16   } else {
17     // IE
18     try {
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);
23       }
24     } catch (e) {
25       // Safari
26       if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
27         factory = document.createElement("object");
28         factory.style.display = "none";
29         factory.width = 0;
30         factory.height = 0;
31         factory.type = "application/x-googlegears";
32         document.documentElement.appendChild(factory);
33       }
34     }
35   }
36
37   // *Do not* define any objects if Gears is not installed. This mimics the
38   // behavior of Gears defining the objects in the future.
39   if (!factory) {
40     return;
41   }
42
43   // Now set up the objects, being careful not to overwrite anything.
44   //
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.
48   if (!window.google) {
49     google = {};
50   }
51
52   if (!google.gears) {
53     google.gears = {factory: factory};
54   }
55 })();
56 // -- END GEARS_INIT
57
58 var GearsGeoLocation = (function() {
59     // -- PRIVATE
60     var geo = google.gears.factory.create('beta.geolocation');
61     
62     var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
63         return function(position) {
64             callback(position);
65             self.lastPosition = position;
66         };
67     };
68     
69     // -- PUBLIC
70     return {
71         shim: true,
72         
73         type: "Gears",
74         
75         lastPosition: null,
76         
77         getCurrentPosition: function(successCallback, errorCallback, options) {
78             var self = this;
79             var sc = wrapSuccess(successCallback, self);
80             geo.getCurrentPosition(sc, errorCallback, options);
81         },
82         
83         watchPosition: function(successCallback, errorCallback, options) {
84             geo.watchPosition(successCallback, errorCallback, options);
85         },
86         
87         clearWatch: function(watchId) {
88             geo.clearWatch(watchId);
89         },
90         
91         getPermission: function(siteName, imageUrl, extraMessage) {
92             geo.getPermission(siteName, imageUrl, extraMessage);
93         }
94
95     };
96 });
97
98 var AjaxGeoLocation = (function() {
99     // -- PRIVATE
100     var loading = false;
101     var loadGoogleLoader = function() {
102         if (!hasGoogleLoader() && !loading) {
103             loading = true;
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);
108         }
109     };
110     
111     var queue = [];
112     var addLocationQueue = function(callback) {
113         queue.push(callback);
114     };
115     
116     var runLocationQueue = function() {
117         if (hasGoogleLoader()) {
118             while (queue.length > 0) {
119                 var call = queue.pop();
120                 call();
121             }
122         }
123     };
124     
125     window['_google_loader_apiLoaded'] = function() {
126         runLocationQueue();
127     };
128     
129     var hasGoogleLoader = function() {
130         return (window['google'] && google['loader']);
131     };
132     
133     var checkGoogleLoader = function(callback) {
134         if (hasGoogleLoader()) { return true; }
135
136         addLocationQueue(callback);
137                 
138         loadGoogleLoader();
139         
140         return false;
141     };
142     
143     loadGoogleLoader(); // start to load as soon as possible just in case
144     
145     // -- PUBLIC
146     return {
147         shim: true,
148         
149         type: "ClientLocation",
150         
151         lastPosition: null,
152         
153         getCurrentPosition: function(successCallback, errorCallback, options) {
154             var self = this;
155             if (!checkGoogleLoader(function() {
156                 self.getCurrentPosition(successCallback, errorCallback, options);
157             })) { return; }
158             
159             if (google.loader.ClientLocation) {
160                 var cl = google.loader.ClientLocation;
161                 
162                 var position = {
163                     coords: {
164                         latitude: cl.latitude,
165                         longitude: cl.longitude,
166                         altitude: null,
167                         accuracy: 43000, // same as Gears accuracy over wifi?
168                         altitudeAccuracy: null,
169                         heading: null,
170                         speed: null
171                     },
172                     // extra info that is outside of the bounds of the core API
173                     address: {
174                         city: cl.address.city,
175                         country: cl.address.country,
176                         country_code: cl.address.country_code,
177                         region: cl.address.region
178                     },
179                     timestamp: new Date()
180                 };
181
182                 successCallback(position);
183                 
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."});
187             }
188         },
189         
190         watchPosition: function(successCallback, errorCallback, options) {
191             this.getCurrentPosition(successCallback, errorCallback, options);
192             
193             var self = this;
194             var watchId = setInterval(function() {
195                 self.getCurrentPosition(successCallback, errorCallback, options);
196             }, 10000);
197             
198             return watchId;
199         },
200         
201         clearWatch: function(watchId) {
202             clearInterval(watchId);
203         },
204         
205         getPermission: function(siteName, imageUrl, extraMessage) {
206             // for now just say yes :)
207             return true;
208         }
209
210     };
211 });
212
213 // If you have Gears installed use that, else use Ajax ClientLocation
214 navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();
215
216 })();
217 }