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