Use leaflet-hash
authorJohn Firebaugh <john.firebaugh@gmail.com>
Fri, 19 Jul 2013 21:45:20 +0000 (14:45 -0700)
committerJohn Firebaugh <john.firebaugh@gmail.com>
Tue, 30 Jul 2013 22:41:40 +0000 (15:41 -0700)
Vendorfile
app/assets/javascripts/application.js
app/assets/javascripts/index.js
vendor/assets/leaflet/leaflet.hash.js [new file with mode: 0644]

index 2c05a3ecb7b24f0eb6c210706959c1c78540e2db..babb601e86af8cd7e277b20f8cb4fef9434adc95 100644 (file)
@@ -23,6 +23,10 @@ folder 'vendor/assets' do
     from 'git://github.com/jfirebaugh/leaflet-osm.git' do
       file 'leaflet.osm.js', 'leaflet-osm.js'
     end
+
+    from 'git://github.com/mlevans/leaflet-hash.git' do
+      file 'leaflet.hash.js', 'leaflet-hash.js'
+    end
   end
 
   folder 'ohauth' do
index cb670da340d0feaf2fbead39da4086e643afef02..44858506bf3dea3d2c3d7dd112b2c86af6550bfb 100644 (file)
@@ -5,6 +5,7 @@
 //= require augment
 //= require leaflet
 //= require leaflet.osm
+//= require leaflet.hash
 //= require leaflet.zoom
 //= require leaflet.extend
 //= require leaflet.locationfilter
index 029c0bfd1f1046fe8ef0617b911a48bd6bb4a1d1..68f10ebc18332942aab036ba1c91adbc11708a9b 100644 (file)
@@ -19,6 +19,8 @@ $(document).ready(function () {
 
   map.attributionControl.setPrefix('');
 
+  new L.Hash(map);
+
   var layers = [
     new L.OSM.Mapnik({
       attribution: '',
diff --git a/vendor/assets/leaflet/leaflet.hash.js b/vendor/assets/leaflet/leaflet.hash.js
new file mode 100644 (file)
index 0000000..26bb8ab
--- /dev/null
@@ -0,0 +1,162 @@
+(function(window) {
+       var HAS_HASHCHANGE = (function() {
+               var doc_mode = window.documentMode;
+               return ('onhashchange' in window) &&
+                       (doc_mode === undefined || doc_mode > 7);
+       })();
+
+       L.Hash = function(map) {
+               this.onHashChange = L.Util.bind(this.onHashChange, this);
+
+               if (map) {
+                       this.init(map);
+               }
+       };
+
+       L.Hash.parseHash = function(hash) {
+               if(hash.indexOf('#') === 0) {
+                       hash = hash.substr(1);
+               }
+               var args = hash.split("/");
+               if (args.length == 3) {
+                       var zoom = parseInt(args[0], 10),
+                       lat = parseFloat(args[1]),
+                       lon = parseFloat(args[2]);
+                       if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
+                               return false;
+                       } else {
+                               return {
+                                       center: new L.LatLng(lat, lon),
+                                       zoom: zoom
+                               };
+                       }
+               } else {
+                       return false;
+               }
+       };
+
+       L.Hash.formatHash = function(map) {
+               var center = map.getCenter(),
+                   zoom = map.getZoom(),
+                   precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
+
+               return "#" + [zoom,
+                       center.lat.toFixed(precision),
+                       center.lng.toFixed(precision)
+               ].join("/");
+       },
+
+       L.Hash.prototype = {
+               map: null,
+               lastHash: null,
+
+               parseHash: L.Hash.parseHash,
+               formatHash: L.Hash.formatHash,
+
+               init: function(map) {
+                       this.map = map;
+
+                       // reset the hash
+                       this.lastHash = null;
+                       this.onHashChange();
+
+                       if (!this.isListening) {
+                               this.startListening();
+                       }
+               },
+
+               remove: function() {
+                       if (this.changeTimeout) {
+                               clearTimeout(this.changeTimeout);
+                       }
+
+                       if (this.isListening) {
+                               this.stopListening();
+                       }
+
+                       this.map = null;
+               },
+
+               onMapMove: function() {
+                       // bail if we're moving the map (updating from a hash),
+                       // or if the map is not yet loaded
+
+                       if (this.movingMap || !this.map._loaded) {
+                               return false;
+                       }
+
+                       var hash = this.formatHash(this.map);
+                       if (this.lastHash != hash) {
+                               location.replace(hash);
+                               this.lastHash = hash;
+                       }
+               },
+
+               movingMap: false,
+               update: function() {
+                       var hash = location.hash;
+                       if (hash === this.lastHash) {
+                               return;
+                       }
+                       var parsed = this.parseHash(hash);
+                       if (parsed) {
+                               this.movingMap = true;
+
+                               this.map.setView(parsed.center, parsed.zoom);
+
+                               this.movingMap = false;
+                       } else {
+                               this.onMapMove(this.map);
+                       }
+               },
+
+               // defer hash change updates every 100ms
+               changeDefer: 100,
+               changeTimeout: null,
+               onHashChange: function() {
+                       // throttle calls to update() so that they only happen every
+                       // `changeDefer` ms
+                       if (!this.changeTimeout) {
+                               var that = this;
+                               this.changeTimeout = setTimeout(function() {
+                                       that.update();
+                                       that.changeTimeout = null;
+                               }, this.changeDefer);
+                       }
+               },
+
+               isListening: false,
+               hashChangeInterval: null,
+               startListening: function() {
+                       this.map.on("moveend", this.onMapMove, this);
+
+                       if (HAS_HASHCHANGE) {
+                               L.DomEvent.addListener(window, "hashchange", this.onHashChange);
+                       } else {
+                               clearInterval(this.hashChangeInterval);
+                               this.hashChangeInterval = setInterval(this.onHashChange, 50);
+                       }
+                       this.isListening = true;
+               },
+
+               stopListening: function() {
+                       this.map.off("moveend", this.onMapMove, this);
+
+                       if (HAS_HASHCHANGE) {
+                               L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
+                       } else {
+                               clearInterval(this.hashChangeInterval);
+                       }
+                       this.isListening = false;
+               }
+       };
+       L.hash = function(map) {
+               return new L.Hash(map);
+       };
+       L.Map.prototype.addHash = function() {
+               this._hash = L.hash(this);
+       };
+       L.Map.prototype.removeHash = function() {
+               this._hash.remove();
+       };
+})(window);