2 var HAS_HASHCHANGE = (function() {
3 var doc_mode = window.documentMode;
4 return ('onhashchange' in window) &&
5 (doc_mode === undefined || doc_mode > 7);
8 L.Hash = function(map) {
9 this.onHashChange = L.Util.bind(this.onHashChange, this);
16 L.Hash.parseHash = function(hash) {
17 if(hash.indexOf('#') === 0) {
18 hash = hash.substr(1);
20 var args = hash.split("/");
21 if (args.length == 3) {
22 var zoom = parseInt(args[0], 10),
23 lat = parseFloat(args[1]),
24 lon = parseFloat(args[2]);
25 if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
29 center: new L.LatLng(lat, lon),
38 L.Hash.formatHash = function(map) {
39 var center = map.getCenter(),
41 precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
44 center.lat.toFixed(precision),
45 center.lng.toFixed(precision)
53 parseHash: L.Hash.parseHash,
54 formatHash: L.Hash.formatHash,
63 if (!this.isListening) {
64 this.startListening();
69 if (this.changeTimeout) {
70 clearTimeout(this.changeTimeout);
73 if (this.isListening) {
80 onMapMove: function() {
81 // bail if we're moving the map (updating from a hash),
82 // or if the map is not yet loaded
84 if (this.movingMap || !this.map._loaded) {
88 var hash = this.formatHash(this.map);
89 if (this.lastHash != hash) {
90 location.replace(hash);
97 var hash = location.hash;
98 if (hash === this.lastHash) {
101 var parsed = this.parseHash(hash);
103 this.movingMap = true;
105 this.map.setView(parsed.center, parsed.zoom);
107 this.movingMap = false;
109 this.onMapMove(this.map);
113 // defer hash change updates every 100ms
116 onHashChange: function() {
117 // throttle calls to update() so that they only happen every
119 if (!this.changeTimeout) {
121 this.changeTimeout = setTimeout(function() {
123 that.changeTimeout = null;
124 }, this.changeDefer);
129 hashChangeInterval: null,
130 startListening: function() {
131 this.map.on("moveend", this.onMapMove, this);
133 if (HAS_HASHCHANGE) {
134 L.DomEvent.addListener(window, "hashchange", this.onHashChange);
136 clearInterval(this.hashChangeInterval);
137 this.hashChangeInterval = setInterval(this.onHashChange, 50);
139 this.isListening = true;
142 stopListening: function() {
143 this.map.off("moveend", this.onMapMove, this);
145 if (HAS_HASHCHANGE) {
146 L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
148 clearInterval(this.hashChangeInterval);
150 this.isListening = false;
153 L.hash = function(map) {
154 return new L.Hash(map);
156 L.Map.prototype.addHash = function() {
157 this._hash = L.hash(this);
159 L.Map.prototype.removeHash = function() {