Add prettier and reformat code

This commit is contained in:
Gautier Pelloux-Prayer 2019-05-16 21:31:06 +02:00
parent 68eb00bae9
commit 970a34981f
37 changed files with 3459 additions and 1969 deletions

View file

@ -1,17 +1,19 @@
BR.BingLayer = L.BingLayer.extend({
options: {
maxZoom: 19,
attribution: '<a target="_blank" href="https://www.bing.com/maps/">Bing Maps</a>'
+ ' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)'
attribution:
'<a target="_blank" href="https://www.bing.com/maps/">Bing Maps</a>' +
' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)'
},
initialize: function(key, options) {
L.BingLayer.prototype.initialize.call(this, key, options);
this._logo = L.control({position: 'bottomleft'});
this._logo.onAdd = function (map) {
this._logo = L.control({ position: 'bottomleft' });
this._logo.onAdd = function(map) {
this._div = L.DomUtil.create('div', 'bing-logo');
this._div.innerHTML = '<img src="https://www.microsoft.com/maps/images/branding/Bing%20logo%20white_50px-19px.png">';
this._div.innerHTML =
'<img src="https://www.microsoft.com/maps/images/branding/Bing%20logo%20white_50px-19px.png">';
return this._div;
};
},

View file

@ -1,33 +1,47 @@
BR.Elevation = L.Control.Elevation.extend({
options: {
width:$('#map').outerWidth(),
width: $('#map').outerWidth(),
margins: {
top: 20,
right: 30,
bottom: 30,
left: 60
},
theme: "steelblue-theme"
theme: 'steelblue-theme'
},
onAdd: function (map) {
onAdd: function(map) {
var container = L.Control.Elevation.prototype.onAdd.call(this, map);
// revert registering touch events when touch screen detection is available and negative
// see https://github.com/MrMufflon/Leaflet.Elevation/issues/67
if (L.Browser.touch && BR.Browser.touchScreenDetectable && !BR.Browser.touchScreen) {
this._background.on("touchmove.drag", null).
on("touchstart.drag", null).
on("touchstart.focus", null);
L.DomEvent.off(this._container, 'touchend', this._dragEndHandler, this);
this._background.on("mousemove.focus", this._mousemoveHandler.bind(this)).
on("mouseout.focus", this._mouseoutHandler.bind(this)).
on("mousedown.drag", this._dragStartHandler.bind(this)).
on("mousemove.drag", this._dragHandler.bind(this));
L.DomEvent.on(this._container, 'mouseup', this._dragEndHandler, this);
if (
L.Browser.touch &&
BR.Browser.touchScreenDetectable &&
!BR.Browser.touchScreen
) {
this._background
.on('touchmove.drag', null)
.on('touchstart.drag', null)
.on('touchstart.focus', null);
L.DomEvent.off(
this._container,
'touchend',
this._dragEndHandler,
this
);
this._background
.on('mousemove.focus', this._mousemoveHandler.bind(this))
.on('mouseout.focus', this._mouseoutHandler.bind(this))
.on('mousedown.drag', this._dragStartHandler.bind(this))
.on('mousemove.drag', this._dragHandler.bind(this));
L.DomEvent.on(
this._container,
'mouseup',
this._dragEndHandler,
this
);
}
return container;
@ -44,10 +58,13 @@ BR.Elevation = L.Control.Elevation.extend({
function setParent(el, newParent) {
newParent.appendChild(el);
}
this.addTo(map);
}
this.addTo(map);
// move elevation graph outside of the map
setParent(this.getContainer(), document.getElementById('elevation-chart'));
setParent(
this.getContainer(),
document.getElementById('elevation-chart')
);
},
update: function(track, layer) {
@ -62,7 +79,7 @@ BR.Elevation = L.Control.Elevation.extend({
if (track && track.getLatLngs().length > 0) {
this.addData(track.toGeoJSON(), layer);
layer.on("mouseout", this._hidePositionMarker.bind(this));
layer.on('mouseout', this._hidePositionMarker.bind(this));
}
}
});
});

View file

@ -4,7 +4,8 @@ BR.NogoAreas = L.Control.extend({
MSG_BUTTON_CANCEL: 'Cancel drawing no-go area',
MSG_CREATE: 'Click and drag to draw circle',
MSG_DISABLED: 'Click to edit',
MSG_ENABLED: '&square; = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click nogo to quit editing',
MSG_ENABLED:
'&square; = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click nogo to quit editing',
STATE_CREATE: 'no-go-create',
STATE_CANCEL: 'cancel-no-go-create'
},
@ -19,17 +20,17 @@ BR.NogoAreas = L.Control.extend({
},
editStyle: {
color: '#fe57a1',
opacity: 0.6,
dashArray: '10, 10',
fillOpacity: 0.1
color: '#fe57a1',
opacity: 0.6,
dashArray: '10, 10',
fillOpacity: 0.1
},
initialize: function () {
initialize: function() {
this._wasRouteDrawing = false;
},
onAdd: function (map) {
onAdd: function(map) {
var self = this;
this.drawnItems = new L.FeatureGroup().addTo(map);
@ -38,55 +39,77 @@ BR.NogoAreas = L.Control.extend({
e.layer.toggleEdit();
});
var editTools = this.editTools = map.editTools = new L.Editable(map, {
var editTools = (this.editTools = map.editTools = new L.Editable(map, {
circleEditorClass: BR.DeletableCircleEditor,
// FeatureGroup instead of LayerGroup to propagate events to members
editLayer: new L.FeatureGroup().addTo(map),
featuresLayer: this.drawnItems
});
}));
this.button = L.easyButton({
states: [{
stateName: BR.NogoAreas.STATE_CREATE,
icon: 'fa-ban',
title: BR.NogoAreas.MSG_BUTTON,
onClick: function (control) {
// initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp
var opts = L.extend({radius: 0}, self.style);
editTools.startCircle(null, opts);
states: [
{
stateName: BR.NogoAreas.STATE_CREATE,
icon: 'fa-ban',
title: BR.NogoAreas.MSG_BUTTON,
onClick: function(control) {
// initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp
var opts = L.extend({ radius: 0 }, self.style);
editTools.startCircle(null, opts);
control.state('cancel-no-go-create');
control.state('cancel-no-go-create');
}
},
{
stateName: BR.NogoAreas.STATE_CANCEL,
icon: 'fa-ban active',
title: BR.NogoAreas.MSG_BUTTON_CANCEL,
onClick: function(control) {
editTools.stopDrawing();
control.state('no-go-create');
}
}
}, {
stateName: BR.NogoAreas.STATE_CANCEL,
icon: 'fa-ban active',
title: BR.NogoAreas.MSG_BUTTON_CANCEL,
onClick: function (control) {
editTools.stopDrawing();
control.state('no-go-create');
}
}]
]
});
this.editTools.on('editable:drawing:end', function (e) {
self.button.state(BR.NogoAreas.STATE_CREATE);
this.editTools.on(
'editable:drawing:end',
function(e) {
self.button.state(BR.NogoAreas.STATE_CREATE);
setTimeout(L.bind(function () {
// turn editing off after create; async to still fire 'editable:vertex:dragend'
e.layer.disableEdit();
}, this), 0);
}, this);
setTimeout(
L.bind(function() {
// turn editing off after create; async to still fire 'editable:vertex:dragend'
e.layer.disableEdit();
}, this),
0
);
},
this
);
this.editTools.on('editable:vertex:dragend editable:deleted', function (e) {
this._fireUpdate();
}, this);
this.editTools.on(
'editable:vertex:dragend editable:deleted',
function(e) {
this._fireUpdate();
},
this
);
this.editTools.on('editable:enable', function (e) {
e.layer.setStyle(this.editStyle);
}, this);
this.editTools.on('editable:disable', function (e) {
e.layer.setStyle(this.style);
}, this);
this.editTools.on(
'editable:enable',
function(e) {
e.layer.setStyle(this.editStyle);
},
this
);
this.editTools.on(
'editable:disable',
function(e) {
e.layer.setStyle(this.style);
},
this
);
this.tooltip = new BR.EditingTooltip(map, editTools, this.button);
this.tooltip.enable();
@ -97,28 +120,40 @@ BR.NogoAreas = L.Control.extend({
// prevent route waypoint added after circle create (map click after up)
preventRoutePointOnCreate: function(routing) {
this.editTools.on('editable:drawing:start', function (e) {
this._wasRouteDrawing = routing.isDrawing();
routing.draw(false);
}, this);
this.editTools.on(
'editable:drawing:start',
function(e) {
this._wasRouteDrawing = routing.isDrawing();
routing.draw(false);
},
this
);
// after create
this.editTools.on('editable:drawing:end', function (e) {
if (this._wasRouteDrawing) {
setTimeout(function () {
routing.draw(true);
}, 0);
}
}, this);
this.editTools.on(
'editable:drawing:end',
function(e) {
if (this._wasRouteDrawing) {
setTimeout(function() {
routing.draw(true);
}, 0);
}
},
this
);
},
getOptions: function() {
return {
nogos: this.drawnItems.getLayers().filter(function (e) { return e instanceof L.Circle; }),
polygons: this.drawnItems.getLayers().filter(function (e) { return e instanceof L.Polygon; }),
polylines: this.drawnItems.getLayers().filter(function (e) {
return (e instanceof L.Polyline) && !(e instanceof L.Polygon);
nogos: this.drawnItems.getLayers().filter(function(e) {
return e instanceof L.Circle;
}),
polygons: this.drawnItems.getLayers().filter(function(e) {
return e instanceof L.Polygon;
}),
polylines: this.drawnItems.getLayers().filter(function(e) {
return e instanceof L.Polyline && !(e instanceof L.Polygon);
})
};
},
@ -147,17 +182,17 @@ BR.NogoAreas = L.Control.extend({
}
},
_clear: function () {
_clear: function() {
this.drawnItems.clearLayers();
},
clear: function () {
clear: function() {
this._clear();
this._fireUpdate();
},
_fireUpdate: function () {
this.fire('update', {options: this.getOptions()});
_fireUpdate: function() {
this.fire('update', { options: this.getOptions() });
},
getFeatureGroup: function() {
@ -175,27 +210,32 @@ BR.NogoAreas = L.Control.extend({
BR.NogoAreas.include(L.Evented.prototype);
L.Editable.prototype.createVertexIcon = function (options) {
return BR.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
L.Editable.prototype.createVertexIcon = function(options) {
return BR.Browser.touch
? new L.Editable.TouchVertexIcon(options)
: new L.Editable.VertexIcon(options);
};
BR.EditingTooltip = L.Handler.extend({
options: {
closeTimeout: 2000
},
initialize: function (map, editTools, button) {
initialize: function(map, editTools, button) {
this.map = map;
this.editTools = editTools;
this.button = button;
},
addHooks: function () {
addHooks: function() {
// hack: listen to EasyButton click (instead of editable:drawing:start),
// to get mouse position from event for initial tooltip location
L.DomEvent.addListener(this.button.button, 'click', this._addCreate, this);
L.DomEvent.addListener(
this.button.button,
'click',
this._addCreate,
this
);
this.editTools.featuresLayer.on('layeradd', this._bind, this);
@ -204,8 +244,13 @@ BR.EditingTooltip = L.Handler.extend({
this.editTools.on('editable:disable', this._disable, this);
},
removeHooks: function () {
L.DomEvent.removeListener(this.button.button, 'click', this._addCreate, this);
removeHooks: function() {
L.DomEvent.removeListener(
this.button.button,
'click',
this._addCreate,
this
);
this.editTools.featuresLayer.off('layeradd', this._bind, this);
@ -214,7 +259,7 @@ BR.EditingTooltip = L.Handler.extend({
this.editTools.off('editable:disable', this._disable, this);
},
_bind: function (e) {
_bind: function(e) {
// Position tooltip at bottom of circle, less distracting than
// sticky with cursor or at center.
@ -226,18 +271,20 @@ BR.EditingTooltip = L.Handler.extend({
// Override to set position to south instead of center (circle latlng);
// works better with zooming than updating offset to match radius
layer.openTooltip = function (layer, latlng) {
layer.openTooltip = function(layer, latlng) {
if (!latlng && layer instanceof L.Layer) {
latlng = L.latLng(
layer.getBounds().getSouth(),
0.5 * (layer.getBounds().getWest() + layer.getBounds().getEast())
0.5 *
(layer.getBounds().getWest() +
layer.getBounds().getEast())
);
}
L.Layer.prototype.openTooltip.call(this, layer, latlng);
};
},
_addCreate: function (e) {
_addCreate: function(e) {
// button cancel
if (!this.editTools.drawing()) return;
@ -255,28 +302,32 @@ BR.EditingTooltip = L.Handler.extend({
tooltip._tooltip = tooltip;
// simulate sticky feature (follow mouse) for map tooltip without layer
var onOffMove = function (e) {
var onOff = (e.type === 'tooltipclose') ? 'off' : 'on';
var onOffMove = function(e) {
var onOff = e.type === 'tooltipclose' ? 'off' : 'on';
this._map[onOff]('mousemove', this._moveTooltip, this);
}
};
this.map.on('tooltipopen', onOffMove, tooltip);
this.map.on('tooltipclose', onOffMove, tooltip);
var onTooltipRemove = function (e) {
var onTooltipRemove = function(e) {
this.map.off('tooltipopen', onOffMove, e.tooltip);
this.map.off('tooltipclose', onOffMove, e.tooltip);
this.map.off('tooltipclose', onTooltipRemove, this);
e.tooltip._tooltip = null;
}
};
this.map.on('tooltipclose', onTooltipRemove, this);
tooltip.setTooltipContent(BR.NogoAreas.MSG_CREATE);
this.map.openTooltip(tooltip, initialLatLng);
var closeTooltip = function () {
var closeTooltip = function() {
this.map.closeTooltip(tooltip);
};
this.editTools.once('editable:editing editable:drawing:cancel', closeTooltip, this);
this.editTools.once(
'editable:editing editable:drawing:cancel',
closeTooltip,
this
);
if (BR.Browser.touch) {
// can't move with cursor on touch devices, so show at start pos for a few seconds
@ -285,51 +336,58 @@ BR.EditingTooltip = L.Handler.extend({
},
_setCloseTimeout: function(layer) {
var timeoutId = setTimeout(function () {
layer.closeTooltip();
var timeoutId = setTimeout(function() {
layer.closeTooltip();
}, this.options.closeTimeout);
// prevent timer to close tooltip that changed in the meantime
layer.once('tooltipopen', function (e) {
clearTimeout(timeoutId);
layer.once('tooltipopen', function(e) {
clearTimeout(timeoutId);
});
},
_postCreate: function () {
_postCreate: function() {
// editing is disabled by another handler, tooltip won't stay open before
this.editTools.once('editable:disable', function (e) {
// show for a few seconds, as mouse often not hovering circle after create
e.layer.openTooltip(e.layer);
this._setCloseTimeout(e.layer);
}, this);
this.editTools.once(
'editable:disable',
function(e) {
// show for a few seconds, as mouse often not hovering circle after create
e.layer.openTooltip(e.layer);
this._setCloseTimeout(e.layer);
},
this
);
},
_enable: function (e) {
_enable: function(e) {
e.layer.setTooltipContent(BR.NogoAreas.MSG_ENABLED);
this.editTools.once('editable:editing', function(e) {
e.layer.closeTooltip();
}, this);
this.editTools.once(
'editable:editing',
function(e) {
e.layer.closeTooltip();
},
this
);
},
_disable: function (e) {
_disable: function(e) {
e.layer.setTooltipContent(BR.NogoAreas.MSG_DISABLED);
this._setCloseTimeout(e.layer);
}
});
BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
_computeDeleteLatLng: function () {
_computeDeleteLatLng: function() {
// While circle is not added to the map, _radius is not set.
var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4),
var delta =
(this.feature._radius || this.feature._mRadius) *
Math.cos(Math.PI / 4),
point = this.map.project(this.feature._latlng);
return this.map.unproject([point.x - delta, point.y - delta]);
},
_updateDeleteLatLng: function () {
_updateDeleteLatLng: function() {
this._deleteLatLng.update(this._computeDeleteLatLng());
this._deleteLatLng.__vertex.update();
},
@ -350,15 +408,20 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
this.fireAndForward('editable:deleted');
},
initialize: function (map, feature, options) {
L.Editable.CircleEditor.prototype.initialize.call(this, map, feature, options);
initialize: function(map, feature, options) {
L.Editable.CircleEditor.prototype.initialize.call(
this,
map,
feature,
options
);
this._deleteLatLng = this._computeDeleteLatLng();
// FeatureGroup instead of LayerGroup to propagate events to members
this.editLayer = new L.FeatureGroup();
},
addHooks: function () {
addHooks: function() {
L.Editable.CircleEditor.prototype.addHooks.call(this);
if (this.feature) {
this._addDeleteMarker();
@ -366,12 +429,12 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
return this;
},
reset: function () {
reset: function() {
L.Editable.CircleEditor.prototype.reset.call(this);
this._addDeleteMarker();
},
onDrawingMouseDown: function (e) {
onDrawingMouseDown: function(e) {
this._deleteLatLng.update(e.latlng);
L.Editable.CircleEditor.prototype.onDrawingMouseDown.call(this, e);
},
@ -379,7 +442,7 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
// override to cancel/remove created circle when added by click instead of drag, because:
// - without resize, edit handles stacked on top of each other
// - makes event handling more complicated (editable:vertex:dragend not called)
onDrawingMouseUp: function (e) {
onDrawingMouseUp: function(e) {
if (this.feature.getRadius() > 0) {
this.commitDrawing(e);
} else {
@ -390,25 +453,24 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
},
onVertexMarkerDrag: function (e) {
onVertexMarkerDrag: function(e) {
this._updateDeleteLatLng();
L.Editable.CircleEditor.prototype.onVertexMarkerDrag.call(this, e);
}
});
BR.DeleteMarker = L.Marker.extend({
options: {
draggable: false,
icon: L.divIcon({
iconSize: BR.Browser.touch ? new L.Point(24, 24) : new L.Point(16, 16),
iconSize: BR.Browser.touch
? new L.Point(24, 24)
: new L.Point(16, 16),
className: 'leaflet-div-icon fa fa-trash-o nogo-delete-marker'
})
},
initialize: function (latlng, editor, options) {
initialize: function(latlng, editor, options) {
// derived from L.Editable.VertexMarker.initialize
// We don't use this._latlng, because on drag Leaflet replace it while
@ -425,18 +487,18 @@ BR.DeleteMarker = L.Marker.extend({
this.setZIndexOffset(editor.tools._lastZIndex);
},
onAdd: function (map) {
onAdd: function(map) {
L.Marker.prototype.onAdd.call(this, map);
this.on('click', this.onClick);
},
onRemove: function (map) {
onRemove: function(map) {
delete this.latlng.__vertex;
this.off('click', this.onClick);
L.Marker.prototype.onRemove.call(this, map);
},
onClick: function (e) {
onClick: function(e) {
this.editor.delete();
}
});

View file

@ -1,7 +1,7 @@
L.Routing.Draw.prototype._hideTrailer = function() {
if (this._trailer.options.opacity !== 0.0) {
this._trailer.setStyle({opacity: 0.0});
}
if (this._trailer.options.opacity !== 0.0) {
this._trailer.setStyle({ opacity: 0.0 });
}
};
BR.Routing = L.Routing.extend({
@ -20,7 +20,7 @@ BR.Routing = L.Routing.extend({
zIndexOffset: -2000
},
onAdd: function (map) {
onAdd: function(map) {
this._segmentsCasing = new L.FeatureGroup().addTo(map);
var container = L.Routing.prototype.onAdd.call(this, map);
@ -31,35 +31,50 @@ BR.Routing = L.Routing.extend({
this._waypoints.on('layeradd', this._setMarkerOpacity, this);
// turn line mouse marker off while over waypoint marker
this.on('waypoint:mouseover', function(e) {
// L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw)
if (this._dragging) { return; }
this.on(
'waypoint:mouseover',
function(e) {
// L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw)
if (this._dragging) {
return;
}
this._mouseMarker.setOpacity(0.0);
this._map.off('mousemove', this._segmentOnMousemove, this);
this._suspended = true;
}, this._edit);
this._mouseMarker.setOpacity(0.0);
this._map.off('mousemove', this._segmentOnMousemove, this);
this._suspended = true;
},
this._edit
);
this.on('waypoint:mouseout', function(e) {
this._segmentOnMouseover(e);
this._suspended = false;
}, this._edit);
this.on(
'waypoint:mouseout',
function(e) {
this._segmentOnMouseover(e);
this._suspended = false;
},
this._edit
);
this._edit._mouseMarker.setIcon(L.divIcon({
className: 'line-mouse-marker'
,iconAnchor: [8, 8] // size/2 + border/2
,iconSize: [16, 16]
}));
this._edit._mouseMarker.setIcon(
L.divIcon({
className: 'line-mouse-marker',
iconAnchor: [8, 8], // size/2 + border/2
iconSize: [16, 16]
})
);
// Forward mousemove event to snapped feature (for Leaflet.Elevation to
// update indicator), see also L.Routing.Edit._segmentOnMousemove
this._edit._mouseMarker.on('move', L.bind(function(e) {
var latLng = e.latlng;
if (latLng._feature) {
this._mouseMarker._feature = latLng._feature;
latLng._feature.fire('mousemove', e, true);
}
}, this._edit));
this._edit._mouseMarker.on(
'move',
L.bind(function(e) {
var latLng = e.latlng;
if (latLng._feature) {
this._mouseMarker._feature = latLng._feature;
latLng._feature.fire('mousemove', e, true);
}
}, this._edit)
);
var mouseoutHandler = function(e) {
if (this._mouseMarker._feature) {
this._mouseMarker._feature.fire('mouseout', e, true);
@ -79,12 +94,20 @@ BR.Routing = L.Routing.extend({
// intercept listener: only re-show draw trailer after marker hover
// when edit is not active (i.e. wasn't also supended)
this._parent.off('waypoint:mouseout' , this._catchWaypointEvent, this);
this.on('waypoint:mouseout' , function(e) {
if (!this._parent._edit._suspended) {
this._catchWaypointEvent(e);
}
}, this);
this._parent.off(
'waypoint:mouseout',
this._catchWaypointEvent,
this
);
this.on(
'waypoint:mouseout',
function(e) {
if (!this._parent._edit._suspended) {
this._catchWaypointEvent(e);
}
},
this
);
});
this._draw.on('disabled', function() {
L.DomUtil.removeClass(map.getContainer(), 'routing-draw-enabled');
@ -111,7 +134,12 @@ BR.Routing = L.Routing.extend({
this._map.off('mouseout', hide, this);
this._map.off('mouseover', show, this);
L.DomEvent.off(this._map._controlContainer, 'mouseout', show, this);
L.DomEvent.off(this._map._controlContainer, 'mouseover', hide, this);
L.DomEvent.off(
this._map._controlContainer,
'mouseover',
hide,
this
);
});
// Call show after deleting last waypoint, but hide trailer.
@ -119,191 +147,209 @@ BR.Routing = L.Routing.extend({
// mouseout to show again never fires when deleted. Click handler
// _onMouseClick aborts when hidden, so no waypoint can be added
// although enabled.
this.on('waypoint:click', function() {
if (this._hidden && !this._parent._waypoints._first) {
this._show();
this._hideTrailer();
}
}, this._draw);
this.on(
'waypoint:click',
function() {
if (this._hidden && !this._parent._waypoints._first) {
this._show();
this._hideTrailer();
}
},
this._draw
);
// keys not working when map container does not have focus, use document instead
L.DomEvent.removeListener(this._container, 'keyup', this._keyupListener);
L.DomEvent.removeListener(
this._container,
'keyup',
this._keyupListener
);
L.DomEvent.addListener(document, 'keyup', this._keyupListener, this);
// enable drawing mode
this.draw(true);
return container;
}
},
,_addSegmentCasing: function(e) {
var casing = L.polyline(e.layer.getLatLngs(), this.options.styles.trackCasing);
this._segmentsCasing.addLayer(casing);
e.layer._casing = casing;
this._segments.bringToFront();
}
_addSegmentCasing: function(e) {
var casing = L.polyline(
e.layer.getLatLngs(),
this.options.styles.trackCasing
);
this._segmentsCasing.addLayer(casing);
e.layer._casing = casing;
this._segments.bringToFront();
},
,_removeSegmentCasing: function(e) {
this._segmentsCasing.removeLayer(e.layer._casing);
}
_removeSegmentCasing: function(e) {
this._segmentsCasing.removeLayer(e.layer._casing);
},
,setOpacity: function(opacity) {
// Due to the second Polyline layer for casing, the combined opacity is less
// transparent than with a single layer and the slider is non-linear. The
// inverted formula is used to get the same result as with a single layer.
// SVG simple alpha compositing: Ca' = 1 - (1 - Ea) * (1 - Ca)
// https://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending
var sourceOpacity = 1 - Math.sqrt(1 - opacity);
setOpacity: function(opacity) {
// Due to the second Polyline layer for casing, the combined opacity is less
// transparent than with a single layer and the slider is non-linear. The
// inverted formula is used to get the same result as with a single layer.
// SVG simple alpha compositing: Ca' = 1 - (1 - Ea) * (1 - Ca)
// https://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending
var sourceOpacity = 1 - Math.sqrt(1 - opacity);
this.options.styles.track.opacity = sourceOpacity;
this.options.styles.trackCasing.opacity = sourceOpacity;
this.options.icons.opacity = opacity;
this.options.styles.track.opacity = sourceOpacity;
this.options.styles.trackCasing.opacity = sourceOpacity;
this.options.icons.opacity = opacity;
this._segments.setStyle({
opacity: sourceOpacity
});
this._segmentsCasing.setStyle({
opacity: sourceOpacity
});
this._waypoints.eachLayer(function(marker) {
marker.setOpacity(opacity);
});
}
,_setMarkerOpacity: function(e) {
e.layer.setOpacity(this.options.icons.opacity);
}
,_removeMarkerEvents: function(marker) {
marker.off('mouseover', this._fireWaypointEvent, this);
marker.off('mouseout' , this._fireWaypointEvent, this);
marker.off('dragstart', this._fireWaypointEvent, this);
marker.off('dragend' , this._fireWaypointEvent, this);
marker.off('drag' , this._fireWaypointEvent, this);
marker.off('click' , this._fireWaypointEvent, this);
}
,clear: function() {
var drawEnabled = this._draw._enabled;
var current = this._waypoints._first;
this.draw(false);
if (current === null) { return; }
this._removeMarkerEvents(current);
while (current._routing.nextMarker) {
var marker = current._routing.nextMarker;
this._removeMarkerEvents(marker);
current = marker;
};
this._waypoints._first = null;
this._waypoints._last = null;
this._waypoints.clearLayers();
this._segments.clearLayers();
if (drawEnabled) {
this.draw(true);
}
}
,setWaypoints: function(latLngs, cb) {
var i;
var callbackCount = 0;
var firstErr;
var $this = this;
var callback = function(err, data) {
callbackCount++;
firstErr = firstErr || err;
if (callbackCount >= latLngs.length) {
$this.fire('routing:setWaypointsEnd', { err: firstErr });
if (cb) {
cb(firstErr);
}
}
};
this.fire('routing:setWaypointsStart');
for (i = 0; latLngs && i < latLngs.length; i++) {
this.addWaypoint(latLngs[i], this._waypoints._last, null, callback);
}
}
// patch to fix error when line is null or error line
// (when called while still segments to calculate, e.g. permalink or fast drawing)
,toPolyline: function() {
var latLngs = [];
this._eachSegment(function(m1, m2, line) {
// omit if null (still calculating) or error
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
if (line && line.feature) {
latLngs = latLngs.concat(line.getLatLngs());
}
});
return L.polyline(latLngs);
}
,_routeSegment: function(m1, m2, cb) {
var loadingTrailer;
// change segment color before request to indicate recalculation (mark old)
if (m1 && m1._routing.nextLine !== null) {
m1._routing.nextLine.setStyle({color: 'dimgray' });
}
// animate dashed trailer as loading indicator
if (m1 && m2) {
loadingTrailer = new L.Polyline([m1.getLatLng(), m2.getLatLng()], {
color: this.options.styles.track.color,
opacity: this.options.styles.trailer.opacity,
dashArray: [10, 10],
className: 'loading-trailer'
this._segments.setStyle({
opacity: sourceOpacity
});
loadingTrailer.addTo(this._map);
}
this._segmentsCasing.setStyle({
opacity: sourceOpacity
});
this._waypoints.eachLayer(function(marker) {
marker.setOpacity(opacity);
});
},
L.Routing.prototype._routeSegment.call(this, m1, m2, L.bind(function(err, data) {
if (loadingTrailer) {
this._map.removeLayer(loadingTrailer);
_setMarkerOpacity: function(e) {
e.layer.setOpacity(this.options.icons.opacity);
},
_removeMarkerEvents: function(marker) {
marker.off('mouseover', this._fireWaypointEvent, this);
marker.off('mouseout', this._fireWaypointEvent, this);
marker.off('dragstart', this._fireWaypointEvent, this);
marker.off('dragend', this._fireWaypointEvent, this);
marker.off('drag', this._fireWaypointEvent, this);
marker.off('click', this._fireWaypointEvent, this);
},
clear: function() {
var drawEnabled = this._draw._enabled;
var current = this._waypoints._first;
this.draw(false);
if (current === null) {
return;
}
this._removeMarkerEvents(current);
while (current._routing.nextMarker) {
var marker = current._routing.nextMarker;
this._removeMarkerEvents(marker);
current = marker;
}
cb(err, data);
}, this));
}
,getSegments: function() {
var segments = [];
this._waypoints._first = null;
this._waypoints._last = null;
this._waypoints.clearLayers();
this._segments.clearLayers();
this._eachSegment(function(m1, m2, line) {
// omit if null (still calculating) or error
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
if (line && line.feature) {
segments.push(line);
}
});
if (drawEnabled) {
this.draw(true);
}
},
return segments;
}
setWaypoints: function(latLngs, cb) {
var i;
var callbackCount = 0;
var firstErr;
var $this = this;
// add 'esc' to disable drawing
,_keyupListener: function (e) {
if (e.keyCode === 27) {
this._draw.disable();
} else {
L.Routing.prototype._keyupListener.call(this, e);
var callback = function(err, data) {
callbackCount++;
firstErr = firstErr || err;
if (callbackCount >= latLngs.length) {
$this.fire('routing:setWaypointsEnd', { err: firstErr });
if (cb) {
cb(firstErr);
}
}
};
this.fire('routing:setWaypointsStart');
for (i = 0; latLngs && i < latLngs.length; i++) {
this.addWaypoint(latLngs[i], this._waypoints._last, null, callback);
}
},
// patch to fix error when line is null or error line
// (when called while still segments to calculate, e.g. permalink or fast drawing)
toPolyline: function() {
var latLngs = [];
this._eachSegment(function(m1, m2, line) {
// omit if null (still calculating) or error
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
if (line && line.feature) {
latLngs = latLngs.concat(line.getLatLngs());
}
});
return L.polyline(latLngs);
},
_routeSegment: function(m1, m2, cb) {
var loadingTrailer;
// change segment color before request to indicate recalculation (mark old)
if (m1 && m1._routing.nextLine !== null) {
m1._routing.nextLine.setStyle({ color: 'dimgray' });
}
// animate dashed trailer as loading indicator
if (m1 && m2) {
loadingTrailer = new L.Polyline([m1.getLatLng(), m2.getLatLng()], {
color: this.options.styles.track.color,
opacity: this.options.styles.trailer.opacity,
dashArray: [10, 10],
className: 'loading-trailer'
});
loadingTrailer.addTo(this._map);
}
L.Routing.prototype._routeSegment.call(
this,
m1,
m2,
L.bind(function(err, data) {
if (loadingTrailer) {
this._map.removeLayer(loadingTrailer);
}
cb(err, data);
}, this)
);
},
getSegments: function() {
var segments = [];
this._eachSegment(function(m1, m2, line) {
// omit if null (still calculating) or error
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
if (line && line.feature) {
segments.push(line);
}
});
return segments;
},
// add 'esc' to disable drawing
_keyupListener: function(e) {
if (e.keyCode === 27) {
this._draw.disable();
} else {
L.Routing.prototype._keyupListener.call(this, e);
}
},
isDrawing: function() {
return this._draw._enabled;
},
reverse: function() {
var waypoints = this.getWaypoints();
waypoints.reverse();
this.clear();
this.setWaypoints(waypoints);
}
}
,isDrawing: function () {
return this._draw._enabled;
}
,reverse: function() {
var waypoints = this.getWaypoints();
waypoints.reverse();
this.clear();
this.setWaypoints(waypoints);
}
});

View file

@ -3,7 +3,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
options: {
position: 'right',
container: 'sidebar',
container: 'sidebar',
tabContainer: 'sidebarTabs',
autopan: false,
defaultTabId: '',
@ -13,26 +13,34 @@ BR.Sidebar = L.Control.Sidebar.extend({
listeningTabs: {}
},
initialize: function (id, options) {
initialize: function(id, options) {
L.Control.Sidebar.prototype.initialize.call(this, id, options);
this.oldTab = null;
},
addTo: function (map) {
addTo: function(map) {
L.Control.Sidebar.prototype.addTo.call(this, map);
this.on('content', this._notifyOnContent, this);
this.on('closing', this._notifyOnClose, this);
this.on('toggleExpand', this._notifyOnResize, this);
this.on('closing', function () {
this._map.getContainer().focus();
}, this);
this.on(
'closing',
function() {
this._map.getContainer().focus();
},
this
);
this._rememberTabState();
if (L.Browser.touch && BR.Browser.touchScreenDetectable && !BR.Browser.touchScreen) {
if (
L.Browser.touch &&
BR.Browser.touchScreenDetectable &&
!BR.Browser.touchScreen
) {
L.DomUtil.removeClass(this._container, 'leaflet-touch');
L.DomUtil.removeClass(this._tabContainer, 'leaflet-touch');
}
@ -47,12 +55,12 @@ BR.Sidebar = L.Control.Sidebar.extend({
return this;
},
_rememberTabState: function () {
_rememberTabState: function() {
if (BR.Util.localStorageAvailable()) {
this.on('content closing', this._storeActiveTab, this);
var tabId = localStorage.getItem(this.storageId);
// 'true': legacy value for toggling old sidebar
if (tabId === 'true') {
tabId = this.options.defaultTabId;
@ -66,42 +74,42 @@ BR.Sidebar = L.Control.Sidebar.extend({
}
},
_notifyShow: function (tab) {
_notifyShow: function(tab) {
if (tab && tab.show) {
tab.show();
}
},
_notifyHide: function (tab) {
_notifyHide: function(tab) {
if (tab && tab.hide) {
tab.hide();
}
},
_notifyOnContent: function (e) {
_notifyOnContent: function(e) {
var tab = this.options.listeningTabs[e.id];
this._notifyHide(this.oldTab);
this._notifyShow(tab);
this.oldTab = tab;
},
_notifyOnClose: function (e) {
_notifyOnClose: function(e) {
this._notifyHide(this.oldTab);
this.oldTab = null;
},
_notifyOnResize: function (e) {
_notifyOnResize: function(e) {
var tab = this.oldTab;
if (tab && tab.onResize) {
tab.onResize();
}
},
_storeActiveTab: function (e) {
_storeActiveTab: function(e) {
localStorage.setItem(this.storageId, e.id || '');
}
});
BR.sidebar = function (divId, options) {
BR.sidebar = function(divId, options) {
return new BR.Sidebar(divId, options);
};

View file

@ -1,8 +1,9 @@
(function(window) {
var HAS_HASHCHANGE = (function() {
var doc_mode = window.documentMode;
return ('onhashchange' in window) &&
(doc_mode === undefined || doc_mode > 7);
return (
'onhashchange' in window && (doc_mode === undefined || doc_mode > 7)
);
})();
L.Hash = function(map, options) {
@ -14,17 +15,17 @@
};
L.Hash.parseHash = function(hash) {
if(hash.indexOf('#map=') === 0) {
if (hash.indexOf('#map=') === 0) {
hash = hash.substr(5);
}
var args = hash.split(/\&(.+)/);
var mapsArgs = args[0].split("/");
var mapsArgs = args[0].split('/');
if (mapsArgs.length == 4) {
var zoom = parseInt(mapsArgs[0], 10),
lat = parseFloat(mapsArgs[1]),
lon = parseFloat(mapsArgs[2]),
layers = this.parseLayers(mapsArgs[3]),
additional = args[1];
lat = parseFloat(mapsArgs[1]),
lon = parseFloat(mapsArgs[2]),
layers = this.parseLayers(mapsArgs[3]),
additional = args[1];
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
return false;
} else {
@ -40,7 +41,7 @@
}
};
L.Hash.formatHash = function(map) {
(L.Hash.formatHash = function(map) {
var center = map.getCenter(),
zoom = map.getZoom(),
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)),
@ -52,7 +53,7 @@
center.lng.toFixed(precision),
layers
];
url = "#map=" + params.join("/");
url = '#map=' + params.join('/');
if (this.additionalCb != null) {
var additional = this.additionalCb();
if (additional != null) {
@ -60,232 +61,261 @@
}
}
return url;
},
}),
(L.Hash.prototype = {
options: {
layerSeparator: ','
},
map: null,
lastHash: null,
L.Hash.prototype = {
options: {
layerSeparator: ','
},
map: null,
lastHash: null,
parseHash: L.Hash.parseHash,
formatHash: L.Hash.formatHash,
parseHash: L.Hash.parseHash,
formatHash: L.Hash.formatHash,
init: function(map, options) {
this.map = map;
L.Util.setOptions(this, options);
init: function(map, options) {
this.map = map;
L.Util.setOptions(this, options);
// reset the hash
this.lastHash = null;
this.onHashChange();
// reset the hash
this.lastHash = null;
this.onHashChange();
if (!this.isListening) {
this.startListening();
}
},
if (!this.isListening) {
this.startListening();
}
},
_parseLayers: function(layersParam, layerSeparator) {
var layers = layersParam.split(layerSeparator).map(
L.bind(function(layerEncoded) {
var obj = null;
var layerString = decodeURIComponent(layerEncoded);
_parseLayers: function (layersParam, layerSeparator) {
var layers = layersParam.split(layerSeparator).map(L.bind(function (layerEncoded) {
var obj = null;
var layerString = decodeURIComponent(layerEncoded);
if (layerString) {
obj = this._getLayerFromString(layerString);
}
if (layerString) {
obj = this._getLayerFromString(layerString);
return obj;
}, this)
);
return layers;
},
parseLayers: function(layersParam) {
var countFoundLayers = function(count, obj) {
if (obj) {
count++;
}
return count;
};
var layers = this._parseLayers(
layersParam,
this.options.layerSeparator
);
var found = layers.reduce(countFoundLayers, 0);
if (found < layers.length) {
// legacy support for name instead of id and '-' layer separator
var layersLegacy = this._parseLayers(layersParam, '-');
var foundLegacy = layersLegacy.reduce(countFoundLayers, 0);
if (foundLegacy > found) {
layers = layersLegacy;
}
}
return layers;
},
activateLayers: function(layers) {
var layersControl = this.options.layersControl;
var added = false;
layersControl.removeActiveLayers();
layers.forEach(
L.bind(function(obj, index, array) {
if (obj) {
layersControl.activateLayer(obj.layer);
if (obj && !obj.overlay) {
added = true;
}
}
}, this)
);
if (!added) {
// if we couldn't add layers (removed or invalid name), add the default one
layersControl.activateDefaultBaseLayer();
}
},
formatLayers: function() {
var objList = this.options.layersControl.getActiveLayers();
var layerList = objList.map(
L.bind(function(obj) {
return encodeURIComponent(this._toLayerString(obj));
}, this)
);
return layerList.join(this.options.layerSeparator);
},
_toLayerString: function(obj) {
return obj.layer.id ? obj.layer.id : obj.name;
},
_getLayerFromString: function(layerString) {
var layersControl = this.options.layersControl;
var obj = layersControl.getLayerById(layerString);
if (!obj) {
// fallback to name for custom and config layers
obj = layersControl.getLayer(layerString);
if (!obj) {
// legacy layer name support
obj = layersControl.getLayerByLegacyName(layerString);
}
}
return obj;
}, this));
},
return layers;
},
parseLayers: function (layersParam) {
var countFoundLayers = function (count, obj) {
if (obj) {
count++;
removeFrom: function(map) {
if (this.changeTimeout) {
clearTimeout(this.changeTimeout);
}
return count;
};
var layers = this._parseLayers(layersParam, this.options.layerSeparator);
var found = layers.reduce(countFoundLayers, 0);
if (found < layers.length) {
// legacy support for name instead of id and '-' layer separator
var layersLegacy = this._parseLayers(layersParam, '-');
var foundLegacy = layersLegacy.reduce(countFoundLayers, 0);
if (foundLegacy > found) {
layers = layersLegacy;
if (this.isListening) {
this.stopListening();
}
}
return layers;
},
this.map = null;
},
activateLayers: function (layers) {
var layersControl = this.options.layersControl;
var added = false;
onMapMove: function() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
layersControl.removeActiveLayers();
if (this.movingMap || !this.map._loaded) {
return false;
}
layers.forEach(L.bind(function(obj, index, array) {
if (obj) {
layersControl.activateLayer(obj.layer);
if (obj && !obj.overlay) {
added = true;
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) {
// migration from old hash style to new one
if (this.onInvalidHashChangeCb != null) {
var newHash = this.onInvalidHashChangeCb(hash);
if (newHash != null && newHash != hash) {
parsed = this.parseHash(newHash);
}
}
}
}, this));
if (!added) {
// if we couldn't add layers (removed or invalid name), add the default one
layersControl.activateDefaultBaseLayer();
}
},
if (parsed) {
this.movingMap = true;
formatLayers: function () {
var objList = this.options.layersControl.getActiveLayers();
var layerList = objList.map(L.bind(function (obj) {
return encodeURIComponent(this._toLayerString(obj));
}, this));
this.map.setView(parsed.center, parsed.zoom);
return layerList.join(this.options.layerSeparator)
},
this.activateLayers(parsed.layers);
_toLayerString: function (obj) {
return obj.layer.id ? obj.layer.id : obj.name;
},
if (this.onHashChangeCb != null) {
this.onHashChangeCb(parsed.additional);
}
_getLayerFromString: function (layerString) {
var layersControl = this.options.layersControl;
var obj = layersControl.getLayerById(layerString);
if (!obj) {
// fallback to name for custom and config layers
obj = layersControl.getLayer(layerString);
if (!obj) {
// legacy layer name support
obj = layersControl.getLayerByLegacyName(layerString);
this.movingMap = false;
} else {
this.onMapMove(this.map);
}
}
},
return obj;
},
// 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);
}
},
removeFrom: function(map) {
if (this.changeTimeout) {
clearTimeout(this.changeTimeout);
}
isListening: false,
hashChangeInterval: null,
startListening: function() {
this.map.on(
'moveend layeradd layerremove',
this.onMapMove,
this
);
if (this.isListening) {
this.stopListening();
}
if (HAS_HASHCHANGE) {
L.DomEvent.addListener(
window,
'hashchange',
this.onHashChange
);
} else {
clearInterval(this.hashChangeInterval);
this.hashChangeInterval = setInterval(
this.onHashChange,
50
);
}
this.isListening = true;
},
this.map = null;
},
stopListening: function() {
this.map.off(
'moveend layeradd layerremove',
this.onMapMove,
this
);
onMapMove: function() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
if (HAS_HASHCHANGE) {
L.DomEvent.removeListener(
window,
'hashchange',
this.onHashChange
);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
},
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) {
// migration from old hash style to new one
if (this.onInvalidHashChangeCb != null) {
var newHash = this.onInvalidHashChangeCb(hash);
if (newHash != null && newHash != hash) {
parsed = this.parseHash(newHash);
_keyByValue: function(obj, value) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] === value) {
return key;
} else {
return null;
}
}
}
}
if (parsed) {
this.movingMap = true;
this.map.setView(parsed.center, parsed.zoom);
this.activateLayers(parsed.layers);
if (this.onHashChangeCb != null) {
this.onHashChangeCb(parsed.additional);
}
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 layeradd layerremove", 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 layeradd layerremove", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
},
_keyByValue: function(obj, value) {
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] === value) {
return key;
} else { return null; };
};
};
}
};
});
L.hash = function(map, options) {
return new L.Hash(map, options);
};

View file

@ -1,18 +1,26 @@
BR.stravaSegments = function (map, layersControl) {
const stravaControl = L.control.stravaSegments({
runningTitle: i18next.t('map.strava-running'),
bikingTitle: i18next.t('map.strava-biking'),
loadingTitle: i18next.t('map.loading'),
stravaToken: BR.keys.strava
})
.addTo(map);
layersControl.addOverlay(stravaControl.stravaLayer, i18next.t('map.layer.strava-segments'));
BR.stravaSegments = function(map, layersControl) {
const stravaControl = L.control
.stravaSegments({
runningTitle: i18next.t('map.strava-running'),
bikingTitle: i18next.t('map.strava-biking'),
loadingTitle: i18next.t('map.loading'),
stravaToken: BR.keys.strava
})
.addTo(map);
layersControl.addOverlay(
stravaControl.stravaLayer,
i18next.t('map.layer.strava-segments')
);
stravaControl.onError = function(err) {
BR.message.showError(i18next.t('warning.strava-error', {error: err && err.message ? err.message : err}));
}
BR.message.showError(
i18next.t('warning.strava-error', {
error: err && err.message ? err.message : err
})
);
};
// hide strava buttons when layer is inactive
var toggleStravaControl = function () {
var toggleStravaControl = function() {
var stravaBar = stravaControl.runningButton.button.parentElement;
stravaBar.hidden = !stravaBar.hidden;
};