' + data.replace('');
var user_data = html.find('[data-user-data]');
if (user_data.length) {
c3nav._set_user_data(JSON.parse(user_data.attr('data-user-data')));
}
c3nav._set_modal_content(html.find('main').html());
},
- _modal_error: function(data) {
- $('#modal').removeClass('loading').find('#modal-content').html('
Error '+data.status+'
');
+ _modal_error: function (data) {
+ $('#modal').removeClass('loading').find('#modal-content').html('
Error ' + data.status + '
');
},
// map
@@ -1420,6 +1425,8 @@ c3nav = {
$('.leaflet-touch').removeClass('leaflet-touch');
}
+ c3nav.create_key(c3nav.theme);
+
c3nav.map.fitBounds(L.GeoJSON.coordsToLatLngs(c3nav.initial_bounds), c3nav._add_map_padding({}));
c3nav.map.on('moveend', c3nav._map_moved);
@@ -1479,12 +1486,12 @@ c3nav = {
},
theme: 0,
- setTheme: function(id) {
+ setTheme: function (id) {
if (id === c3nav.theme) return;
c3nav.theme = id;
const theme = c3nav.themes[id];
if (!theme.funky) {
- c3nav_api.post('settings/theme/?id='+id);
+ c3nav_api.post('settings/theme/?id=' + id);
localStorageWrapper.setItem('c3nav-theme', c3nav.theme); // TODO: instead (or additionally?) do a request to save it in the session!
}
document.querySelector('#c3nav-theme-vars').innerText = theme.css;
@@ -1493,8 +1500,9 @@ c3nav = {
document.querySelector('#theme-color-meta-light').content = theme.theme_color_light;
c3nav._levelControl.setTheme(id);
+ c3nav.create_key(id);
},
- show_theme_select: function(e) {
+ show_theme_select: function (e) {
e.preventDefault();
c3nav.open_modal(document.querySelector('main>.theme-selection').outerHTML);
const select = document.querySelector('#modal .theme-selection select');
@@ -1510,30 +1518,51 @@ c3nav = {
currentThemeOption.selected = true;
}
},
- select_theme: function(e) {
+ select_theme: function (e) {
const themeId = e.target.parentElement.querySelector('select').value;
c3nav.setTheme(themeId);
history.back(); // close the modal
},
+ key_control: null,
+ create_key: function (theme_id) {
+ c3nav_api.get(`map/legend/${theme_id}/`)
+ .then(key => {
+ const entries = [...key.base, ...key.groups, ...key.obstacles];
+ const key_control = new KeyControl();
+ for (let entry of entries) {
+ key_control.addKey(entry.title, entry.fill, entry.border);
+ }
+ if (c3nav.key_control !== null) {
+ c3nav.map.removeControl(c3nav.key_control);
+ }
+ if (entries.length > 0) {
+ c3nav.key_control = key_control;
+ key_control.addTo(c3nav.map);
+ }
+ });
+ },
+
_click_anywhere_popup: null,
- _click_anywhere: function(e) {
+ _click_anywhere: function (e) {
if (e.originalEvent.target.id !== 'map') return;
if (c3nav.embed) return;
c3nav._click_anywhere_load(false, e.latlng);
},
- _latlng_to_name: function(latlng) {
+ _latlng_to_name: function (latlng) {
var level = c3nav.current_level();
- return 'c:'+String(c3nav.level_labels_by_id[level])+':'+Math.round(latlng.lng*100)/100+':'+Math.round(latlng.lat*100)/100;
+ return 'c:' + String(c3nav.level_labels_by_id[level]) + ':' + Math.round(latlng.lng * 100) / 100 + ':' + Math.round(latlng.lat * 100) / 100;
},
- _click_anywhere_load: function(nearby, latlng) {
+ _click_anywhere_load: function (nearby, latlng) {
if (!c3nav._click_anywhere_popup && !latlng) return;
if (latlng === undefined) latlng = c3nav._click_anywhere_popup.getLatLng();
if (c3nav._click_anywhere_popup) c3nav._click_anywhere_popup.remove();
var popup = L.popup().setLatLng(latlng).setContent('
'),
name = c3nav._latlng_to_name(latlng);
c3nav._click_anywhere_popup = popup;
- popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map);
+ popup.on('remove', function () {
+ c3nav._click_anywhere_popup = null
+ }).openOn(c3nav.map);
c3nav_api.get(`map/locations/${name}/`)
.then(data => {
if (c3nav._click_anywhere_popup !== popup || !popup.isOpen()) return;
@@ -1556,7 +1585,7 @@ c3nav = {
}).openOn(c3nav.map);
}
})
- .catch(function() {
+ .catch(function () {
popup.remove();
});
},
@@ -1569,9 +1598,9 @@ c3nav = {
c3nav.update_location_labels();
},
_add_icon: function (name) {
- c3nav[name+'Icon'] = new L.Icon({
- iconUrl: '/static/img/marker-icon-'+name+'.png',
- iconRetinaUrl: '/static/img/marker-icon-'+name+'-2x.png',
+ c3nav[name + 'Icon'] = new L.Icon({
+ iconUrl: '/static/img/marker-icon-' + name + '.png',
+ iconRetinaUrl: '/static/img/marker-icon-' + name + '-2x.png',
shadowUrl: '/static/leaflet/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
@@ -1613,7 +1642,7 @@ c3nav = {
}
c3nav._locationLayerBounds = bounds;
},
- fly_to_bounds: function(replace_state, nofly) {
+ fly_to_bounds: function (replace_state, nofly) {
// fly to the bounds of the current overlays
var level = c3nav.current_level(),
bounds = null;
@@ -1636,9 +1665,9 @@ c3nav = {
var target = c3nav.map._getBoundsCenterZoom(bounds, c3nav._add_map_padding({}));
var center = c3nav.map._limitCenter(target.center, target.zoom, c3nav.map.options.maxBounds);
if (nofly) {
- c3nav.map.flyTo(center, target.zoom, { animate: false });
+ c3nav.map.flyTo(center, target.zoom, {animate: false});
} else {
- c3nav.map.flyTo(center, target.zoom, { duration: 1 });
+ c3nav.map.flyTo(center, target.zoom, {duration: 1});
}
if (replace_state) {
@@ -1646,7 +1675,7 @@ c3nav = {
}
}
},
- _add_map_padding: function(options, topleft, bottomright) {
+ _add_map_padding: function (options, topleft, bottomright) {
// add padding information for the current ui layout to fitBounds options
var $search = $('#search'),
$main = $('main'),
@@ -1654,26 +1683,26 @@ c3nav = {
$main.width() > 1000 &&
($main.height() < 250 || c3nav.state.details || c3nav.state.options)
),
- left = padBesideSidebar ? ($search.width() || 0)+10 : 0,
- top = padBesideSidebar ? 10 : ($search.height() || 0)+10;
+ left = padBesideSidebar ? ($search.width() || 0) + 10 : 0,
+ top = padBesideSidebar ? 10 : ($search.height() || 0) + 10;
if ('maxWidth' in options) {
- options.maxWidth = Math.min(options.maxWidth, $main.width()-left-13-50)
+ options.maxWidth = Math.min(options.maxWidth, $main.width() - left - 13 - 50)
}
- options[topleft || 'paddingTopLeft'] = L.point(left+13, top+41);
+ options[topleft || 'paddingTopLeft'] = L.point(left + 13, top + 41);
options[bottomright || 'paddingBottomRight'] = L.point(50, 20);
return options;
},
- _get_padded_max_bounds: function(zoom) {
+ _get_padded_max_bounds: function (zoom) {
if (zoom === undefined) zoom = c3nav.map.getZoom();
var bounds = c3nav.bounds,
factor = Math.pow(2, zoom);
return [
- [bounds[0][0]-600/factor, bounds[0][1]-200/factor],
- [bounds[1][0]+600/factor, bounds[1][1]+200/factor]
+ [bounds[0][0] - 600 / factor, bounds[0][1] - 200 / factor],
+ [bounds[1][0] + 600 / factor, bounds[1][1] + 200 / factor]
];
},
_location_point_overrides: {},
- _add_location_to_map: function(location, icon, no_geometry) {
+ _add_location_to_map: function (location, icon, no_geometry) {
if (!location) {
// if location is not in the searchable list...
return
@@ -1707,13 +1736,13 @@ c3nav = {
let buttons_html = '';
if (!c3nav.embed) {
let buttons = $('#location-popup-buttons').clone();
- buttons.find('.report').attr('href', '/report/l/'+String(location.id)+'/');
+ buttons.find('.report').attr('href', '/report/l/' + String(location.id) + '/');
buttons_html = buttons.html();
}
L.marker(latlng, {
icon: icon
- }).bindPopup(location.elem+buttons_html, c3nav._add_map_padding({
+ }).bindPopup(location.elem + buttons_html, c3nav._add_map_padding({
className: 'location-popup',
maxWidth: 500
}, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight')).addTo(c3nav._locationLayers[location.point[0]]);
@@ -1724,18 +1753,18 @@ c3nav = {
);
return result
},
- _merge_bounds: function(bounds, new_bounds) {
+ _merge_bounds: function (bounds, new_bounds) {
for (var level_id in new_bounds) {
bounds[level_id] = bounds[level_id] ? bounds[level_id].extend(new_bounds[level_id]) : new_bounds[level_id];
}
},
- _dynamic_location_loaded: function(data) {
+ _dynamic_location_loaded: function (data) {
if (c3nav._maybe_update_dynamic_location($('#origin-input'), data) || c3nav._maybe_update_dynamic_location($('#destination-input'), data)) {
c3nav.update_state();
c3nav.fly_to_bounds(true);
}
},
- _maybe_update_dynamic_location: function(elem, location) {
+ _maybe_update_dynamic_location: function (elem, location) {
if (elem.is('.empty')) return false;
var orig_location = elem.data('location');
if (orig_location.id !== location.id) return false;
@@ -1745,7 +1774,7 @@ c3nav = {
return true;
},
- _location_geometry_loaded: function(data) {
+ _location_geometry_loaded: function (data) {
if (c3nav._visible_map_locations.indexOf(data.id) === -1 || data.geometry === null || data.level === null) return;
if (data.geometry.type === "Point") return;
@@ -1773,7 +1802,7 @@ c3nav = {
c3nav._fetch_updates_failure_count++;
waittime = Math.min(5 + c3nav._fetch_updates_failure_count * 5, 120);
// console.log('fetch updates failed, retying in ' + waittime + 'sec');
- c3nav.schedule_fetch_updates(waittime*1000);
+ c3nav.schedule_fetch_updates(waittime * 1000);
});
},
resume_level: null,
@@ -1791,12 +1820,12 @@ c3nav = {
}
c3nav._set_user_data(data.user_data);
},
- _maybe_load_site_update: function(state) {
+ _maybe_load_site_update: function (state) {
if (c3nav.new_site_update && !state.modal && (!state.routing || !state.origin || !state.destination)) {
c3nav._load_site_update();
}
},
- _load_site_update: function() {
+ _load_site_update: function () {
$('#modal-content').css({
width: 'auto',
minHeight: 0
@@ -1815,14 +1844,14 @@ c3nav = {
},
_hasLocationPermission: undefined,
- hasLocationPermission: function(nocache) {
+ hasLocationPermission: function (nocache) {
if (c3nav._hasLocationPermission === undefined || (nocache !== undefined && nocache === true)) {
c3nav._hasLocationPermission = window.mobileclient && (typeof window.mobileclient.hasLocationPermission !== 'function' || window.mobileclient.hasLocationPermission())
}
return c3nav._hasLocationPermission;
},
- getWifiScanRate: function() {
+ getWifiScanRate: function () {
if (mobileclient.getWifiScanRate) {
return mobileclient.getWifiScanRate() * 1000;
}
@@ -1831,20 +1860,22 @@ c3nav = {
},
_wifiScanningTimer: null,
- startWifiScanning: function() {
+ startWifiScanning: function () {
if (c3nav._wifiScanningTimer == null) {
console.log("started wifi scanning with interval of " + c3nav.getWifiScanRate());
- c3nav._wifiScanningTimer = window.setInterval(function() { mobileclient.scanNow(); }, c3nav.getWifiScanRate());
+ c3nav._wifiScanningTimer = window.setInterval(function () {
+ mobileclient.scanNow();
+ }, c3nav.getWifiScanRate());
}
},
- stopWifiScanning: function() {
+ stopWifiScanning: function () {
if (c3nav._wifiScanningTimer !== null) {
window.clearInterval(c3nav._wifiScanningTimer);
c3nav._wifiScanningTimer = null;
}
},
- startBLEScanning: function() {
+ startBLEScanning: function () {
if (mobileclient.registerBeaconUuid) {
mobileclient.registerBeaconUuid("a142621a-2f42-09b3-245b-e1ac6356e9b0");
}
@@ -1854,7 +1885,7 @@ c3nav = {
_last_wifi_peers: [],
_last_ibeacon_peers: [],
_no_scan_count: 0,
- _wifi_scan_results: function(peers) {
+ _wifi_scan_results: function (peers) {
peers = JSON.parse(peers);
if (c3nav.ssids) {
@@ -1874,12 +1905,12 @@ c3nav = {
c3nav._last_wifi_peers = peers;
c3nav._after_scan_results();
},
- _ibeacon_scan_results: function(peers) {
+ _ibeacon_scan_results: function (peers) {
peers = JSON.parse(peers);
c3nav._last_ibeacon_peers = peers;
c3nav._after_scan_results();
},
- _after_scan_results: function() {
+ _after_scan_results: function () {
has_peers = c3nav._last_wifi_peers.length || c3nav._last_ibeacon_peers.length;
if (has_peers) {
c3nav._hasLocationPermission = true;
@@ -1888,7 +1919,7 @@ c3nav = {
}
var now = Date.now();
- if (now-4000 < c3nav._last_scan) return;
+ if (now - 4000 < c3nav._last_scan) return;
if (!has_peers) {
if (!c3nav._hasLocationPermission) {
@@ -1907,7 +1938,7 @@ c3nav = {
let ibeacon_peers = c3nav._last_ibeacon_peers.map(p => ({...p}));
for (let peer of ibeacon_peers) {
- peer.last_seen_ago = Math.max(0, now - peer.last_seen);
+ peer.last_seen_ago = Math.max(0, now - peer.last_seen);
}
c3nav_api.post('positioning/locate/', {
@@ -1921,7 +1952,7 @@ c3nav = {
});
},
_current_user_location: null,
- _set_user_location: function(location) {
+ _set_user_location: function (location) {
c3nav._current_user_location = location;
for (var id in c3nav._userLocationLayers) {
c3nav._userLocationLayers[id].clearLayers();
@@ -1971,12 +2002,12 @@ c3nav = {
}
if (c3nav._current_user_location) {
c3nav._levelControl.setLevel(c3nav._current_user_location.level);
- c3nav.map.flyTo(L.GeoJSON.coordsToLatLng(c3nav._current_user_location.geometry.coordinates), 3, { duration: 1 });
+ c3nav.map.flyTo(L.GeoJSON.coordsToLatLng(c3nav._current_user_location.geometry.coordinates), 3, {duration: 1});
}
},
_material_symbols_codepoints: null,
- load_material_symbols_if_needed: function() {
+ load_material_symbols_if_needed: function () {
// load material icons codepoint for android 4.3.3 and other heccing old browsers
var elem = document.createElement('span'),
before = elem.style.fontFeatureSettings,
@@ -1989,26 +2020,26 @@ c3nav = {
$.get('/static/material-symbols/MaterialSymbolsOutlined.codepoints', c3nav._material_symbols_loaded);
}
},
- _material_symbols_loaded: function(data) {
+ _material_symbols_loaded: function (data) {
var lines = data.split("\n"),
line, result = {};
- for (var i=0;i
fetch_updates");
c3nav.fetch_updates();
@@ -2042,9 +2073,9 @@ c3nav = {
}
},
_visibility_hidden_timer: null,
- on_visibility_change: function() {
+ on_visibility_change: function () {
if (document.visibilityState === "hidden") {
- c3nav._visibility_hidden_timer = window.setTimeout( function () {
+ c3nav._visibility_hidden_timer = window.setTimeout(function () {
c3nav._visibility_hidden_timer = null;
if (document.visibilityState === "hidden") {
c3nav._pause();
@@ -2102,7 +2133,7 @@ LevelControl = L.Control.extend({
return this._container;
},
- createTileLayer: function(id) {
+ createTileLayer: function (id) {
let urlPattern = (c3nav.tile_server || '/map/') + `${id}/{z}/{x}/{y}/${this.currentTheme}.png`;
return L.tileLayer(urlPattern, {
minZoom: -2,
@@ -2110,7 +2141,7 @@ LevelControl = L.Control.extend({
bounds: L.GeoJSON.coordsToLatLngs(c3nav.bounds)
});
},
- setTheme: function(theme) {
+ setTheme: function (theme) {
if (theme === this.currentTheme) return;
this.currentTheme = theme;
if (this.currentLevel !== null) {
@@ -2175,13 +2206,15 @@ LevelControl = L.Control.extend({
buttons.removeClass('current');
},
- reloadMap: function() { // TODO: create fresh tile layers
+ reloadMap: function () { // TODO: create fresh tile layers
if (this.currentLevel === null) return;
var old_tile_layer = this._tileLayers[this.currentLevel],
new_tile_layer = this.createTileLayer(this.currentLevel);
this._tileLayers[this.currentLevel] = new_tile_layer;
new_tile_layer.addTo(c3nav.map);
- window.setTimeout(function() { old_tile_layer.remove(); }, 2000);
+ window.setTimeout(function () {
+ old_tile_layer.remove();
+ }, 2000);
}
});
@@ -2213,7 +2246,9 @@ LabelControl = L.Control.extend({
onAdd: function () {
this._container = L.DomUtil.create('div', 'leaflet-control-labels leaflet-bar ' + this.options.addClasses);
this._button = L.DomUtil.create('a', 'material-symbols', this._container);
- $(this._button).click(this.toggleLabels).dblclick(function(e) { e.stopPropagation(); });
+ $(this._button).click(this.toggleLabels).dblclick(function (e) {
+ e.stopPropagation();
+ });
this._button.innerText = c3nav._map_material_icon('label');
this._button.href = '#';
this._button.classList.toggle('control-disabled', false);
@@ -2224,8 +2259,8 @@ LabelControl = L.Control.extend({
return this._container;
},
- toggleLabels: function(e) {
- if(e) e.preventDefault();
+ toggleLabels: function (e) {
+ if (e) e.preventDefault();
if (c3nav._labelControl.labelsActive) {
c3nav._labelControl.hideLabels();
} else {
@@ -2233,7 +2268,7 @@ LabelControl = L.Control.extend({
}
},
- showLabels: function() {
+ showLabels: function () {
if (this.labelsActive) return;
c3nav._labelLayer.addTo(c3nav.map);
this._button.innerText = c3nav._map_material_icon('label');
@@ -2243,7 +2278,7 @@ LabelControl = L.Control.extend({
c3nav.update_location_labels();
},
- hideLabels: function() {
+ hideLabels: function () {
if (!this.labelsActive) return;
c3nav._labelLayer.clearLayers();
c3nav._labelLayer.remove();
@@ -2264,7 +2299,9 @@ SquareGridControl = L.Control.extend({
onAdd: function () {
this._container = L.DomUtil.create('div', 'leaflet-control-grid-layer leaflet-bar ' + this.options.addClasses);
this._button = L.DomUtil.create('a', 'material-symbols', this._container);
- $(this._button).click(this.toggleGrid).dblclick(function(e) { e.stopPropagation(); });
+ $(this._button).click(this.toggleGrid).dblclick(function (e) {
+ e.stopPropagation();
+ });
this._button.innerText = c3nav._map_material_icon('grid_off');
this._button.href = '#';
this._button.classList.toggle('control-disabled', true);
@@ -2275,8 +2312,8 @@ SquareGridControl = L.Control.extend({
return this._container;
},
- toggleGrid: function(e) {
- if(e) e.preventDefault();
+ toggleGrid: function (e) {
+ if (e) e.preventDefault();
if (c3nav._gridControl.gridActive) {
c3nav._gridControl.hideGrid();
} else {
@@ -2284,7 +2321,7 @@ SquareGridControl = L.Control.extend({
}
},
- showGrid: function() {
+ showGrid: function () {
if (this.gridActive) return;
c3nav._gridLayer.addTo(c3nav.map);
this._button.innerText = c3nav._map_material_icon('grid_on');
@@ -2293,7 +2330,7 @@ SquareGridControl = L.Control.extend({
localStorageWrapper.setItem('showGrid', true);
},
- hideGrid: function() {
+ hideGrid: function () {
if (!this.gridActive) return;
c3nav._gridLayer.remove();
this._button.innerText = c3nav._map_material_icon('grid_off');
@@ -2308,10 +2345,12 @@ ThemeControl = L.Control.extend({
position: 'bottomright',
addClasses: '',
},
- onAdd: function() {
+ onAdd: function () {
this._container = L.DomUtil.create('div', 'leaflet-control-theme leaflet-bar ' + this.options.addClasses);
this._button = L.DomUtil.create('a', 'material-symbols', this._container);
- $(this._button).click(c3nav.show_theme_select).dblclick(function(e) { e.stopPropagation(); });
+ $(this._button).click(c3nav.show_theme_select).dblclick(function (e) {
+ e.stopPropagation();
+ });
this._button.innerText = c3nav._map_material_icon('contrast');
this._button.href = '#';
return this._container;
@@ -2322,29 +2361,29 @@ ThemeControl = L.Control.extend({
L.SquareGridLayer = L.Layer.extend({
initialize: function (config) {
this.config = config;
- },
+ },
- onAdd: function(map) {
+ onAdd: function (map) {
this._container = L.DomUtil.create('div', 'leaflet-pane c3nav-grid');
this.getPane().appendChild(this._container);
this.cols = [];
this.rows = [];
var i, elem, label;
- for(i=0;i'+label+'';
+ label = String.fromCharCode(65 + (this.config.invert_x ? (this.config.cols.length - i - 2) : i));
+ if (i < this.config.cols.length - 1) {
+ elem.innerHTML = '' + label + '' + label + '';
}
this._container.appendChild(elem);
this.cols.push(elem);
}
- for(i=0;i0) {
- elem.innerHTML = ''+label+''+label+'';
+ label = (this.config.invert_y ? (this.config.rows.length - i) : i);
+ if (i > 0) {
+ elem.innerHTML = '' + label + '' + label + '';
}
this._container.appendChild(elem);
this.rows.push(elem);
@@ -2355,18 +2394,18 @@ L.SquareGridLayer = L.Layer.extend({
map.on('viewreset zoom move zoomend moveend', this._update, this);
},
- onRemove: function(map) {
+ onRemove: function (map) {
L.DomUtil.remove(this._container);
this.cols = [];
this.rows = [];
map.off('viewreset zoom move zoomend moveend', this._update, this);
},
- _update: function(e) {
+ _update: function (e) {
this._updateGrid(e.target);
},
- _updateGrid: function(map) {
+ _updateGrid: function (map) {
if (!this.cols || this.cols.length === 0) return;
var mapSize = map.getSize(),
panePos = map._getMapPanePos(),
@@ -2376,39 +2415,39 @@ L.SquareGridLayer = L.Layer.extend({
attributionStart = mapSize.x - $('.leaflet-control-attribution').outerWidth() - 16,
bottomRightStart = mapSize.y - $('.leaflet-bottom.leaflet-right').outerHeight() - 24,
coord = null, lastCoord = null, size, center;
- this._container.style.width = mapSize.x+'px';
- this._container.style.height = mapSize.y+'px';
- this._container.style.left = (-panePos.x)+'px';
- this._container.style.top = (-panePos.y)+'px';
- for(i=0;i0) {
- size = coord-lastCoord;
- center = (lastCoord+coord)/2;
+ this.cols[i].style.left = coord + 'px';
+ if (i > 0) {
+ size = coord - lastCoord;
+ center = (lastCoord + coord) / 2;
if (size > 0) {
this.cols[i - 1].style.display = '';
this.cols[i - 1].style.width = size + 'px';
- this.cols[i - 1].style.paddingTop = Math.max(0, Math.min(searchHeight, (sidebarStart-center)/15*searchHeight)) + 'px';
- this.cols[i - 1].style.paddingBottom = Math.max(0, Math.min(16, (center-attributionStart))) + 'px';
+ this.cols[i - 1].style.paddingTop = Math.max(0, Math.min(searchHeight, (sidebarStart - center) / 15 * searchHeight)) + 'px';
+ this.cols[i - 1].style.paddingBottom = Math.max(0, Math.min(16, (center - attributionStart))) + 'px';
} else {
this.cols[i - 1].style.display = 'none';
}
}
lastCoord = coord;
}
- for(i=0;i0) {
- size = lastCoord-coord;
- center = (lastCoord+coord)/2;
+ this.rows[i].style.top = coord + 'px';
+ if (i > 0) {
+ size = lastCoord - coord;
+ center = (lastCoord + coord) / 2;
if (size > 0) {
this.rows[i].style.display = '';
- this.rows[i].style.height = size+'px';
- this.rows[i].style.paddingRight = Math.max(0, Math.min(controlsWidth, (center-bottomRightStart)/16*controlsWidth)) + 'px';
+ this.rows[i].style.height = size + 'px';
+ this.rows[i].style.paddingRight = Math.max(0, Math.min(controlsWidth, (center - bottomRightStart) / 16 * controlsWidth)) + 'px';
} else {
this.rows[i].style.display = 'none';
}
@@ -2418,51 +2457,148 @@ L.SquareGridLayer = L.Layer.extend({
}
});
+KeyControl = L.Control.extend({
+ options: {position: 'topright', addClasses: ''},
+ _keys: [],
+
+ onAdd: function () {
+ const pinned = JSON.parse(localStorage.getItem('c3nav.key.pinned') ?? 'false');
+
+ this._container = L.DomUtil.create('div', 'leaflet-control-key ' + this.options.addClasses);
+ this._container.classList.toggle('leaflet-control-key-expanded', pinned);
+ this._content = L.DomUtil.create('div', 'content');
+ const collapsed = L.DomUtil.create('div', 'collapsed-toggle leaflet-control-key-toggle');
+ this._pin = L.DomUtil.create('div', 'pin-toggle');
+ this._pin.classList.toggle('active', pinned);
+ this._pin.innerText = '🖈';
+ this._container.append(this._pin, this._content, collapsed);
+ this._expanded = pinned;
+ this._pinned = pinned;
+
+ if (!L.Browser.android) {
+ L.DomEvent.on(this._container, {
+ mouseenter: this.expand,
+ mouseleave: this.collapse
+ }, this);
+ }
+
+ if (!L.Browser.touch) {
+ L.DomEvent.on(this._container, 'focus', this.expand, this);
+ L.DomEvent.on(this._container, 'blur', this.collapse, this);
+ }
+
+ this.render();
+
+ $(this._container).on('click', 'div.pin-toggle', e => {
+ this.togglePinned();
+ });
+ $(this._container).on('mousedown pointerdown wheel', e => {
+ e.stopPropagation();
+ });
+ return this._container;
+ },
+
+ addKey: function (name, background, border) {
+ this._keys.push({
+ name,
+ background,
+ border,
+ });
+ this.render();
+ },
+
+ render: function () {
+ if (!this._content) return;
+ const fragment = document.createDocumentFragment();
+ for (const key of this._keys) {
+ const key_container = document.createElement('div');
+ key_container.classList.add('key');
+ const color = document.createElement('div');
+ color.classList.add('key-color');
+ if (key.background !== null) {
+ color.style.backgroundColor = key.background;
+ }
+ if (key.border !== null) {
+ color.style.borderColor = key.border;
+ }
+
+ const name = document.createElement('div');
+ name.innerText = key.name;
+ key_container.append(color, name);
+ fragment.append(key_container);
+ }
+ this._content.replaceChildren(...fragment.children);
+ },
+
+ expand: function () {
+ if (this._pinned) return;
+ this._expanded = true;
+ this._container.classList.add('leaflet-control-key-expanded');
+ return this;
+ },
+
+ collapse: function () {
+ if (this._pinned) return;
+ this._expanded = false;
+ this._container.classList.remove('leaflet-control-key-expanded');
+ return this;
+ },
+
+ togglePinned: function () {
+ this._pinned = !this._pinned;
+ if (this._pinned) {
+ this._expanded = true;
+ }
+ this._pin.classList.toggle('active', this._pinned);
+ localStorage.setItem('c3nav.key.pinned', JSON.stringify(this._pinned));
+ },
+});
+
var SvgIcon = L.Icon.extend({
- options: {
- // @section
- // @aka DivIcon options
- iconSize: [12, 12], // also can be set through CSS
+ options: {
+ // @section
+ // @aka DivIcon options
+ iconSize: [12, 12], // also can be set through CSS
- // iconAnchor: (Point),
- // popupAnchor: (Point),
+ // iconAnchor: (Point),
+ // popupAnchor: (Point),
- // @option html: String|SVGElement = ''
- // Custom HTML code to put inside the div element, empty by default. Alternatively,
- // an instance of `SVGElement`.
- iconSvg: null,
- shadowSvg: null,
+ // @option html: String|SVGElement = ''
+ // Custom HTML code to put inside the div element, empty by default. Alternatively,
+ // an instance of `SVGElement`.
+ iconSvg: null,
+ shadowSvg: null,
- // @option bgPos: Point = [0, 0]
- // Optional relative position of the background, in pixels
- bgPos: null,
+ // @option bgPos: Point = [0, 0]
+ // Optional relative position of the background, in pixels
+ bgPos: null,
- className: 'leaflet-svg-icon'
- },
+ className: 'leaflet-svg-icon'
+ },
// @method createIcon(oldIcon?: HTMLElement): HTMLElement
- // Called internally when the icon has to be shown, returns a `
` HTML element
- // styled according to the options.
- createIcon: function (oldIcon) {
- return this._createIcon('icon', oldIcon);
- },
+ // Called internally when the icon has to be shown, returns a `
` HTML element
+ // styled according to the options.
+ createIcon: function (oldIcon) {
+ return this._createIcon('icon', oldIcon);
+ },
- // @method createShadow(oldIcon?: HTMLElement): HTMLElement
- // As `createIcon`, but for the shadow beneath it.
- createShadow: function (oldIcon) {
- return this._createIcon('shadow', oldIcon);
- },
+ // @method createShadow(oldIcon?: HTMLElement): HTMLElement
+ // As `createIcon`, but for the shadow beneath it.
+ createShadow: function (oldIcon) {
+ return this._createIcon('shadow', oldIcon);
+ },
- _createIcon: function (name, oldIcon) {
+ _createIcon: function (name, oldIcon) {
var src = this.options[`${name}Svg`];
- if (!src) {
- if (name === 'icon') {
- throw new Error('iconSvg not set in Icon options (see the docs).');
- }
- return null;
- }
+ if (!src) {
+ if (name === 'icon') {
+ throw new Error('iconSvg not set in Icon options (see the docs).');
+ }
+ return null;
+ }
var svgEl;
if (src instanceof SVGElement) {
@@ -2471,8 +2607,8 @@ var SvgIcon = L.Icon.extend({
svgEl = (new DOMParser()).parseFromString(src, 'image/svg+xml').documentElement;
}
- this._setIconStyles(svgEl, name);
+ this._setIconStyles(svgEl, name);
- return svgEl;
- },
+ return svgEl;
+ },
});
\ No newline at end of file