var PtpWidget = new (function(){ var self = this; this.version = 'v4'; /* параметри ініціалізації */ this.parameters = { tec_phone: '0987242032', tec_email: 'Office@ua-gis.com', apiKey: null, //апі ключ apiPassword: null, //апі пароль group: null, //апі група server_ip: null, //іп адресс сервера lang: 'uk', //мова wrapper: 'true', //чи рендерити скелет для віджетів menu: 'true', //чи показувати навігаційне меню віджетів widgets: '', //список віджетів для підключення active_widget: '', //назва віджета який потрібно ініціалізувати після загрузки load_styles: false, //чи підключати стилі віджетів, load_media_styles: false, //чи підключати медіа стилі віджетів, widget_type: 'lviv', //тип віджету, для якого регіону }; /* назва параметра в урлі відповідающого за активний віджет */ this.active_widget_url_parameter = 'ptp-active-widget'; /* оприділяє чи були ініціалізовані параметри */ this.parameters_was_be_get = false; /* список активних віджетів */ this.active_widgets = []; /* часовий інтервал для циклічних функцій */ this.timeout_interval = 1000; /* перевірка чи доступний сервер трека */ this.track_available = false; this.track_request = false; this.track_available_error_message = 'GPS-дані транспорту тимчасово недоступні через масштабну пожежу в найбільшому дата-центрі Європи. Просимо вибачення за спричинені незручності.'; /* ідентифікатор готовності документа */ this.document_ready = false; /* ідентифікатор наявності jQuery */ this.has_jquery = false; /* назва поточного скрипту */ this.script_name = 'ptp-widget.js'; /* файл стилів віджету */ this.widget_style = ['src/style.css']; this.widget_media_style = ['src/meia-style.css']; /* адреса робочої директиви */ this.work_folder_url = null; /* jQuery для підключення */ this.jQuery_script = '//code.jquery.com/jquery-3.4.1.min.js'; /* список усіх віджетів */ this.widgets = { 'reports': { 'js': 'reports/reports.js', 'css': 'reports/reports.css', }, 'schedules': { 'js': 'schedules/schedules.js', 'css': 'schedules/schedules.css', }, 'online-map': { 'js': 'online-map/online-map.js', 'css': 'online-map/online-map.css' } }; /* список віджетів які необхідно загрузити */ this.widgets_for_load = []; /* кількість уже підключених віджетів */ this.count_done_loading_widgets = 0; /* селектори скелету віджетів */ this.cssSelectors = { 'menu': 'PtpWidgetMenu', 'sidebar': 'PtpWidgetSidebar', 'content': 'PtpWidgetContent', 'footer': 'PtpWidgetFooter' }; /* адреса апі шлюза */ this.ptp_api_sluice_url = window.location.protocol + '//api-ptp.sm.vin/'; this.widget_api_sluice_url = '{work_folder_url}gtfs/api/{version}/'; /* адреси апі сервісів */ this.ptp_api_services = { 'getTranslate': this.ptp_api_sluice_url + 'translate', 'getGroupInfo': this.ptp_api_sluice_url + 'groups/get', }; /* типи транспорту */ this.route_types_was_created = false; this.route_types = null; /* переклад */ this.was_get_locale = false; this.locale = { 'route_type_0': 'Трамвай', 'route_type_1': 'Метро', 'route_type_2': 'Залізна дорога', 'route_type_3': 'Автобус/Тролейбус', 'route_type_4': 'Паром', 'route_type_5': 'Канатний трамвай', 'route_type_6': 'Підвісні канатні дороги', 'route_type_7': 'Фунікулер', 'reports_widget_name': 'Звіти', 'schedules_widget_name': 'Графіки', 'online-map_widget_name': 'Онлайн відстеження', 'footer_info_text': 'У разі виявлення помилки, прохання повідомити за контактами:', 'group_active_error': 'У Вас немає дозволу на використання віджету. :(', 'group_api_error': 'У Вас немає дозволу на використання api методів транспортного порталу. :(' } this.init = function() { if (!self.document_ready) { self.checkDocumentState(); return false; } if (!self.has_jquery) { self.checkJquery(); return false; } /* перевірка чи доступний сервер трека */ /* START */ /* if (!self.track_request) { self.track_request = true; self.request('http://track.ua-gis.com/', {}, 'GET', function(data){ self.track_available = true; self.init(); }); setTimeout(self.init, 5000); return false; } if (self.track_request && !self.track_available) { alert(self.track_available_error_message); return false; } */ /* END */ if (!self.parameters_was_be_get) { var script = $('script[src*="' + self.script_name + '"]'); if (script.length != 1) { return false; } self.work_folder_url = $(script).attr('src').split('?')[0].split(self.script_name)[0]; if (self.work_folder_url.indexOf('//') == 0) { self.work_folder_url = window.location.protocol + self.work_folder_url; } if (self.work_folder_url.indexOf(self.version) < 0) { self.work_folder_url = self.work_folder_url + self.version + '/'; } var scriptSrc = $(script).attr('src'); for (var key in self.parameters) { if (key === 'widget_type' && window.location.host === 'loda.gov.ua') { self.parameters[key] = 'loda'; } else { self.parameters[key] = self.getUrlParameterByName(scriptSrc, key, self.parameters[key]); } } var api_sluice_variabels = { work_folder_url: self.work_folder_url.split(self.version)[0], version: self.version }; for (var var_key in api_sluice_variabels) { self.widget_api_sluice_url = self.widget_api_sluice_url.replace('{'+var_key+'}', api_sluice_variabels[var_key]); } self.parameters.active_widget = self.getUrlParameterByName(window.location.href, self.active_widget_url_parameter, self.parameters.active_widget); self.parameters_was_be_get = true; } if (self.parameters.lang != 'uk' && !self.was_get_locale) { self.getTranslate(self.locale, function(newLocale){ if (typeof(newLocale.error) != 'undefined' && !newLocale.error) { self.locale = newLocale.text; } self.was_get_locale = true; self.init(); }); return false; } if (!self.route_types_was_created) { self.getRouteTypes(); return false; } self.getUserGroup(); } /* отримання типів */ this.getRouteTypes = function() { self.route_types = { 0: { name: self.locale.route_type_0, image: self.work_folder_url + 'src/img/route-type-0.png', }, 1: { name: self.locale.route_type_1, }, 2: { name: self.locale.route_type_2, }, 3: { name: self.locale.route_type_3, image: self.work_folder_url + 'src/img/route-type-3.png', }, 4: { name: self.locale.route_type_4, }, 5: { name: self.locale.route_type_5, }, 6: { name: self.locale.route_type_6, }, 7: { name: self.locale.route_type_7, }, }; self.route_types_was_created = true; self.init(); } /* отримання групи апі доступи якої використовуються */ this.getUserGroup = function() { self.request(self.ptp_api_services.getGroupInfo, {'apiKey': self.parameters.apiKey, 'apiPassword': self.parameters.apiPassword}, 'GET', function(group_info){ if ( typeof(group_info.active) !== 'undefined' && typeof(group_info.api_status) !== 'undefined' ) { group_info.active = parseInt(group_info.active); group_info.api_status = parseInt(group_info.api_status); if ( !group_info.active ) { alert( self.locale.group_active_error ); } else if ( !group_info.api_status ) { alert( self.locale.group_api_error ); } else if ( group_info.active && group_info.api_status ) { self.parameters.group = group_info; self.checkGroupCss(); } } else { self.parameters.group = group_info; self.checkGroupCss(); } }); } /* перевіряє наявність файлу стилів для поточної групи */ this.checkGroupCss = function() { var style_file_path = 'src/groups_css/group_' + self.parameters.group.id + '.css'; var style_url = self.work_folder_url + style_file_path; self.checkUrl(style_url, function(status){ if (status) { self.widget_style.push(style_file_path); } self.initWidgetContent(); }); } /* генерування контенту віджета */ this.initWidgetContent = function() { var widgets_list = self.parameters.widgets.split(','); for (var key in widgets_list) { if (typeof(self.widgets[widgets_list[key]]) != 'undefined') { self.widgets_for_load.push(self.widgets[widgets_list[key]]); } } if (self.parameters.load_styles == 'true') self.loadStyles(self.widget_style); if (self.parameters.load_media_styles == 'true') self.loadStyles(self.widget_media_style); if (self.widgets_for_load.length) self.includeWidgets(); if (self.parameters.wrapper == 'true') self.renderSkeleton(); } /* підключає усі оголошені при ініціалізації віджети */ this.includeWidgets = function() { for (var key in self.widgets_for_load) { /* автоактивація віджета */ self.addScript(self.work_folder_url + self.widgets_for_load[key].js, self.afterWidgetLoadEvent); if (self.parameters.load_styles == 'true') { self.addStyle(self.work_folder_url + self.widgets_for_load[key].css); } } } /* */ this.afterWidgetLoadEvent = function() { self.count_done_loading_widgets++; if (self.count_done_loading_widgets == self.widgets_for_load.length) { if (self.parameters.menu == 'true') { self.renderNavigationMenu(); } self.activateVidgetByKey(self.parameters.active_widget); } } /* запускає ініціалізацію активного віджета після загрузки усіх */ this.activateVidgetByKey = function(widgetKeyForActivate) { if (widgetKeyForActivate != '' && typeof(self.active_widgets[widgetKeyForActivate]) != 'undefined') { if (self.parameters.menu == 'true') { $('#' + self.cssSelectors.menu + ' li').removeClass('active'); $('#' + self.cssSelectors.menu + ' li[data-widget-key="' + widgetKeyForActivate + '"]').addClass('active'); } self.active_widgets[widgetKeyForActivate].init(); self.active_widgets[widgetKeyForActivate].initWidgetContent(); } } /* отримує значення гет параметра з урли */ this.getUrlParameterByName = function(url, name, defaultValue) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, '\\$&'); var regex = new RegExp('[?&]' + name + '(=([^]*)|&|#|$)'), results = regex.exec(url); var value = null; if (!results) { if (typeof(defaultValue) != 'undefined') { value = defaultValue; } else { value = null; } } else if (!results[2]) { value = ''; } else { value = decodeURIComponent(results[2].replace(/\+/g, ' ')); } return value; } /* перевіряє готовність документа перед початком ініціалізації */ this.checkDocumentState = function() { if (typeof(document) != 'undefined') { if (document.readyState === "complete") { self.document_ready = true; self.init(); } else { setTimeout(self.checkDocumentState, self.timeout_interval); } } } /* перевіряє наявність jQuery */ this.checkJquery = function() { if (!window.jQuery) { self.addScript(self.jQuery_script, self.checkJquery); } else { $ = window.jQuery; self.has_jquery = true; self.init(); } } /* підключає скрипт на сторінку */ this.addScript = function(src, callback) { if (typeof(src) == 'undefined') return false; var script = document.createElement('script'); script.type = "text/javascript"; script.src = src; if (typeof(callback) != 'undefined') script.onload = callback; document.getElementsByTagName('head')[0].appendChild(script); } /* підключає стилі на сторінку */ this.addStyle = function(linkHref) { if (typeof(linkHref) == 'undefined') return false; var link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = linkHref; link.media = 'all'; document.getElementsByTagName('head')[0].appendChild(link); } /* отримання перекладу */ this.getTranslate = function(locaes, callback) { self.request( self.ptp_api_services.getTranslate, { from: 'uk', to: self.parameters.lang, text: locaes }, 'GET', callback ); } /* перевіряє чи є відповідь від урл */ this.checkUrl = function(urlForCheck, callback) { var checker = new XMLHttpRequest(); checker.open('get', urlForCheck, true); checker.onreadystatechange = function() { var status = false; if (checker.readyState === 4) { if (checker.status == 200) { status = true; } } if (checker.readyState === 4) { if (typeof(callback) != 'undefined') { var callbackFunction = callback; callbackFunction(status); } } } checker.send(null); } /* відправка запитів */ this.request = function(url, sendData, type, callback) { if (typeof(url) == 'undefined') return false; if (typeof(sendData) == 'undefined') var sendData = {}; if (typeof(type) == 'undefined') var type = 'GET'; var params = { headers: new Headers({ "ApiKey": self.parameters.apiKey, "ApiPassword": self.parameters.apiPassword, "Language": self.parameters.lang, }), method: type }; var requestUrl = new URL(url); if (requestUrl.origin != window.location.origin) { params.credentials = 'same-origin'; params.mode = 'cors'; } if (typeof(sendData) == 'object') { sendData.gtfs_type = self.parameters.widget_type; } if (type == 'GET') { if (typeof(sendData) != 'undefined') { var data_for_url = $.param(sendData); if (data_for_url) { var delimiter = '?'; if (url.indexOf(delimiter) >= 0) { delimiter = '&'; } url += delimiter + data_for_url; } } } else { params.body = JSON.stringify(sendData); } fetch(url, params).then(function(response){ response.text().then(text => { var data = null; try { data = text && JSON.parse(text); } catch(error) { data = text; } if (typeof(callback) != 'undefined') { var callbackFunction = callback; callbackFunction(data); } }); }) } /* підключає глобальні файлів стилів */ this.loadStyles = function(styles) { for (var key in styles) { self.addStyle(self.work_folder_url + styles[key]); } } /* генерує навігаційне меню */ this.renderNavigationMenu = function() { var menu = '
'; $('#' + self.cssSelectors.menu).html(menu); $('#' + self.cssSelectors.menu).on('click', 'li', function(event){ if (!$(this).hasClass('active')) { var widget_key = $(this).attr('data-widget-key'); var page_url = window.location.href; if (page_url.indexOf(self.active_widget_url_parameter + '=') >= 0) { var page_url_array = page_url.split(self.active_widget_url_parameter + '='); page_url = page_url_array[0]; page_url_array = page_url_array[1].split('&'); page_url += self.active_widget_url_parameter + '=' + widget_key; if (typeof(page_url_array[1]) != 'undefined') { page_url += page_url_array[1]; } } else { if (page_url.indexOf('?') >= 0) { page_url += '&'; } else { page_url += '?'; } page_url += self.active_widget_url_parameter + '=' + widget_key; } window.location.href = page_url; } }); } /* генерує "скелет" для віджетів */ this.renderSkeleton = function() { var contact_phone_number = ''; var contact_email = ''; if (this.parameters.tec_phone) { contact_phone_number = '' + this.parameters.tec_phone + ''; } if (this.parameters.tec_email) { contact_email = '' + this.parameters.tec_email + ''; } var footer_text = ''; if (contact_phone_number || contact_email) { footer_text = '' + this.locale.footer_info_text + '' + contact_phone_number + contact_email; } footer_text += '© ' + new Date().getFullYear() + ' OneSoft'; var skeleton = ''; if (self.parameters.menu == 'true') { skeleton += ''; } skeleton += ''; skeleton += ''; skeleton += ''; $('body .PtpWidget').html(skeleton); } this.init(); })();