Use our own hash implementation
We need more flexibility than L.Hash provides.
This commit is contained in:
parent
aa45efc1b7
commit
a805e0b545
8 changed files with 71 additions and 199 deletions
|
@ -32,10 +32,6 @@ 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
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
//= require osm
|
||||
//= require leaflet
|
||||
//= require leaflet.osm
|
||||
//= require leaflet.hash
|
||||
//= require leaflet.map
|
||||
//= require leaflet.zoom
|
||||
//= require leaflet.locationfilter
|
||||
|
|
|
@ -23,21 +23,7 @@ $(document).ready(function () {
|
|||
|
||||
map.attributionControl.setPrefix('');
|
||||
|
||||
map.hash = L.hash(map);
|
||||
|
||||
$(window).on('popstate', function(e) {
|
||||
// popstate is triggered when the hash changes as well as on actual navigation
|
||||
// events. We want to update the hash on the latter and not the former.
|
||||
if (e.originalEvent.state) {
|
||||
map.hash.update();
|
||||
}
|
||||
});
|
||||
|
||||
map.updateLayers(params);
|
||||
|
||||
$(window).on("hashchange", function () {
|
||||
map.updateLayers(OSM.mapParams());
|
||||
});
|
||||
map.updateLayers(params.layers);
|
||||
|
||||
map.on("baselayerchange", function (e) {
|
||||
if (map.getZoom() > e.layer.options.maxZoom) {
|
||||
|
@ -110,9 +96,6 @@ $(document).ready(function () {
|
|||
var expiry = new Date();
|
||||
expiry.setYear(expiry.getFullYear() + 10);
|
||||
$.cookie("_osm_location", cookieContent(map), { expires: expiry });
|
||||
|
||||
// Trigger hash update on layer changes.
|
||||
map.hash.onMapMove();
|
||||
});
|
||||
|
||||
if (OSM.PIWIK) {
|
||||
|
@ -225,7 +208,7 @@ $(document).ready(function () {
|
|||
var history = OSM.History(map),
|
||||
note = OSM.Note(map);
|
||||
|
||||
OSM.route = OSM.Router({
|
||||
OSM.route = OSM.Router(map, {
|
||||
"/": OSM.Index(map),
|
||||
"/search": OSM.Search(map),
|
||||
"/export": OSM.Export(map),
|
||||
|
|
|
@ -140,6 +140,7 @@ L.OSM.layers = function(options) {
|
|||
} else {
|
||||
map.removeLayer(layer);
|
||||
}
|
||||
map.fire('overlaylayerchange', {layer: layer});
|
||||
});
|
||||
|
||||
map.on('layeradd layerremove', function() {
|
||||
|
|
|
@ -56,8 +56,8 @@ L.OSM.Map = L.Map.extend({
|
|||
this.dataLayer.options.code = 'D';
|
||||
},
|
||||
|
||||
updateLayers: function(params) {
|
||||
var layerParam = params.layers || "M";
|
||||
updateLayers: function(layerParam) {
|
||||
layerParam = layerParam || "M";
|
||||
var layersAdded = "";
|
||||
|
||||
for (var i = this.baseLayers.length - 1; i >= 0; i--) {
|
||||
|
@ -243,9 +243,6 @@ L.extend(L.Icon.Default.prototype, {
|
|||
}
|
||||
});
|
||||
|
||||
L.Hash.prototype.parseHash = OSM.parseHash;
|
||||
L.Hash.prototype.formatHash = OSM.formatHash;
|
||||
|
||||
function getUserIcon(url) {
|
||||
return L.icon({
|
||||
iconUrl: url || <%= asset_path('marker-red.png').to_json %>,
|
||||
|
|
|
@ -101,15 +101,41 @@ OSM = {
|
|||
},
|
||||
|
||||
parseHash: function(hash) {
|
||||
if (hash.indexOf('#') === 0) {
|
||||
hash = hash.substr(1);
|
||||
var i = hash.indexOf('#');
|
||||
if (i < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hash = hash.substr(i + 1);
|
||||
|
||||
if (hash === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
hash = querystring.parse(hash);
|
||||
var args = L.Hash.parseHash(hash.map || '') || {};
|
||||
if (hash.layers) args.layers = hash.layers;
|
||||
|
||||
var args = hash.map.split("/");
|
||||
if (args.length !== 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var zoom = parseInt(args[0], 10),
|
||||
lat = parseFloat(args[1]),
|
||||
lon = parseFloat(args[2]);
|
||||
|
||||
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
args = {
|
||||
center: new L.LatLng(lat, lon),
|
||||
zoom: zoom
|
||||
};
|
||||
|
||||
if (hash.layers) {
|
||||
args.layers = hash.layers;
|
||||
}
|
||||
|
||||
return args;
|
||||
},
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
OSM.Router = function(rts) {
|
||||
OSM.Router = function(map, rts) {
|
||||
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
|
||||
var optionalParam = /\((.*?)\)/g;
|
||||
var namedParam = /(\(\?)?:\w+/g;
|
||||
|
@ -45,14 +45,39 @@ OSM.Router = function(rts) {
|
|||
};
|
||||
|
||||
var currentPath = window.location.pathname + window.location.search,
|
||||
currentRoute = routes.recognize(currentPath);
|
||||
currentRoute = routes.recognize(currentPath),
|
||||
currentHash = location.hash || OSM.formatHash(map);
|
||||
|
||||
currentRoute.run('load', currentPath);
|
||||
|
||||
var stateChange;
|
||||
|
||||
map.on('moveend baselayerchange overlaylayerchange', function() {
|
||||
var hash = OSM.formatHash(map);
|
||||
if (hash === currentHash) return;
|
||||
currentHash = hash;
|
||||
stateChange(OSM.parseHash(hash), hash);
|
||||
});
|
||||
|
||||
$(window).on('hashchange', function() {
|
||||
var hash = location.hash;
|
||||
if (hash === currentHash) return;
|
||||
currentHash = hash;
|
||||
var state = OSM.parseHash(hash);
|
||||
if (!state) return;
|
||||
map.setView(state.center, state.zoom);
|
||||
map.updateLayers(state.layers);
|
||||
stateChange(state, hash);
|
||||
});
|
||||
|
||||
if (window.history && window.history.pushState) {
|
||||
stateChange = function(state, hash) {
|
||||
window.history.replaceState(state, document.title, hash);
|
||||
};
|
||||
|
||||
// Set a non-null initial state, so that the e.originalEvent.state
|
||||
// check below works correctly when going back to the initial page.
|
||||
window.history.replaceState({}, document.title, window.location);
|
||||
stateChange(OSM.parseHash(currentHash), currentPath + currentHash);
|
||||
|
||||
$(window).on('popstate', function(e) {
|
||||
if (!e.originalEvent.state) return; // Is it a real popstate event or just a hash change?
|
||||
|
@ -62,13 +87,16 @@ OSM.Router = function(rts) {
|
|||
currentPath = path;
|
||||
currentRoute = routes.recognize(currentPath);
|
||||
currentRoute.run('popstate', currentPath);
|
||||
var state = e.originalEvent.state;
|
||||
map.setView(state.center, state.zoom);
|
||||
map.updateLayers(state.layers);
|
||||
});
|
||||
|
||||
return function (url) {
|
||||
var path = url.replace(/#.*/, ''),
|
||||
route = routes.recognize(path);
|
||||
if (!route) return false;
|
||||
window.history.pushState({}, document.title, url);
|
||||
window.history.pushState(OSM.parseHash(url) || {}, document.title, url);
|
||||
currentRoute.run('unload');
|
||||
currentPath = path;
|
||||
currentRoute = route;
|
||||
|
@ -76,6 +104,10 @@ OSM.Router = function(rts) {
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
stateChange = function(state, hash) {
|
||||
window.location.replace(hash);
|
||||
};
|
||||
|
||||
return function (url) {
|
||||
window.location.assign(url);
|
||||
}
|
||||
|
|
162
vendor/assets/leaflet/leaflet.hash.js
vendored
162
vendor/assets/leaflet/leaflet.hash.js
vendored
|
@ -1,162 +0,0 @@
|
|||
(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);
|
Loading…
Add table
Add a link
Reference in a new issue