geometa.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. // -- BEGIN GEARS_INIT
  4. (function() {
  5. // We are already defined. Hooray!
  6. if (window.google && google.gears) {
  7. return;
  8. }
  9. var factory = null;
  10. // Firefox
  11. if (typeof GearsFactory != 'undefined') {
  12. factory = new GearsFactory();
  13. } else {
  14. // IE
  15. try {
  16. factory = new ActiveXObject('Gears.Factory');
  17. // privateSetGlobalObject is only required and supported on WinCE.
  18. if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
  19. factory.privateSetGlobalObject(this);
  20. }
  21. } catch (e) {
  22. // Safari
  23. if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
  24. factory = document.createElement("object");
  25. factory.style.display = "none";
  26. factory.width = 0;
  27. factory.height = 0;
  28. factory.type = "application/x-googlegears";
  29. document.documentElement.appendChild(factory);
  30. }
  31. }
  32. }
  33. // *Do not* define any objects if Gears is not installed. This mimics the
  34. // behavior of Gears defining the objects in the future.
  35. if (!factory) {
  36. return;
  37. }
  38. // Now set up the objects, being careful not to overwrite anything.
  39. //
  40. // Note: In Internet Explorer for Windows Mobile, you can't add properties to
  41. // the window object. However, global objects are automatically added as
  42. // properties of the window object in all browsers.
  43. if (!window.google) {
  44. google = {};
  45. }
  46. if (!google.gears) {
  47. google.gears = {factory: factory};
  48. }
  49. })();
  50. // -- END GEARS_INIT
  51. var GearsGeoLocation = (function() {
  52. // -- PRIVATE
  53. var geo = google.gears.factory.create('beta.geolocation');
  54. var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
  55. return function(position) {
  56. callback(position);
  57. self.lastPosition = position;
  58. };
  59. };
  60. // -- PUBLIC
  61. return {
  62. shim: true,
  63. type: "Gears",
  64. lastPosition: null,
  65. getCurrentPosition: function(successCallback, errorCallback, options) {
  66. var self = this;
  67. var sc = wrapSuccess(successCallback, self);
  68. geo.getCurrentPosition(sc, errorCallback, options);
  69. },
  70. watchPosition: function(successCallback, errorCallback, options) {
  71. geo.watchPosition(successCallback, errorCallback, options);
  72. },
  73. clearWatch: function(watchId) {
  74. geo.clearWatch(watchId);
  75. },
  76. getPermission: function(siteName, imageUrl, extraMessage) {
  77. geo.getPermission(siteName, imageUrl, extraMessage);
  78. }
  79. };
  80. });
  81. var AjaxGeoLocation = (function() {
  82. // -- PRIVATE
  83. var loading = false;
  84. var loadGoogleLoader = function() {
  85. if (!hasGoogleLoader() && !loading) {
  86. loading = true;
  87. var s = document.createElement('script');
  88. s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
  89. s.type = "text/javascript";
  90. document.getElementsByTagName('body')[0].appendChild(s);
  91. }
  92. };
  93. var queue = [];
  94. var addLocationQueue = function(callback) {
  95. queue.push(callback);
  96. };
  97. var runLocationQueue = function() {
  98. if (hasGoogleLoader()) {
  99. while (queue.length > 0) {
  100. var call = queue.pop();
  101. call();
  102. }
  103. }
  104. };
  105. window['_google_loader_apiLoaded'] = function() {
  106. runLocationQueue();
  107. };
  108. var hasGoogleLoader = function() {
  109. return (window['google'] && google['loader']);
  110. };
  111. var checkGoogleLoader = function(callback) {
  112. if (hasGoogleLoader()) { return true; }
  113. addLocationQueue(callback);
  114. loadGoogleLoader();
  115. return false;
  116. };
  117. loadGoogleLoader(); // start to load as soon as possible just in case
  118. // -- PUBLIC
  119. return {
  120. shim: true,
  121. type: "ClientLocation",
  122. lastPosition: null,
  123. getCurrentPosition: function(successCallback, errorCallback, options) {
  124. var self = this;
  125. if (!checkGoogleLoader(function() {
  126. self.getCurrentPosition(successCallback, errorCallback, options);
  127. })) { return; }
  128. if (google.loader.ClientLocation) {
  129. var cl = google.loader.ClientLocation;
  130. var position = {
  131. coords: {
  132. latitude: cl.latitude,
  133. longitude: cl.longitude,
  134. altitude: null,
  135. accuracy: 43000, // same as Gears accuracy over wifi?
  136. altitudeAccuracy: null,
  137. heading: null,
  138. speed: null
  139. },
  140. // extra info that is outside of the bounds of the core API
  141. address: {
  142. city: cl.address.city,
  143. country: cl.address.country,
  144. country_code: cl.address.country_code,
  145. region: cl.address.region
  146. },
  147. timestamp: new Date()
  148. };
  149. successCallback(position);
  150. this.lastPosition = position;
  151. } else if (errorCallback === "function") {
  152. errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
  153. }
  154. },
  155. watchPosition: function(successCallback, errorCallback, options) {
  156. this.getCurrentPosition(successCallback, errorCallback, options);
  157. var self = this;
  158. var watchId = setInterval(function() {
  159. self.getCurrentPosition(successCallback, errorCallback, options);
  160. }, 10000);
  161. return watchId;
  162. },
  163. clearWatch: function(watchId) {
  164. clearInterval(watchId);
  165. },
  166. getPermission: function(siteName, imageUrl, extraMessage) {
  167. // for now just say yes :)
  168. return true;
  169. }
  170. };
  171. });
  172. // If you have Gears installed use that, else use Ajax ClientLocation
  173. navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();
  174. })();
  175. }