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
|
from 'git://github.com/jfirebaugh/leaflet-osm.git' do
|
||||||
file 'leaflet.osm.js', 'leaflet-osm.js'
|
file 'leaflet.osm.js', 'leaflet-osm.js'
|
||||||
end
|
end
|
||||||
|
|
||||||
from 'git://github.com/mlevans/leaflet-hash.git' do
|
|
||||||
file 'leaflet.hash.js', 'leaflet-hash.js'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
folder 'ohauth' do
|
folder 'ohauth' do
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
//= require osm
|
//= require osm
|
||||||
//= require leaflet
|
//= require leaflet
|
||||||
//= require leaflet.osm
|
//= require leaflet.osm
|
||||||
//= require leaflet.hash
|
|
||||||
//= require leaflet.map
|
//= require leaflet.map
|
||||||
//= require leaflet.zoom
|
//= require leaflet.zoom
|
||||||
//= require leaflet.locationfilter
|
//= require leaflet.locationfilter
|
||||||
|
|
|
@ -23,21 +23,7 @@ $(document).ready(function () {
|
||||||
|
|
||||||
map.attributionControl.setPrefix('');
|
map.attributionControl.setPrefix('');
|
||||||
|
|
||||||
map.hash = L.hash(map);
|
map.updateLayers(params.layers);
|
||||||
|
|
||||||
$(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.on("baselayerchange", function (e) {
|
map.on("baselayerchange", function (e) {
|
||||||
if (map.getZoom() > e.layer.options.maxZoom) {
|
if (map.getZoom() > e.layer.options.maxZoom) {
|
||||||
|
@ -110,9 +96,6 @@ $(document).ready(function () {
|
||||||
var expiry = new Date();
|
var expiry = new Date();
|
||||||
expiry.setYear(expiry.getFullYear() + 10);
|
expiry.setYear(expiry.getFullYear() + 10);
|
||||||
$.cookie("_osm_location", cookieContent(map), { expires: expiry });
|
$.cookie("_osm_location", cookieContent(map), { expires: expiry });
|
||||||
|
|
||||||
// Trigger hash update on layer changes.
|
|
||||||
map.hash.onMapMove();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (OSM.PIWIK) {
|
if (OSM.PIWIK) {
|
||||||
|
@ -225,7 +208,7 @@ $(document).ready(function () {
|
||||||
var history = OSM.History(map),
|
var history = OSM.History(map),
|
||||||
note = OSM.Note(map);
|
note = OSM.Note(map);
|
||||||
|
|
||||||
OSM.route = OSM.Router({
|
OSM.route = OSM.Router(map, {
|
||||||
"/": OSM.Index(map),
|
"/": OSM.Index(map),
|
||||||
"/search": OSM.Search(map),
|
"/search": OSM.Search(map),
|
||||||
"/export": OSM.Export(map),
|
"/export": OSM.Export(map),
|
||||||
|
|
|
@ -140,6 +140,7 @@ L.OSM.layers = function(options) {
|
||||||
} else {
|
} else {
|
||||||
map.removeLayer(layer);
|
map.removeLayer(layer);
|
||||||
}
|
}
|
||||||
|
map.fire('overlaylayerchange', {layer: layer});
|
||||||
});
|
});
|
||||||
|
|
||||||
map.on('layeradd layerremove', function() {
|
map.on('layeradd layerremove', function() {
|
||||||
|
|
|
@ -56,8 +56,8 @@ L.OSM.Map = L.Map.extend({
|
||||||
this.dataLayer.options.code = 'D';
|
this.dataLayer.options.code = 'D';
|
||||||
},
|
},
|
||||||
|
|
||||||
updateLayers: function(params) {
|
updateLayers: function(layerParam) {
|
||||||
var layerParam = params.layers || "M";
|
layerParam = layerParam || "M";
|
||||||
var layersAdded = "";
|
var layersAdded = "";
|
||||||
|
|
||||||
for (var i = this.baseLayers.length - 1; i >= 0; i--) {
|
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) {
|
function getUserIcon(url) {
|
||||||
return L.icon({
|
return L.icon({
|
||||||
iconUrl: url || <%= asset_path('marker-red.png').to_json %>,
|
iconUrl: url || <%= asset_path('marker-red.png').to_json %>,
|
||||||
|
|
|
@ -101,15 +101,41 @@ OSM = {
|
||||||
},
|
},
|
||||||
|
|
||||||
parseHash: function(hash) {
|
parseHash: function(hash) {
|
||||||
if (hash.indexOf('#') === 0) {
|
var i = hash.indexOf('#');
|
||||||
hash = hash.substr(1);
|
if (i < 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash = hash.substr(i + 1);
|
||||||
|
|
||||||
if (hash === '') {
|
if (hash === '') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = querystring.parse(hash);
|
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;
|
return args;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
OSM.Router = function(rts) {
|
OSM.Router = function(map, rts) {
|
||||||
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
|
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
|
||||||
var optionalParam = /\((.*?)\)/g;
|
var optionalParam = /\((.*?)\)/g;
|
||||||
var namedParam = /(\(\?)?:\w+/g;
|
var namedParam = /(\(\?)?:\w+/g;
|
||||||
|
@ -45,14 +45,39 @@ OSM.Router = function(rts) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var currentPath = window.location.pathname + window.location.search,
|
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);
|
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) {
|
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
|
// Set a non-null initial state, so that the e.originalEvent.state
|
||||||
// check below works correctly when going back to the initial page.
|
// 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) {
|
$(window).on('popstate', function(e) {
|
||||||
if (!e.originalEvent.state) return; // Is it a real popstate event or just a hash change?
|
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;
|
currentPath = path;
|
||||||
currentRoute = routes.recognize(currentPath);
|
currentRoute = routes.recognize(currentPath);
|
||||||
currentRoute.run('popstate', currentPath);
|
currentRoute.run('popstate', currentPath);
|
||||||
|
var state = e.originalEvent.state;
|
||||||
|
map.setView(state.center, state.zoom);
|
||||||
|
map.updateLayers(state.layers);
|
||||||
});
|
});
|
||||||
|
|
||||||
return function (url) {
|
return function (url) {
|
||||||
var path = url.replace(/#.*/, ''),
|
var path = url.replace(/#.*/, ''),
|
||||||
route = routes.recognize(path);
|
route = routes.recognize(path);
|
||||||
if (!route) return false;
|
if (!route) return false;
|
||||||
window.history.pushState({}, document.title, url);
|
window.history.pushState(OSM.parseHash(url) || {}, document.title, url);
|
||||||
currentRoute.run('unload');
|
currentRoute.run('unload');
|
||||||
currentPath = path;
|
currentPath = path;
|
||||||
currentRoute = route;
|
currentRoute = route;
|
||||||
|
@ -76,6 +104,10 @@ OSM.Router = function(rts) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
stateChange = function(state, hash) {
|
||||||
|
window.location.replace(hash);
|
||||||
|
};
|
||||||
|
|
||||||
return function (url) {
|
return function (url) {
|
||||||
window.location.assign(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