From 4bf9a457844e360187dc2b37bf164a3b3a58e73a Mon Sep 17 00:00:00 2001
From: Jacek Kowalski <Jacek@jacekk.info>
Date: Sun, 30 Aug 2020 20:40:28 +0000
Subject: [PATCH] Fix right panel on Safari browser (overflow: auto + position: fixed)
---
map.js | 268 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 195 insertions(+), 73 deletions(-)
diff --git a/map.js b/map.js
index aefb371..85542e9 100644
--- a/map.js
+++ b/map.js
@@ -1,4 +1,4 @@
-"use strict";
+'use strict';
var ttss_refresh = 10000; // 10 seconds
var ttss_position_type = 'RAW';
@@ -20,7 +20,7 @@
var vehicles_info = {};
var stops_xhr = null;
-var stops_ignored = ['131'];
+var stops_ignored = ['131', '744', '1263', '3039'];
var stops_style = {
'sb': new ol.style.Style({
image: new ol.style.Circle({
@@ -70,6 +70,7 @@
var map = null;
var panel = null;
+var find = null;
var fail_element = document.getElementById('fail');
var fail_text = document.querySelector('#fail span');
@@ -81,22 +82,27 @@
this._element = element;
this._element.classList.add('panel');
- this._hide = addParaWithText(this._element, '▶');
+ this._hide = addElementWithText(this._element, 'a', '▶');
this._hide.title = lang.action_collapse;
this._hide.className = 'hide';
this._hide.addEventListener('click', this.toggleExpanded.bind(this));
- this._close = addParaWithText(this._element, '×');
+ this._container = document.createElement('div');
+ this._container.className = 'panel-container';
+
+ this._close = addElementWithText(this._container, 'a', '×');
this._close.title = lang.action_close;
this._close.className = 'close';
this._close.addEventListener('click', this.close.bind(this));
this._content = document.createElement('div');
- this._element.appendChild(this._content);
-};
+ this._container.appendChild(this._content);
+ this._element.appendChild(this._container);
+}
Panel.prototype = {
_element: null,
_hide: null,
+ _container: null,
_close: null,
_content: null,
@@ -144,6 +150,85 @@
},
};
+
+function Find() {
+ this.div = document.createElement('div');
+
+ this.form = document.createElement('form');
+ this.div.appendChild(this.form);
+
+ var para = addParaWithText(this.form, lang.enter_query);
+ para.appendChild(document.createElement('br'));
+ this.input = document.createElement('input');
+ this.input.type = 'text';
+ this.input.style.width = '80%';
+ para.appendChild(this.input);
+ para.appendChild(document.createElement('hr'));
+
+ this.results = document.createElement('div');
+ this.div.appendChild(this.results);
+
+ this.input.addEventListener('keyup', this.findDelay.bind(this));
+ this.form.addEventListener('submit', this.findDelay.bind(this));
+}
+Find.prototype = {
+ query: '',
+ timeout: null,
+
+ div: null,
+ form: null,
+ input: null,
+ results: null,
+
+ find: function() {
+ var query = this.input.value.toUpperCase();
+ if(query === this.query) return;
+ this.query = query;
+
+ if(query === '') {
+ deleteChildren(this.results);
+ return;
+ }
+
+ var features = [];
+ stops_type.forEach(function(stop_type) {
+ if(stop_type.substr(0,1) === 'p') return;
+ stops_source[stop_type].forEachFeature(function(feature) {
+ if(feature.get('name').toUpperCase().indexOf(query) > -1) {
+ features.push(feature);
+ }
+ });
+ });
+
+ ttss_types.forEach(function(ttss_type) {
+ vehicles_source[ttss_type].forEachFeature(function(feature) {
+ if(feature.get('vehicle_type') && feature.get('vehicle_type').num.indexOf(query) > -1) {
+ features.push(feature);
+ }
+ });
+ });
+
+ deleteChildren(this.results);
+ this.results.appendChild(listFeatures(features));
+ },
+ findDelay: function(e) {
+ e.preventDefault();
+ if(this.timeout) clearTimeout(this.timeout);
+ this.timeout = setTimeout(this.find.bind(this), 100);
+ },
+ open: function(panel) {
+ ignore_hashchange = true;
+ window.location.hash = '#!f';
+
+ panel.show(this.div, this.close.bind(this));
+ this.input.focus();
+ },
+ close: function() {
+ if(this.timeout) clearTimeout(this.timeout);
+ },
+};
+
+
function fail(msg) {
setText(fail_text, msg);
fail_element.style.top = '0.5em';
@@ -193,14 +278,15 @@
fill = '#05B';
}
if(selected) {
- fill = '#292';
+ fill = '#922';
}
- var image = '<svg xmlns="http://www.w3.org/2000/svg" height="30" width="20"><polygon points="10,0 20,23 0,23" style="fill:'+fill+';stroke:'+color_type+';stroke-width:3" /></svg>';
+ var image = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="30"><polygon points="10,0 20,23 0,23" style="fill:'+fill+';stroke:'+color_type+';stroke-width:3"/></svg>';
vehicle.setStyle(new ol.style.Style({
image: new ol.style.Icon({
src: 'data:image/svg+xml;base64,' + btoa(image),
+ imgSize: [20,30],
rotation: Math.PI * parseFloat(vehicle.get('heading') ? vehicle.get('heading') : 0) / 180.0,
}),
text: new ol.style.Text({
@@ -228,7 +314,6 @@
var feature, prefix;
for(var i = 0; i < stops.length; i++) {
- feature = null;
if(stops[i].getId) {
feature = stops[i];
} else {
@@ -270,7 +355,7 @@
if(vehicle_feature) {
vehicles_source[prefix].removeFeature(vehicle_feature);
if(feature_clicked && feature_clicked.getId() === vehicle_feature.getId()) {
- featureClicked();
+ panel.close();
}
}
continue;
@@ -278,7 +363,7 @@
var vehicle_name_space = vehicle.name.indexOf(' ');
vehicle.line = vehicle.name.substr(0, vehicle_name_space);
- vehicle.direction = vehicle.name.substr(vehicle_name_space+1);
+ vehicle.direction = normalizeName(vehicle.name.substr(vehicle_name_space+1));
if(special_directions[vehicle.direction]) {
vehicle.line = special_directions[vehicle.direction];
}
@@ -310,8 +395,9 @@
function updateStopSource(stops, prefix) {
var source = stops_source[prefix];
var mapping = stops_mapping[prefix];
+ var stop;
for(var i = 0; i < stops.length; i++) {
- var stop = stops[i];
+ stop = stops[i];
if(stop.category == 'other') continue;
if(stops_ignored.includes(stop.shortName)) continue;
@@ -347,7 +433,7 @@
}).fail(fail_ajax);
}
-function vehiclePath(feature, tripId) {
+function vehiclePath(feature) {
if(path_xhr) path_xhr.abort();
var featureId = feature.getId();
@@ -389,7 +475,7 @@
+ '?tripId=' + encodeURIComponent(feature.get('tripId'))
+ '&mode=departure'
).done(function(data) {
- if(!data.routeName || !data.directionText) {
+ if(typeof data.old === "undefined" || typeof data.actual === "undefined") {
return;
}
@@ -401,7 +487,7 @@
for(var i = 0, il = all_departures.length; i < il; i++) {
tr = document.createElement('tr');
addCellWithText(tr, all_departures[i].actualTime || all_departures[i].plannedTime);
- addCellWithText(tr, all_departures[i].stop_seq_num + '. ' + all_departures[i].stop.name);
+ addCellWithText(tr, all_departures[i].stop_seq_num + '. ' + normalizeName(all_departures[i].stop.name));
if(i >= data.old.length) {
stopsToMark.push('s' + ttss_type + all_departures[i].stop.id);
@@ -415,6 +501,14 @@
table.appendChild(tr);
}
+ if(all_departures.length === 0) {
+ tr = document.createElement('tr');
+ table.appendChild(tr);
+ tr = addCellWithText(tr, lang.no_data);
+ tr.colSpan = '2';
+ tr.className = 'active';
+ }
+
markStops(stopsToMark, ttss_type, true);
feature_timer = setTimeout(function() { vehicleTable(feature, table); }, ttss_refresh);
@@ -438,7 +532,7 @@
for(var i = 0, il = all_departures.length; i < il; i++) {
tr = document.createElement('tr');
addCellWithText(tr, all_departures[i].patternText);
- dir_cell = addCellWithText(tr, all_departures[i].direction);
+ dir_cell = addCellWithText(tr, normalizeName(all_departures[i].direction));
vehicle = parseVehicle(all_departures[i].vehicleId);
dir_cell.appendChild(displayVehicle(vehicle));
status = parseStatus(all_departures[i]);
@@ -476,12 +570,9 @@
return;
}
- var coordinates = feature.getGeometry().getCoordinates();
-
var div = document.createElement('div');
- var typeName;
- var name = feature.get('name');
+ var name = normalizeName(feature.get('name'));
var additional;
var table = document.createElement('table');
var thead = document.createElement('thead');
@@ -506,6 +597,8 @@
}
// Vehicle
else if(ttss_types.includes(type)) {
+ styleVehicle(feature, true);
+
var span = displayVehicle(feature.get('vehicle_type'));
additional = document.createElement('p');
@@ -521,8 +614,6 @@
vehicleTable(feature, tbody);
vehiclePath(feature);
-
- styleVehicle(feature, true);
}
// Stop or stop point
else if(['s', 'p'].includes(type)) {
@@ -578,7 +669,19 @@
loader.colSpan = thead.childNodes.length;
addParaWithText(div, typeName).className = 'type';
- addParaWithText(div, name).className = 'name';
+
+ var nameElement = addParaWithText(div, name + ' ');
+ nameElement.className = 'name';
+
+ var showOnMapElement = addElementWithText(nameElement, 'a', lang.show_on_map);
+ var showOnMapFunction = function() {
+ setTimeout(function () {map.getView().animate({
+ center: feature.getGeometry().getCoordinates(),
+ })}, 10);
+ };
+ showOnMapElement.addEventListener('click', showOnMapFunction);
+ showOnMapElement.className = 'icon icon-pin';
+ showOnMapElement.title = lang.show_on_map;
if(additional) {
div.appendChild(additional);
@@ -590,10 +693,7 @@
window.location.hash = '#!' + feature.getId();
}
- setTimeout(function () {map.getView().animate({
- center: feature.getGeometry().getCoordinates(),
- }) }, 10);
-
+ showOnMapFunction();
panel.show(div, function() {
if(!ignore_hashchange) {
@@ -612,6 +712,46 @@
feature_clicked = feature;
}
+function listFeatures(features) {
+ var div = document.createElement('div');
+
+ if(features.length === 0) {
+ addParaWithText(div, lang.no_results);
+ return div;
+ }
+
+ addParaWithText(div, lang.select_feature);
+
+ var feature, p, a, full_type, typeName;
+ for(var i = 0; i < features.length; i++) {
+ feature = features[i];
+
+ p = document.createElement('p');
+ a = document.createElement('a');
+ p.appendChild(a);
+ a.addEventListener('click', function(feature) { return function() {
+ featureClicked(feature);
+ }}(feature));
+
+ full_type = feature.getId().match(/^[a-z]+/)[0];
+ typeName = lang.types[full_type];
+ if(typeof typeName === 'undefined') {
+ typeName = '';
+ }
+ if(feature.get('vehicle_type')) {
+ typeName += ' ' + feature.get('vehicle_type').num;
+ }
+
+ addElementWithText(a, 'span', typeName).className = 'small';
+ a.appendChild(document.createTextNode(' '));
+ addElementWithText(a, 'span', normalizeName(feature.get('name')));
+
+ div.appendChild(p);
+ }
+
+ return div;
+}
+
function mapClicked(e) {
var point = e.coordinate;
var features = [];
@@ -620,43 +760,13 @@
if(feature.getId()) features.push(feature);
});
+ var feature = features[0];
+
if(features.length > 1) {
- featureClicked();
-
- var div = document.createElement('div');
-
- addParaWithText(div, lang.select_feature);
-
- var feature, p, a, full_type, typeName;
- for(var i = 0; i < features.length; i++) {
- feature = features[i];
-
- p = document.createElement('p');
- a = document.createElement('a');
- p.appendChild(a);
- a.addEventListener('click', function(feature) { return function() {
- featureClicked(feature);
- }}(feature));
-
- full_type = feature.getId().match(/^[a-z]+/)[0];
- typeName = lang.types[full_type];
- if(typeof typeName === 'undefined') {
- typeName = '';
- }
-
- addElementWithText(a, 'span', typeName).className = 'small';
- a.appendChild(document.createTextNode(' '));
- addElementWithText(a, 'span', feature.get('name'));
-
- div.appendChild(p);
- }
-
- panel.show(div);
-
+ panel.show(listFeatures(features));
return;
}
- var feature = features[0];
if(!feature) {
stops_type.forEach(function(type) {
if(stops_layer[type].getVisible()) {
@@ -702,6 +812,7 @@
}
}
+
function hash() {
if(ignore_hashchange) {
ignore_hashchange = false;
@@ -726,6 +837,9 @@
stopId = window.location.hash.substr(2,1) + 't' + window.location.hash.substr(3);
} else if(window.location.hash.match(/^#![sp][tb]-?[0-9]+$/)) {
stopId = window.location.hash.substr(2);
+ } else if(window.location.hash.match(/^#!f$/)) {
+ find.open(panel);
+ return;
}
if(vehicleId) {
@@ -759,6 +873,7 @@
function init() {
panel = new Panel(document.getElementById('panel'));
+ find = new Find();
route_source = new ol.source.Vector({
features: [],
@@ -796,12 +911,11 @@
});
vehicles_layer[type] = new ol.layer.Vector({
source: vehicles_source[type],
+ renderMode: 'image',
});
vehicles_last_update[type] = 0;
});
- ol.style.IconImageCache.shared.setSize(512);
-
geolocation_feature = new ol.Feature({
name: '',
style: new ol.style.Style({
@@ -820,9 +934,9 @@
geolocation_layer = new ol.layer.Vector({
source: geolocation_source,
});
- geolocation_button = document.querySelector('#track button');
+ geolocation_button = document.querySelector('#track');
if(!navigator.geolocation) {
- geolocation_button.classList.add('hidden');
+ geolocation_button.remove();
}
geolocation = new ol.Geolocation({projection: 'EPSG:3857'});
@@ -847,13 +961,17 @@
geolocation.on('error', function(error) {
fail(lang.error_location + ' ' + error.message);
trackingStop();
- geolocation_button.classList.add('hidden');
+ geolocation_button.remove();
});
geolocation_button.addEventListener('click', trackingToggle);
+ document.getElementById('find').addEventListener('click', find.open.bind(find, panel));
+
var layers = [
new ol.layer.Tile({
- source: new ol.source.OSM(),
+ source: new ol.source.OSM({
+ url: 'https://tiles.ttss.pl/{z}/{x}/{y}.png',
+ }),
}),
route_layer,
geolocation_layer,
@@ -885,7 +1003,7 @@
element: fail_element,
}),
new ol.control.Control({
- element: document.getElementById('track'),
+ element: document.getElementById('menu'),
}),
]),
loadTilesWhileAnimating: false,
@@ -906,7 +1024,7 @@
});
// Change layer visibility on zoom
- var change_resolution = function(e) {
+ var change_resolution = function() {
stops_type.forEach(function(type) {
if(type.startsWith('p')) {
stops_layer[type].setVisible(map.getView().getZoom() >= 16);
@@ -931,11 +1049,15 @@
window.addEventListener('hashchange', hash);
setTimeout(function() {
- if(trams_xhr) trams_xhr.abort();
- if(trams_timer) clearTimeout(trams_timer);
- if(buses_xhr) buses_xhr.abort();
- if(buses_timer) clearTimeout(buses_timer);
-
+ ttss_types.forEach(function(type) {
+ if(vehicles_xhr[type]) {
+ vehicles_xhr[type].abort();
+ }
+ if(vehicles_timer[type]) {
+ clearTimeout(vehicles_timer[type]);
+ }
+ });
+
fail(lang.error_refresh);
}, 1800000);
}
--
Gitblit v1.10.0