brouter-web/js/plugin/POIMarkers.js
Henrik Fehlauer 08c8cfa8be Prevent more accidental shortcut triggers
Do not allow browser keyboard shortcuts to trigger route functions,
e.g. pressing Ctrl+P triggers printing in most browsers, but should not
at the same time switch BRouter-Web to POI mode. This can be prevented
by filtering for modifiers.

In the same fashion, when modal dialogs or dropdowns are open it should
not be possible to activate map functions in the background now.

Finally, inhibit shortcuts in number input fields too, as found in the
editable number input fields in the customize profile options.
Previously only regular text input fields were protected.

To make those checks easier to use, they are deduplicated and moved to
Util.js.
2020-05-28 18:00:00 +00:00

145 lines
4.3 KiB
JavaScript

BR.PoiMarkers = L.Control.extend({
markersLayer: null,
options: {
routing: null,
shortcut: {
draw: {
enable: 80, // char code for 'p'
disable: 27 // char code for 'ESC'
}
}
},
onAdd: function(map) {
var self = this;
this.map = map;
this.markersLayer = L.layerGroup([]).addTo(map);
this.drawButton = L.easyButton({
states: [
{
stateName: 'activate-poi',
icon: 'fa-hand-o-right',
onClick: function() {
self.draw(true);
},
title: i18next.t('map.draw-poi-start')
},
{
stateName: 'deactivate-poi',
icon: 'fa-hand-o-right active',
onClick: function() {
self.draw(false);
},
title: i18next.t('map.draw-poi-stop')
}
]
}).addTo(map);
map.on('routing:draw-start', function() {
self.draw(false);
});
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
var container = new L.DomUtil.create('div');
return container;
},
draw: function(enable) {
this.drawButton.state(enable ? 'deactivate-poi' : 'activate-poi');
if (enable) {
this.options.routing.draw(false);
this.map.on('click', this.onMapClick, this);
L.DomUtil.addClass(this.map.getContainer(), 'pois-draw-enabled');
} else {
this.map.off('click', this.onMapClick, this);
L.DomUtil.removeClass(this.map.getContainer(), 'pois-draw-enabled');
}
},
_keydownListener: function(e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
if (e.keyCode === this.options.shortcut.draw.disable) {
this.draw(false);
} else if (e.keyCode === this.options.shortcut.draw.enable) {
this.draw(true);
}
},
onMapClick: function(e) {
var self = this;
bootbox.prompt({
title: i18next.t('map.enter-poi-name'),
callback: function(result) {
if (result !== null) {
self.addMarker(e.latlng, result);
}
}
});
},
addMarker: function(latlng, name) {
// this method must only be used to sanitize for textContent.
// do NOT use it to sanitize any attribute,
// see https://web.archive.org/web/20121208091505/http://benv.ca/2012/10/4/you-are-probably-misusing-DOM-text-methods/
var sanitizeHTMLContent = function(str) {
var temp = document.createElement('div');
temp.textContent = str;
return temp.innerHTML;
};
var icon = L.VectorMarkers.icon({
icon: 'star',
markerColor: BR.conf.markerColors.poi
});
var content = sanitizeHTMLContent(name) + '<br>';
content += "<button id='remove-poi-marker' class='btn btn-secondary'><i class='fa fa-trash'></i></button>";
var self = this;
var marker = L.marker(latlng, { icon: icon, draggable: true, name: name })
.bindPopup(content)
.on('dragend', function() {
self.fire('update');
})
.on('popupopen', function() {
$('#remove-poi-marker').on('click', function(e) {
self.markersLayer.removeLayer(marker);
e.preventDefault();
self.fire('update');
});
})
.addTo(this.markersLayer);
},
clear: function() {
this.markersLayer.clearLayers();
},
setMarkers: function(latLngNames) {
this.clear();
if (!latLngNames) return;
for (var i = 0; i < latLngNames.length; i++) {
var r = latLngNames[i];
this.addMarker(r.latlng, r.name);
}
},
getMarkers: function() {
return this.markersLayer.getLayers().map(function(it) {
return {
latlng: it._latlng,
name: it.options.name
};
});
}
});
BR.PoiMarkers.include(L.Evented.prototype);