26bb8abf688bb9b26cf63452dd529c93e5325de4
[rails.git] / vendor / assets / leaflet / leaflet.hash.js
1 (function(window) {
2         var HAS_HASHCHANGE = (function() {
3                 var doc_mode = window.documentMode;
4                 return ('onhashchange' in window) &&
5                         (doc_mode === undefined || doc_mode > 7);
6         })();
7
8         L.Hash = function(map) {
9                 this.onHashChange = L.Util.bind(this.onHashChange, this);
10
11                 if (map) {
12                         this.init(map);
13                 }
14         };
15
16         L.Hash.parseHash = function(hash) {
17                 if(hash.indexOf('#') === 0) {
18                         hash = hash.substr(1);
19                 }
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)) {
26                                 return false;
27                         } else {
28                                 return {
29                                         center: new L.LatLng(lat, lon),
30                                         zoom: zoom
31                                 };
32                         }
33                 } else {
34                         return false;
35                 }
36         };
37
38         L.Hash.formatHash = function(map) {
39                 var center = map.getCenter(),
40                     zoom = map.getZoom(),
41                     precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
42
43                 return "#" + [zoom,
44                         center.lat.toFixed(precision),
45                         center.lng.toFixed(precision)
46                 ].join("/");
47         },
48
49         L.Hash.prototype = {
50                 map: null,
51                 lastHash: null,
52
53                 parseHash: L.Hash.parseHash,
54                 formatHash: L.Hash.formatHash,
55
56                 init: function(map) {
57                         this.map = map;
58
59                         // reset the hash
60                         this.lastHash = null;
61                         this.onHashChange();
62
63                         if (!this.isListening) {
64                                 this.startListening();
65                         }
66                 },
67
68                 remove: function() {
69                         if (this.changeTimeout) {
70                                 clearTimeout(this.changeTimeout);
71                         }
72
73                         if (this.isListening) {
74                                 this.stopListening();
75                         }
76
77                         this.map = null;
78                 },
79
80                 onMapMove: function() {
81                         // bail if we're moving the map (updating from a hash),
82                         // or if the map is not yet loaded
83
84                         if (this.movingMap || !this.map._loaded) {
85                                 return false;
86                         }
87
88                         var hash = this.formatHash(this.map);
89                         if (this.lastHash != hash) {
90                                 location.replace(hash);
91                                 this.lastHash = hash;
92                         }
93                 },
94
95                 movingMap: false,
96                 update: function() {
97                         var hash = location.hash;
98                         if (hash === this.lastHash) {
99                                 return;
100                         }
101                         var parsed = this.parseHash(hash);
102                         if (parsed) {
103                                 this.movingMap = true;
104
105                                 this.map.setView(parsed.center, parsed.zoom);
106
107                                 this.movingMap = false;
108                         } else {
109                                 this.onMapMove(this.map);
110                         }
111                 },
112
113                 // defer hash change updates every 100ms
114                 changeDefer: 100,
115                 changeTimeout: null,
116                 onHashChange: function() {
117                         // throttle calls to update() so that they only happen every
118                         // `changeDefer` ms
119                         if (!this.changeTimeout) {
120                                 var that = this;
121                                 this.changeTimeout = setTimeout(function() {
122                                         that.update();
123                                         that.changeTimeout = null;
124                                 }, this.changeDefer);
125                         }
126                 },
127
128                 isListening: false,
129                 hashChangeInterval: null,
130                 startListening: function() {
131                         this.map.on("moveend", this.onMapMove, this);
132
133                         if (HAS_HASHCHANGE) {
134                                 L.DomEvent.addListener(window, "hashchange", this.onHashChange);
135                         } else {
136                                 clearInterval(this.hashChangeInterval);
137                                 this.hashChangeInterval = setInterval(this.onHashChange, 50);
138                         }
139                         this.isListening = true;
140                 },
141
142                 stopListening: function() {
143                         this.map.off("moveend", this.onMapMove, this);
144
145                         if (HAS_HASHCHANGE) {
146                                 L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
147                         } else {
148                                 clearInterval(this.hashChangeInterval);
149                         }
150                         this.isListening = false;
151                 }
152         };
153         L.hash = function(map) {
154                 return new L.Hash(map);
155         };
156         L.Map.prototype.addHash = function() {
157                 this._hash = L.hash(this);
158         };
159         L.Map.prototype.removeHash = function() {
160                 this._hash.remove();
161         };
162 })(window);