Improved www.ttss.krakow.pl
7 files modified
254 ■■■■■ changed files
common.js 81 ●●●●● patch | view | raw | blame | history
index.html 8 ●●●● patch | view | raw | blame | history
index.js 23 ●●●●● patch | view | raw | blame | history
lang_en.js 29 ●●●●● patch | view | raw | blame | history
lang_pl.js 31 ●●●● patch | view | raw | blame | history
map.html 9 ●●●●● patch | view | raw | blame | history
map.js 73 ●●●● patch | view | raw | blame | history
common.js
@@ -8,7 +8,6 @@
};
var ttss_types = ['t', 'b'];
// Special directions
var special_directions = {
    'Zajezdnia Nowa Huta' : 'ZH',
    'Zajezdnia Podgórze' : 'ZP',
@@ -17,12 +16,77 @@
    'Przejazd techniczny' : 'PT',
};
/********
 * AJAX *
 ********/
function Deferred(promise, request) {
    return {
        promise: promise,
        request: request,
        abort: function() {
            request.abort.bind(request)
            return Deferred(promise, request);
        },
        done: function(func) {
            return Deferred(promise.then(func), request);
        },
        fail: function(func) {
            return Deferred(promise.catch(func), request);
        },
        always: function(func) {
            return Deferred(promise.finally(func), request);
        },
    };
}
Deferred.all = function(iterable) {
    return Deferred(
        Promise.all(
            iterable.map(x => x.promise)
        )
    );
};
var $ = {
    timeout: 10000,
    dataType: 'json',
    get: function(url) {
        var self = this;
        var request = new XMLHttpRequest();
        var promise = new Promise(function(resolve, reject) {
            request.timeout = self.timeout;
            request.onreadystatechange = function() {
                if(this.readyState == 4) {
                    if(this.status == 200) {
                        if(self.dataType == 'json') {
                            resolve(JSON.parse(this.responseText));
                        } else {
                            resolve(this.responseText);
                        }
                    } else {
                        reject(request);
                    }
                }
            };
            request.open("GET", url, true);
            request.send();
        });
        return Deferred(promise, request);
    },
};
/***********
 * VERSION *
 ***********/
var script_version;
var script_version_xhr;
var vehicles_info = {};
// Check for website updates
function checkVersion() {
    if(script_version_xhr) script_version_xhr.abort();
    
@@ -46,7 +110,11 @@
    setInterval(checkVersion, 3600000);
}
/* Parsing of received JSON parts */
/***********
 * PARSING *
 ***********/
function parseStatus(status) {
    switch(status.status) {
        case 'STOPPING':
@@ -91,7 +159,6 @@
    return lang.time_minutes_prefix + ((actual.getTime() - planned.getTime()) / 1000 / 60) + lang.time_minutes_suffix;
}
// Webservice-related functions
function parseVehicle(vehicleId) {
    if(!vehicleId) return false;
    if(!vehicles_info || !vehicles_info[vehicleId]) {
@@ -159,7 +226,11 @@
    return span;
}
// Element mangling
/*******
 * DOM *
 *******/
function deleteChildren(element) {
    while(element.lastChild) element.removeChild(element.lastChild);
}
index.html
@@ -133,9 +133,9 @@
                </div>
            </div>
        </div>
        <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT" crossorigin="anonymous"></script>
        <script type="text/javascript" src="lang_pl.js?v4" id="lang_script"></script>
        <script type="text/javascript" src="common.js?v7"></script>
        <script type="text/javascript" src="index.js?v3"></script>
        <script src="https://polyfill.io/v3/polyfill.min.js?features=Promise,XMLHttpRequest"></script>
        <script type="text/javascript" src="lang_pl.js?v7" id="lang_script"></script>
        <script type="text/javascript" src="common.js?v8"></script>
        <script type="text/javascript" src="index.js?v6"></script>
    </body>
</html>
index.js
@@ -176,6 +176,7 @@
        
        times_timer = setTimeout(function(){ loadTimes(); loadRoute(); }, ttss_refresh);
    }).fail(fail_ajax).always(loading_end);
    return times_xhr;
}
function loadRoute(tripId, vehicleInfo) {
@@ -239,6 +240,7 @@
            route_table.appendChild(tr);
        }
    }).fail(fail_ajax);
    return route_xhr;
}
function startTimer(date) {
@@ -282,7 +284,7 @@
    var text_name;
    for(var i = 0; i < elements.length; i++) {
        text_name = elements[i].dataset.translate;
        if(lang[text_name] == undefined) {
        if(typeof lang[text_name] === 'undefined') {
            console.log('Missing translation: ' + text_name);
            continue;
        }
@@ -315,13 +317,15 @@
    }
    language = lang;
    
    var old_script = document.getElementById('lang_script');
    var old_version = old_script.src.match(/\?v[0-9]+/)[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'lang_' + lang + '.js';
    script.src = 'lang_' + lang + '.js' + (old_version ? old_version : '');
    script.id = 'lang_script';
    script.onload = translate;
    
    document.body.removeChild(document.getElementById('lang_script'));
    document.body.removeChild(old_script);
    document.body.appendChild(script);
    
    ignore_hashchange = true;
@@ -367,25 +371,16 @@
        for(var i = 0, il = data.length; i < il; i++) {
            var opt = document.createElement('option');
            opt.value = data[i].id;
            setText(opt, data[i].id.substr(0,1) == 'b' ? lang.select_stop_bus.replace('$stop', data[i].name) : lang.select_stop_tram.replace('$stop', data[i].name));
            setText(opt, lang.select_stop_type[data[i].id.substr(0,1)].replace('$stop', data[i].name));
            stop_name_autocomplete.appendChild(opt);
        }
        
        if(!stop_id) setText(refresh_text, lang.select_stop_click_go);
    }).fail(fail_ajax);
    return stop_name_autocomplete_xhr;
}
function init() {
    if(!window.jQuery) {
        fail(lang.jquery_not_loaded);
        return;
    }
    $.ajaxSetup({
        dataType: 'json',
        timeout: 10000,
    });
    lang_select.addEventListener('input', function(e) {
        change_language(lang_select.value);
    });
lang_en.js
@@ -9,11 +9,12 @@
    action_expand: 'Expand',
    action_collapse: 'Collapse',
    
    jquery_not_loaded: 'Required JavaScript jQuery library failed to load. You may try refreshing the page.',
    enter_stop_name_to_begin: 'Enter the stop name to begin.',
    select_stop_click_go: 'Select the stop and click "Go".',
    select_stop_tram: '$stop (tram)',
    select_stop_bus: '$stop (bus)',
    select_stop_type: {
        'b': '$stop (bus)',
        't': '$stop (tram)',
    },
    stop_name_placeholder: 'Stop name',
    go_button: 'Go',
    refresh_button: '\u27f3 Refresh',
@@ -45,16 +46,18 @@
    time_minutes_ago_prefix: '',
    time_minutes_ago_suffix: ' min ago',
    
    type_vehicle: 'Vehicle',
    type_bus: 'Bus',
    type_tram: 'Tram',
    type_stop: 'Stop',
    type_stop_bus: 'Bus stop',
    type_stop_tram: 'Tram stop',
    type_stoppoint: 'Stop point',
    type_stoppoint_bus: 'Bus stop point',
    type_stoppoint_tram: 'Tram stop point',
    type_location: 'Your location',
    types: {
        v: 'Vehicle',
        b: 'Bus',
        t: 'Tram',
        s: 'Stop',
        sb: 'Bus stop',
        st: 'Tram stop',
        p: 'Stop point',
        pb: 'Bus stop point',
        pt: 'Tram stop point',
        l: 'Your location',
    },
    
    select_feature: 'There is more than one feature here. Select the proper one:',
    departures_for_stop: 'Click for stop departures (and not only this stop point).',
lang_pl.js
@@ -9,11 +9,12 @@
    action_expand: 'Rozwiń',
    action_collapse: 'Zwiń',
    
    jquery_not_loaded: 'Wymagana biblioteka jQuery nie została poprawnie załadowana. Spróbuj odświeżyć stronę.',
    enter_stop_name_to_begin: 'Zacznij wpisywać nazwę przystanku.',
    select_stop_click_go: 'Wyierz przystanek i kliknij "Dalej".',
    select_stop_tram: '$stop (tramwaj)',
    select_stop_bus: '$stop (autobus)',
    select_stop_type: {
        'b': '$stop (autobus)',
        't': '$stop (tramwaj)',
    },
    stop_name_placeholder: 'Nazwa przystanku',
    go_button: 'Dalej',
    refresh_button: '\u27f3 Odśwież',
@@ -25,8 +26,6 @@
    header_line: 'Linia',
    header_direction: 'Kierunek',
    header_vehicle: 'Pojazd',
    header_bus: 'Autobus',
    header_tram: 'Tramwaj',
    header_time: 'Odjazd',
    header_delay: 'Opóźn.',
    header_lines: 'Linie',
@@ -47,16 +46,18 @@
    time_minutes_ago_prefix: '',
    time_minutes_ago_suffix: ' min temu',
    
    type_vehicle: 'Pojazd',
    type_bus: 'Autobus',
    type_tram: 'Tramwaj',
    type_stop: 'Przystanek',
    type_stop_bus: 'Przystanek autobusowy',
    type_stop_tram: 'Przystanek tramwajowy',
    type_stoppoint: 'Peron',
    type_stoppoint_bus: 'Peron autobusowy',
    type_stoppoint_tram: 'Peron tramwajowy',
    type_location: 'Twoja lokalizacja',
    types: {
        'v': 'Pojazd',
        'b': 'Autobus',
        't': 'Tramwaj',
        's': 'Przystanek',
        'sb': 'Przystanek autobusowy',
        'st': 'Przystanek tramwajowy',
        'p': 'Peron',
        'pb': 'Peron autobusowy',
        'pt': 'Peron tramwajowy',
        'l': 'Twoja lokalizacja',
    },
    
    select_feature: 'W tym miejscu znajduje się więcej niż jeden element. Wybierz właściwy z listy:',
    departures_for_stop: 'Kliknij, by zobaczyć odjazdy dla całego przystanku (a nie tylko peronu).',
map.html
@@ -21,11 +21,10 @@
<div id="fail" class="ol-unselectable ol-control"><span></span> <span class="close">×</p></div>
</div>
<div id="panel"></div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT" crossorigin="anonymous"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=Array.prototype.forEach,Array.prototype.includes,Array.prototype.map,Element.prototype.classList,Promise,String.prototype.startsWith,XMLHttpRequest,requestAnimationFrame"></script>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/build/ol.js" integrity="sha384-iQkGyyH4ioz3m+maM3s9MX1Oq67mACa4B9Z3ovUv3Sv37LJ96fx3WnZfLoiC3Wfl" crossorigin="anonymous"></script>
<script tyle="text/javascript" src="lang_pl.js?v6" id="lang_script"></script>
<script tyle="text/javascript" src="common.js?v7"></script>
<script tyle="text/javascript" src="map.js?v18"></script>
<script tyle="text/javascript" src="lang_pl.js?v7" id="lang_script"></script>
<script tyle="text/javascript" src="common.js?v8"></script>
<script tyle="text/javascript" src="map.js?v20"></script>
</body>
</html>
map.js
@@ -151,7 +151,7 @@
function fail_ajax_generic(data, fnc) {
    // abort() is not a failure
    if(data.readyState == 0 && data.statusText == 'abort') return;
    if(data.readyState == 0) return;
    
    if(data.status == 0) {
        fnc(lang.error_request_failed_connectivity, data);
@@ -247,7 +247,7 @@
function unstyleSelectedFeatures() {
    stop_selected_source.clear();
    route_source.clear();
    if(feature_clicked && ttss_types.indexOf(feature_clicked.getId().substr(0, 1)) >= 0) {
    if(feature_clicked && ttss_types.includes(feature_clicked.getId().substr(0, 1))) {
        styleVehicle(feature_clicked);
    }
}
@@ -315,7 +315,7 @@
        var stop = stops[i];
        
        if(stop.category == 'other') continue;
        if(stops_ignored.indexOf(stop.shortName) >= 0) continue;
        if(stops_ignored.includes(stop.shortName)) continue;
        
        stop.geometry = getGeometry(stop);
        var stop_feature = new ol.Feature(stop);
@@ -375,6 +375,7 @@
        }));
        route_layer.setVisible(true);
    });
    return path_xhr;
}
function vehicleTable(feature, table) {
@@ -423,6 +424,7 @@
        
        feature_timer = setTimeout(function() { vehicleTable(feature, table); }, ttss_refresh);
    }).fail(fail_ajax_popup);
    return feature_xhr;
}
function stopTable(stopType, stopId, table, ttss_type) {
@@ -476,6 +478,7 @@
        
        feature_timer = setTimeout(function() { stopTable(stopType, stopId, table, ttss_type); }, ttss_refresh);
    }).fail(fail_ajax_popup);
    return feature_xhr;
}
function featureClicked(feature) {
@@ -504,19 +507,20 @@
    var tabular_data = true;
    
    var type = feature.getId().substr(0, 1);
    var full_type = feature.getId().match(/^[a-z]+/)[0];
    var typeName = lang.types[full_type];
    if(typeof typeName === 'undefined') {
        typeName = '';
    }
    // Location
    if(type == 'l') {
        tabular_data = false;
        name = typeName;
        typeName = '';
        name = lang.type_location;
    }
    // Vehicle
    else if(ttss_types.indexOf(type) >= 0) {
        typeName = lang.type_bus;
        if(type == 't') {
            typeName = lang.type_tram;
        }
    else if(ttss_types.includes(type)) {
        var span = displayVehicle(feature.get('vehicle_type'));
        
        additional = document.createElement('p');
@@ -536,15 +540,13 @@
        styleVehicle(feature, true);
    }
    // Stop or stop point
    else if(['s', 'p'].indexOf(type) >= 0) {
    else if(['s', 'p'].includes(type)) {
        var ttss_type = feature.getId().substr(1, 1);
        if(type == 's') {
            typeName = lang.type_stop_tram;
            var second_type = lang.departures_for_buses;
            var mapping = stops_mapping['sb'];
            
            if(ttss_type == 'b') {
                typeName = lang.type_stop_bus;
                second_type = lang.departures_for_trams;
                mapping = stops_mapping['st'];
            }
@@ -562,12 +564,6 @@
                );
            }
        } else {
            typeName = lang.type_stoppoint_tram;
            if(ttss_type == 'b') {
                typeName = lang.type_stoppoint_bus;
            }
            stopTable('stopPoint', feature.get('stopPoint'), tbody, ttss_type);
            
            additional = document.createElement('p');
@@ -656,31 +652,10 @@
                featureClicked(feature);
            }}(feature));
            
            var type = feature.getId().substr(0, 1);
            var typeName = '';
            if(type == 'l') {
            var full_type = feature.getId().match(/^[a-z]+/)[0];
            var typeName = lang.types[full_type];
            if(typeof typeName === 'undefined') {
                typeName = '';
                name = lang.type_location;
            } else if(ttss_types.indexOf(type) >= 0) {
                typeName = lang.type_bus;
                if(type == 't') {
                    typeName = lang.type_tram;
                }
                if(feature.get('vehicle_type').num) {
                    typeName += ' ' + feature.get('vehicle_type').num;
                }
            } else if(type == 's') {
                typeName = lang.type_stop_tram;
                if(feature.getId().startsWith('sb')) {
                    typeName = lang.type_stop_bus;
                }
            } else if (type == 'p') {
                typeName = lang.type_stoppoint_tram;
                if(feature.getId().startsWith('pb')) {
                    typeName = lang.type_stoppoint_bus;
                }
            } else {
                continue;
            }
            
            addElementWithText(a, 'span', typeName).className = 'small';
@@ -797,16 +772,6 @@
}
function init() {
    if(!window.jQuery) {
        fail(lang.jquery_not_loaded);
        return;
    }
    $.ajaxSetup({
        dataType: 'json',
        timeout: 10000,
    });
    panel = new Panel(document.getElementById('panel'));
    
    route_source = new ol.source.Vector({
@@ -975,7 +940,7 @@
    stops_type.forEach(function(type) {
        future_requests.push(updateStops(type.substr(0,1), type.substr(1,1)));
    });
    $.when(future_requests).done(hash);
    Deferred.all(future_requests).done(hash);
    
    window.addEventListener('hashchange', hash);