/* * Copyright (c) 2014 Sulev-Madis Silber * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ 'use strict'; var tablist = [ 'power_control', 'temperatures', 'network_uplink_status', 'debug', 'lan_status', 'mplayer', 'lightning_radars', 'kitchen_timer', 'ip_cameras', 'networking_extra', 'estonian_weather', 'all_temperature_graphs', 'backend_uptime', 'home', 'networking_extra_2' ]; var tabids = {}; for (var i = 0; i < tablist.length; i++) { var tabname = tablist[i]; tabids[tabname] = 'tab_' + tabname; } var tabbar_order = [ tabids.home, tabids.power_control, tabids.temperatures, tabids.all_temperature_graphs, tabids.lightning_radars, tabids.estonian_weather, tabids.network_uplink_status, tabids.networking_extra, tabids.networking_extra_2, tabids.lan_status, tabids.backend_uptime, tabids.ip_cameras, tabids.kitchen_timer, tabids.mplayer, tabids.debug ]; var config_default = { max_loglines : 100, client_detect : 'auto', client_type : 'full', styles : 'styles.css', lang : 'eng', log_enabled : false, request_type : 'GET', server_delay : 0, tabid_active : tabids.home, kitchentimer_audio_file : 'ext/timer-1.ogg', mplayer_src_url : 'http://127.0.0.1:4022/udp/239.3.1.1:1234', kitchentimer_max_milliseconds : 23 * 60 * 60 * 1000, xhr_timeout_milliseconds : 30 * 1000, websocket_enabled : true, cached_content_prefix : 'cache/' }; var features_default = { img_overlay_text_enabled : false, reload_hack : false, reload_hack2 : false, reload_hack3 : false, reload_hack4 : false, mobile_mode_by_viewport_size : false, short_tabnames : false, long_tabnames : false, active_tab_always_visible : false, powercontrol_use_wait_value : false, powercontrol_use_different_wait_classnames : true, powercontrol_status_is_button : false, powercontrol_two_alternating_buttons : false, textget_uses_notify_border : true, set_hash : true, set_title_suffix : true, clock_uses_textnode : false, clear_location_search : false, use_a_element_wrappers : false, hide_tabbuttons_on_tabswitch : false, debugtab_add_br_separators : false, debugtab_switch_http_request_type : false, debugtab_set_server_delay : false, log_short_scrollback : false, logline_short : false, logline_medium : false, kitchentimer_hide_player : true, empty_named_timezone_remove_hack : false, pause_intervals_on_window_blur : false, session_id_in_url : true, auth_uses_post : true }; var lang_strings_default = { eng : { mplayer_remove : 'Remove', kitchentimer_remove : 'Remove', password : 'Password', auth_failed : 'User authorization failed', title_prefix : 'Smart Home Control Panel', image_alt_text : 'Image', image_loading : 'Loading', image_error : 'Error', image_content_source : 'Source', image_click_to_reload : 'Click on image to reload', plaintext_http_error : 'HTTP error', plaintext_loading : 'Loading content', plaintext_content_source : 'Source', plaintext_click_to_reload : 'Click on text to reload', powercontrol_loading_items : 'Loading items', powercontrol_no_items_found : 'No items found', powercontrol_http_error : 'Got HTTP error while loading items', powercontrol_json_error : 'Got JSON error', powercontrol_status_on : 'ON', powercontrol_status_off : 'OFF', powercontrol_status_wait : 'WAIT', powercontrol_status_fail : 'FAIL', powercontrol_button_on : 'ON', powercontrol_button_off : 'OFF', temperatures_label_out : 'Outdoor temperature at Saue, Estonia', temperatures_label_in : 'Indoor temperature', temperatures_label_server : 'Temperature in equipment corner', temperatures_loading : 'Loading temperature data', temperatures_load_error : 'Error loading temperature data', temperatures_parse_error : 'Error parsing temperature data', uplinkstatus_label : 'Network uplink status', uplinkstatus_up : 'UP', uplinkstatus_down : 'DOWN', uplinkstatus_loading : 'Loading uplink status data', uplinkstatus_load_error : 'Error loading uplink status data', uplinkstatus_parse_error : 'Error parsing uplink status data', tabnames : { normal : { power_control : 'Power control', temperatures : 'Temperatures', network_uplink_status : 'Network uplink', debug : 'Debug', lan_status : 'LAN status', mplayer : 'MPlayer', lightning_radars : 'Lightning radar', kitchen_timer : 'Kitchen timer', ip_cameras : 'IP cameras', networking_extra : 'Networking xtra', estonian_weather : 'Estonian weathr', all_temperature_graphs : 'All temp graphs', backend_uptime : 'Backend uptime', home : 'Home', networking_extra_2 : 'Network xtra #2' }, long : { power_control : 'Power control', temperatures : 'Temperatures', network_uplink_status : 'Network uplink status', debug : 'Debug', lan_status : 'LAN status', mplayer : 'MPlayer', lightning_radars : 'Lightning radars', kitchen_timer : 'Kitchen timer', ip_cameras : 'IP cameras', networking_extra : 'Networking extra', estonian_weather : 'Estonian weather', all_temperature_graphs : 'All temperature graphs', backend_uptime : 'Backend uptime', home : 'Home', networking_extra_2 : 'Networking extra #2' }, short : { power_control : 'Power ctrl', temperatures : 'Temps', network_uplink_status : 'Upl sta', debug : 'Debug', lan_status : 'LAN sta', mplayer : 'MPlayer', lightning_radars : 'Lightning', kitchen_timer : 'K timer', ip_cameras : 'IP cams', networking_extra : 'Net st xtra', estonian_weather : 'Est weathr', all_temperature_graphs : 'Al tem gph', backend_uptime : 'Bcknd uptm', home : 'Home', networking_extra_2 : 'Net xtra #2' } } }, est : { mplayer_remove : 'Eemalda', kitchentimer_remove : 'Eemalda', password : 'Parool', auth_failed : 'Kasutaja tuvastamine eba\u00f5nnestus', title_prefix : 'Targa kodu juhtpaneel', image_alt_text : 'Pilt', image_loading : 'Laadin', image_error : 'Viga', image_content_source : 'Allikas', image_click_to_reload : 'Pildi uuendamiseks vajuta sellele', plaintext_http_error : 'HTTP viga', plaintext_loading : 'Laadin sisu', plaintext_content_source : 'Allikas', plaintext_click_to_reload : 'Teksti uuendamiseks vajuta sellele', powercontrol_loading_items : 'Laadin nimekirja', powercontrol_no_items_found : 'Nimekiri on t\u00fchi', powercontrol_http_error : 'Nimekirja laadimisel tekkis HTTP viga', powercontrol_json_error : 'Tekkis JSON viga', powercontrol_status_on : 'SEES', powercontrol_status_off : 'V\u00c4LJ', powercontrol_status_wait : 'OOTA', powercontrol_status_fail : 'VIGA', powercontrol_button_on : 'SISSE', powercontrol_button_off : 'V\u00c4LJA', temperatures_label_out : 'V\u00e4listemperatuur Sauel, Eestis', temperatures_label_in : 'Toatemperatuur', temperatures_label_server : 'Arvutinurga temperatuur', temperatures_loading : 'Laadin temperatuuriandmeid', temperatures_load_error : 'Viga temperatuuriandmete laadimisel', temperatures_parse_error : 'Viga temperatuuriandmete t\u00f6\u00f6tlemisel', uplinkstatus_label : 'Interneti\u00fchendus', uplinkstatus_up : 'T\u00f6\u00f6tab', uplinkstatus_down : 'Ei t\u00f6\u00f6ta', uplinkstatus_loading : 'Laadin interneti\u00fchenduse andmeid', uplinkstatus_load_error : 'Viga interneti\u00fchenduse andmete laadimisel', uplinkstatus_parse_error : 'Viga interneti\u00fchenduse andmete t\u00f6\u00f6tlemisel', tabnames : { normal : { power_control : 'Elektriseadmed', temperatures : 'Temperatuurid', network_uplink_status : 'Internet', debug : 'Rak. arendusinfo', lan_status : 'Kohalik v\u00f5rk', mplayer : 'Videopleier', lightning_radars : '\u00c4ikeseradarid', kitchen_timer : 'K\u00f6\u00f6gitaimer', ip_cameras : 'IP-kaamerad', networking_extra : 'V\u00f5rk, muu', estonian_weather : 'Ilm Eestis', all_temperature_graphs : 'K\u00f5ik t. graafikud', backend_uptime : 'Serveri info', home : 'Avaleht', networking_extra_2 : 'V\u00f5rk, muu (2)' }, long : { power_control : 'Elektriseadmed', temperatures : 'Temperatuurid', network_uplink_status : 'Internet', debug : 'Rakenduse arendusinfo', lan_status : 'Kohalik v\u00f5rk', mplayer : 'Videopleier', lightning_radars : '\u00c4ikeseradarid', kitchen_timer : 'K\u00f6\u00f6gitaimer', ip_cameras : 'IP-kaamerad', networking_extra : 'V\u00f5rk, muu', estonian_weather : 'Ilm Eestis', all_temperature_graphs : 'K\u00f5ik temp. graafikud', backend_uptime : 'Serveri info', home : 'Avaleht', networking_extra_2 : 'V\u00f5rk, muu (2)' }, short : { power_control : 'Seadmed', temperatures : 'Temp', network_uplink_status : 'Internet', debug : 'Arend.', lan_status : 'K. v\u00f5rk', mplayer : 'Video', lightning_radars : '\u00c4ike', kitchen_timer : 'K taimer', ip_cameras : 'IP kaam.', networking_extra : 'V\u00f5rk muu', estonian_weather : 'Ee ilm', all_temperature_graphs : 'T. graaf.', backend_uptime : 'Srv info', home : 'Avaleht', networking_extra_2 : 'V\u00f5rk (2)' } } } }; var config, features, lang_strings, tabbar_buttons_show, httpreqs_active_count, reloads, init_time, first_load_duration, window_focused; var log_fifo = []; var powercontrol_current_itemlist = []; var textgets = {}; var intervals = {}; var messages_oneline = {}; var tab_eventhandlers = {}; var powercontrol_statuses = {}; var tabid_to_tabname = {}; var bgjobs = {}; var httpreq_stats = {}; var httpreqs_active = {}; var authdata = {}; var urlbases = {}; var kitchentimer = {}; var websocket = {}; function urlencode_callback(chr) { return '%' + chr.charCodeAt(0).toString(16); } function urlencode(string) { return encodeURIComponent(string).replace(/[\x21\x27\x28\x29\x2a]/g, urlencode_callback); } function cookie_set(name, value, expire_days) { var date = new Date(); date.setTime(date.getTime() + (expire_days * 24 * 60 * 60 * 1000)); var expires = 'expires=' + date.toGMTString(); document.cookie = name + '=' + value + '; ' + expires; } function interval_set(name, handler, time) { if (intervals[name] && intervals[name].id) { clearInterval(intervals[name].id); } intervals[name] = {}; intervals[name].handler = handler; intervals[name].time = time; intervals[name].id = setInterval(handler, time); handler(); } function interval_clear(name) { if (intervals[name] && intervals[name].id) { clearInterval(intervals[name].id); } intervals[name] = null; } function intervals_pause() { if (intervals) { for (var name in intervals) { if (!name || !intervals.hasOwnProperty(name) || !intervals[name]) { continue; } if (intervals[name].id) { clearInterval(intervals[name].id); } intervals[name].id = null; } } } function intervals_resume() { if (intervals) { for (var name in intervals) { if (!name || !intervals.hasOwnProperty(name) || !intervals[name]) { continue; } var time = intervals[name].time; var handler = intervals[name].handler; if (intervals[name].id) { clearInterval(intervals[name].id); } intervals[name].id = setInterval(handler, time); handler(); } } } function add_handler(element, type, handler) { if (type == 'readystatechange') { if (element['on' + type] !== undefined) { element['on' + type] = handler; } } else if (typeof element.addEventListener == 'function' && typeof element.removeEventListener == 'function') { element.removeEventListener(type, handler, false); element. addEventListener(type, handler, false); } else if (typeof element.attachEvent == 'function' && typeof element.detachEvent == 'function') { element.detachEvent('on' + type, handler); element.attachEvent('on' + type, handler); } else if (element['on' + type] !== undefined) { element['on' + type] = handler; } } function get_tabname(tabid, type) { var tabid_to_tabname_value = tabid_to_tabname[tabid]; var tabname; if (type == 'long') { tabname = lang_strings.tabnames.long[tabid_to_tabname_value]; } else { if (features.long_tabnames) { tabname = lang_strings.tabnames.long[tabid_to_tabname_value]; } else if (features.short_tabnames) { tabname = lang_strings.tabnames.short[tabid_to_tabname_value]; } else { tabname = lang_strings.tabnames.normal[tabid_to_tabname_value]; } } return (typeof tabname == 'string' && tabname.length > 0 ? tabname : (tabid_to_tabname_value || tabid)); } function get_viewport_size() { var result = { width : null, height : null }; if (typeof window.innerWidth == 'number' && typeof window.innerHeight == 'number') { result.width = window.innerWidth; result.height = window.innerHeight; } else if (typeof document.documentElement.clientWidth == 'number' && typeof document.documentElement.clientHeight == 'number') { result.width = document.documentElement.clientWidth; result.height = document.documentElement.clientHeight; } return result; } function create_xhr() { var xhr; if (typeof window.XMLHttpRequest == 'object' || typeof window.XMLHttpRequest == 'function') { xhr = new XMLHttpRequest(); } else if (typeof window.ActiveXObject == 'object' || typeof window.ActiveXObject == 'function') { try { xhr = new ActiveXObject('Msxml2.XMLHTTP'); } catch (exception) { try { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } catch (exception2) { } } } return xhr; } function create_element(name) { return document.createElement(name); } function create_text_node(text) { return document.createTextNode(text); } function get_element_by_id(id) { return document.getElementById(id); } function get_elements_by_tag(tag) { return document.getElementsByTagName(tag); } function element_exists_by_id(id) { return (get_element_by_id(id) ? true : false); } function audio_play_by_id(id) { var audio_element = get_element_by_id(id); if (typeof audio_element.play == 'function') { audio_element.play(); } } function audio_stop_by_id(id) { var audio_element = get_element_by_id(id); if (typeof audio_element.pause == 'function') { audio_element.pause(); try { audio_element.currentTime = 0; } catch (exception) { } } } function setval_by_id(element_id, value) { var element = get_element_by_id(element_id); if (element) { element.value = value; } } function set_first_child_textnode_value_by_id(element_id, value) { var element = get_element_by_id(element_id); if (!element) { return; } for (var i = 0; i < element.childNodes.length; i++) { var current_node = element.childNodes[i]; if (current_node.nodeName == '#text') { current_node.nodeValue = value; break; } } } function setclass_by_id(element_id, class_name) { var element = get_element_by_id(element_id); if (element) { element.className = class_name; } } function remove_child_from_parent(parent_element, child_element_id) { var child_element = get_element_by_id(child_element_id); if (parent_element && child_element) { parent_element.removeChild(child_element); } } function remove_child(parent_element_id, child_element_id) { var parent_element = get_element_by_id(parent_element_id); var child_element = get_element_by_id(child_element_id); if (parent_element && child_element) { parent_element.removeChild(child_element); } } function title_suffix(tabid) { var title = lang_strings.title_prefix; var suffix = get_tabname(tabid, 'long'); if (suffix) { title += ' - ' + suffix; } document.title = title; } function sethash(tabid) { var params = []; if (config.lang != config_default.lang) { params.push('lang=' + config.lang); } if (config.client_detect != config_default.client_detect) { params.push('client=' + config.client_detect); } if (config.log_enabled != config_default.log_enabled) { if (config.log_enabled) { params.push('log=1'); } } var tabname = tabid_to_tabname[tabid]; if (tabname) { params.push('tab=' + tabname); } if (features.clear_location_search) { window.location.search = ''; } window.location.hash = params.join(','); } function bgjobs_active(tabid) { return bgjobs[tabid]; } function pad_digit(number) { return (number < 10 ? '0' : '') + number; } function pad_ms(number) { if (number < 10) { return '00' + number; } else if (number >= 10 && number < 100) { return '0' + number; } else { return number; } } function to_iso_format(timestamp_milliseconds) { var date = (timestamp_milliseconds ? new Date(timestamp_milliseconds) : new Date()); return date.getFullYear() + '-' + pad_digit(date.getMonth() + 1) + '-' + pad_digit(date.getDate()) + ' ' + pad_digit(date.getHours()) + ':' + pad_digit(date.getMinutes()) + ':' + pad_digit(date.getSeconds()) + '.' + pad_ms(date.getMilliseconds()); } function unix_ts_to_date(timestamp) { var date_string = (new Date(timestamp * 1000)).toString(); return (features.empty_named_timezone_remove_hack ? date_string.replace(/\s+\(\)$/, '') : date_string); } function time_str() { var date = new Date(); return pad_digit(date.getHours()) + ':' + pad_digit(date.getMinutes()) + ':' + pad_digit(date.getSeconds()); } function date_str() { var date = new Date(); return date.getFullYear() + '-' + pad_digit(date.getMonth() + 1) + '-' + pad_digit(date.getDate()) + ' '; } function timestamp_ms() { return (new Date()).getTime(); } function iso_date_ms() { return to_iso_format(); } function timediff(current_time_milliseconds, previous_time_milliseconds) { var time_diff = current_time_milliseconds - previous_time_milliseconds; if (time_diff >= 1000) { time_diff /= 1000; } else { time_diff += 'm'; } time_diff += 's'; return time_diff; } function ms_to_h_m_s(milliseconds) { var hours = (milliseconds / (1000 * 60 * 60)) % 24; var minutes = (milliseconds / (1000 * 60)) % 60; var seconds = (milliseconds / 1000) % 60; return pad_digit(Math.floor(hours)) + ':' + pad_digit(Math.floor(minutes)) + ':' + pad_digit(Math.floor(seconds)); } function duration(milliseconds) { if (!milliseconds) { return; } var temp = milliseconds / 1000; var years = Math.floor(temp / 31536000); var days = Math.floor((temp %= 31536000) / 86400); var hours = Math.floor((temp %= 86400) / 3600); var minutes = Math.floor((temp %= 3600) / 60); var seconds = Math.floor(temp % 60); return ((years > 0 ? years + 'y' : '') + (days > 0 ? days + 'd' : '') + (hours > 0 ? hours + 'h' : '') + (minutes > 0 ? minutes + 'm' : '') + (seconds > 0 ? seconds + 's' : '')) || (milliseconds + 'ms'); } function generate_url_suffix(type) { var args = []; if (type == 'img' && features.session_id_in_url && authdata.cached_session_id) { args.push('sess=' + urlencode(authdata.cached_session_id)); } args.push('ts_ms=' + timestamp_ms()); return '?' + args.join('&'); } function log_fifo_add(element) { log_fifo.push(element); if (log_fifo.length > config.max_loglines) { log_fifo.shift(); } } function logwin_update_and_scroll() { if (!config.log_enabled) { return; } var message_div = get_element_by_id('message_div'); if (!message_div) { return; } if (config.tabid_active != tabids.debug) { return; } for (var i = 0; i < log_fifo.length; i++) { message_div.appendChild(create_text_node(log_fifo[i])); message_div.appendChild(create_element('br')); } message_div.appendChild(create_element('br')); if (messages_oneline.auto) { message_div.appendChild(create_text_node(messages_oneline.auto)); } message_div.appendChild(create_element('br')); if (messages_oneline.manual) { message_div.appendChild(create_text_node(messages_oneline.manual)); } message_div.appendChild(create_element('br')); message_div.scrollTop = message_div.scrollHeight; } function log_init() { for (var i = 0; i < config.max_loglines; i++) { log_fifo_add(''); } } function msgclear() { if (!config.log_enabled) { return; } } function msg(str) { if (!config.log_enabled) { return; } log_fifo_add(iso_date_ms() + ' C=' + httpreqs_active_count + ' ' + str); logwin_update_and_scroll(); } function msgo(str, auto) { if (!config.log_enabled) { return; } var prefix = iso_date_ms() + ' C=' + httpreqs_active_count; if (auto == 'yes') { messages_oneline.auto = prefix + ' A ' + str; } else if (auto == 'no') { messages_oneline.manual = prefix + ' M ' + str; } logwin_update_and_scroll(); } function powercontrol_message(msg) { set_first_child_textnode_value_by_id('powercontrol_message', msg); } function http_request(type, exec_type, item, status, password) { if (!exec_type || !(exec_type == 'auto' || exec_type == 'manual')) { return; } var auto = (exec_type == 'auto' ? 'yes' : 'no'); if (typeof httpreqs_active_count != 'number') { httpreqs_active_count = 0; } if (typeof httpreqs_active[type] != 'number') { httpreqs_active[type] = 0; } if (httpreqs_active[type] > 0 && auto == 'yes') { return; } var url = urlbases.dynamic; var method = 'GET'; var args = []; var post_data = null; if (type == 'plaintext') { if (!item) { return; } var src = textgets[item].src; if (!src) { return; } url += config.cached_content_prefix + src; } else if (type == 'powercontrol') { if (item && status) { if (config.request_type == 'POST') { var powercontrol_items = {}; powercontrol_items[item] = status; try { method = config.request_type; post_data = JSON.stringify(powercontrol_items); } catch (exception) { return; } } else { url += 'powercontrol' + '/' + item + '/' + status; if (config.server_delay > 0) { args.push('makelag_s=' + config.server_delay); } } } else { url += 'powercontrol'; } } else if (type == 'auth') { url += 'auth'; if (features.auth_uses_post && password) { var post_items = {}; post_items.auth = password; method = 'POST'; try { post_data = JSON.stringify(post_items); } catch (exception) { return; } } } else if (type == 'temperatures') { url += config.cached_content_prefix + 'weather-temp.csv'; } else if (type == 'uplinkstatus') { url += config.cached_content_prefix + 'uplink-status.csv'; } else { return; } var time = timestamp_ms(); args.push('ts_ms=' + time); if (args.length) { url += '?' + args.join('&'); } httpreqs_active_count++; httpreqs_active[type]++; var request = create_xhr(); if (!request) { return; } request.shcp_type = type; request.shcp_time = time; request.shcp_method = method; request.shcp_auto = auto; request.shcp_plaintext_item = item; request.open(method, url, true); request.timeout = config.xhr_timeout_milliseconds; if (type == 'auth' && !features.auth_uses_post && password) { request.setRequestHeader('X-SHCP-Auth', password); } if (authdata.cached_session_id) { request.setRequestHeader('X-SHCP-Sess', authdata.cached_session_id); } add_handler(request, 'readystatechange', eventhandler_http_callback); request.send(post_data); if (typeof httpreq_stats[exec_type] != 'number') { httpreq_stats[exec_type] = 0; } httpreq_stats[exec_type]++; return true; } function websocket_send(str) { if (websocket.connected) { websocket.obj.send(str); } } function websocket_create() { websocket.connected = false; if (window.WebSocket) { websocket.obj = new WebSocket(websocket.url); } else if (window.MozWebSocket) { websocket.obj = new MozWebSocket(websocket.url); } else { return false; } add_handler(websocket.obj, 'open', eventhandler_websocket_open); add_handler(websocket.obj, 'close', eventhandler_websocket_close) add_handler(websocket.obj, 'message', eventhandler_websocket_message); add_handler(websocket.obj, 'error', eventhandler_websocket_error); return true; } function eventhandler_websocket_open() { websocket.connected = true; ws_send('ready rtt'); } function eventhandler_websocket_close(e) { var code = e.code; var reason = e.reason; websocket.connected = false; setTimeout(websocket_create, Math.random() * 10000); } function eventhandler_websocket_message(e) { var str = e.data; if (str.match(/^\s*rtt\s+(\d+(?:\.\d+)?)\s*$/i)) { websocket_send(str); } } function eventhandler_websocket_error(e) { var str = e.data; } function websocket_init() { websocket_create(); } function server_request(type, exec_type, item, status, password) { return http_request(type, exec_type, item, status, password); } function tab_event(tabid, mode) { if (mode == 'load') { if (features.set_title_suffix) { title_suffix(tabid); } if (features.set_hash) { sethash(tabid); } } var func = tab_eventhandlers[tabid]; if (typeof func == 'function') { func(tabid, mode); } } function active_tab_reload() { tab_event(config.tabid_active, 'unload'); tab_event(config.tabid_active, 'load'); } function auth(mode) { var request_password; if (mode == 'ok') { var prev_fail; if (authdata.fail_count > 0) { prev_fail = true; } authdata.user_canceled = false; authdata.fail_count = 0; authdata.prompt_active = false; if (prev_fail) { active_tab_reload(); } return; } else if (mode == 'fail') { if (authdata.prompt_active) { return; } authdata.fail_count++; if (authdata.user_canceled || authdata.fail_count > 3) { authdata.cached_session_id = null; return; } authdata.prompt_active = true; var password = prompt(lang_strings.password + ':'); if (!password) { authdata.user_canceled = true; return; } authdata.prompt_active = false; request_password = password; } server_request('auth', 'auto', null, null, request_password); } function img_add_remove(parent_id, mode, imgs, footer_comment) { var parent = get_element_by_id(parent_id); if (!parent) { return; } if (Object.prototype.toString.call(imgs) == '[object Array]') { var imgs_array_to_obj = {}; for (var i = 0; i < imgs.length; i++) { var item = imgs[i]; imgs_array_to_obj[item] = urlbases.dynamic + config.cached_content_prefix + item; } imgs = imgs_array_to_obj; } if (imgs) { for (var name in imgs) { if (!name || !imgs.hasOwnProperty(name)) { continue; } var name_idsafe = name.replace(/[^a-z0-9_]/gi, '_'); var id = 'tabimg_container_' + name_idsafe; var id_img = 'tabimg_' + name_idsafe; if (mode == 'load') { if (!element_exists_by_id(id)) { var img_orig_src = imgs[name]; var url = img_orig_src + generate_url_suffix('img'); var img = create_element('img'); img.id = id_img; img.className = 'border_loading'; img.src = url; if (features.img_overlay_text_enabled) { img.alt = '_________________________________________________________________________________'; } else { img.alt = lang_strings.image_alt_text + ': ' + name; } img.title = img.alt; img.shcp_img_orig_src = img_orig_src; add_handler(img, 'click', eventhandler_img_click); add_handler(img, 'load', eventhandler_img_load); add_handler(img, 'error', eventhandler_img_error); var div = create_element('div'); div.id = id; div.className = 'img_container' + (features.img_overlay_text_enabled ? '_overlay' : ''); if (features.use_a_element_wrappers) { var a = create_element('a'); a.className = 'a_wrapper'; a.href = 'javascript:;'; a.appendChild(img); div.appendChild(a); } else { div.appendChild(img); } if (features.img_overlay_text_enabled) { var text_loading = lang_strings.image_loading + ': ' + name; var text_error = lang_strings.image_error + ': ' + name; var div_overlay_loading = create_element('div'); var div_overlay_error = create_element('div'); div_overlay_loading.id = id_img + '_overlay_loading'; div_overlay_error .id = id_img + '_overlay_error'; div_overlay_loading.className = 'img_overlay img_overlay_loading'; div_overlay_error .className = 'img_overlay img_overlay_error img_overlay_hide'; div_overlay_loading.appendChild(create_text_node(text_loading)); div_overlay_error .appendChild(create_text_node(text_error)); div.appendChild(div_overlay_loading); div.appendChild(div_overlay_error); } parent.appendChild(div); } } else if (mode == 'unload') { remove_child(parent_id, id); } } } var id_footer = 'tabimg_textfooter_' + parent_id; if (mode == 'load') { if (!element_exists_by_id(id_footer)) { var text = lang_strings.image_click_to_reload; if (typeof footer_comment == 'string' && footer_comment.length > 0) { text += ' - ' + footer_comment; } var div_footer = create_element('div'); div_footer.id = id_footer; div_footer.className = 'tabimg_textfooter'; div_footer.appendChild(create_text_node(text)); parent.appendChild(div_footer); } } else if (mode == 'unload') { remove_child(parent_id, id_footer); } } function text_add_remove(parent_id, mode, texts, footer_comment) { var footer_click_to_reload; var parent = get_element_by_id(parent_id); if (!parent) { return; } if (Object.prototype.toString.call(texts) == '[object Array]') { var texts_array_to_obj = {}; for (var i = 0; i < texts.length; i++) { var item = texts[i]; texts_array_to_obj[item] = item; } texts = texts_array_to_obj; } if (texts) { for (var name in texts) { if (!name || !texts.hasOwnProperty(name)) { continue; } var text = texts[name]; var name_idsafe = name.replace(/[^a-z0-9_]/gi, '_'); var id = 'tabtext_container_' + name_idsafe; var id_pre = 'tabtext_' + name_idsafe; if (mode == 'load') { if (!element_exists_by_id(id)) { var textget_mode, preload_src; var text_match = text.match(/^textget:(.+)$/i); if (text_match && text_match[1]) { textget_mode = 1; preload_src = text_match[1]; } var div = create_element('div'); div.id = id; var pre = create_element('pre'); pre.id = id_pre; if (textget_mode) { if (features.textget_uses_notify_border) { pre.className = 'border_loading'; } pre.shcp_name = name; add_handler(pre, 'click', eventhandler_pre_click); } else { pre.className = 'text_static'; } pre.appendChild(create_text_node(textget_mode ? '\'' + name + '\': ' + lang_strings.plaintext_loading + ' ...' : text)); if (textget_mode && features.use_a_element_wrappers) { var a = create_element('a'); a.className = 'a_wrapper'; a.href = 'javascript:;'; a.appendChild(pre); div.appendChild(a); } else { div.appendChild(pre); } parent.appendChild(div); if (textget_mode) { footer_click_to_reload = 1; textgets[name] = {}; textgets[name].name_idsafe = name_idsafe; textgets[name].parent_id = parent_id; textgets[name].src = preload_src; server_request('plaintext', 'manual', name); } } } else if (mode == 'reload') { set_first_child_textnode_value_by_id(id_pre, text); } else if (mode == 'unload') { textgets[name] = {}; remove_child(parent_id, id); } } } var footer_enabled, text_footer; if (footer_click_to_reload) { footer_enabled = 1; text_footer = lang_strings.plaintext_click_to_reload; if (typeof footer_comment == 'string' && footer_comment.length > 0) { text_footer += ' - ' + footer_comment; } } else { if (typeof footer_comment == 'string' && footer_comment.length > 0) { footer_enabled = 1; text_footer = footer_comment; } } var id_footer = 'tabtext_textfooter_' + parent_id; if (mode == 'load') { if (footer_enabled) { if (!element_exists_by_id(id_footer)) { var div_footer = create_element('div'); div_footer.id = id_footer; div_footer.className = 'tabtext_textfooter'; div_footer.appendChild(create_text_node(text_footer)); parent.appendChild(div_footer); } } } else if (mode == 'unload') { remove_child(parent_id, id_footer); } } function update_plaintext_item(plaintext_item, status, content) { var name_idsafe = textgets[plaintext_item].name_idsafe; var parent_id = textgets[plaintext_item].parent_id; if (!name_idsafe || !parent_id) { return; } if (status == 'error') { content = '\'' + plaintext_item + '\': ' + content; } var auth_failed; if (content.match(/auth.+failed/i)) { content = lang_strings.auth_failed; auth_failed = true; } var texts = {}; texts[plaintext_item] = content; if (features.textget_uses_notify_border) { if (status != 'loading') { text_add_remove(parent_id, 'reload', texts); } setclass_by_id('tabtext_' + name_idsafe, (status == 'loading' || status == 'error' ? 'border_' + status : null)); } else { text_add_remove(parent_id, 'reload', texts); } if (auth_failed) { auth('fail'); } } function update_temperatures(status, content) { var auth_failed; var element_id = 'home_temperatures'; var element_text = '...'; if (status == 'loaded') { var temps = {}; var lines = content.split(/\r?\n/); for (var i = 0; i < lines.length; i++) { var line = lines[i]; if (!line) { continue; } var fields = line.split(/[\|\;]/); if (fields.length != 3 || !fields[0] || !fields[1] || !fields[2]) { continue; } temps[fields[0]] = { time : fields[1], value : fields[2] }; } var texts = []; if (typeof temps.temp_out == 'object') { texts.push(lang_strings.temperatures_label_out + '\n' + temps.temp_out.value + '\u00b0C\n' + unix_ts_to_date(temps.temp_out.time)); } if (typeof temps.temp_in == 'object') { texts.push(lang_strings.temperatures_label_in + '\n' + temps.temp_in.value + '\u00b0C\n' + unix_ts_to_date(temps.temp_in.time)); } if (typeof temps.temp_server == 'object') { texts.push(lang_strings.temperatures_label_server + '\n' + temps.temp_server.value + '\u00b0C\n' + unix_ts_to_date(temps.temp_server.time)); } if (texts.length) { element_text = texts.join('\n\n'); } else { if (content.match(/auth.+failed/i)) { element_text = lang_strings.auth_failed; auth_failed = true; } else { element_text = lang_strings.temperatures_parse_error; } } } else if (status == 'error') { element_text = lang_strings.temperatures_load_error; } set_first_child_textnode_value_by_id(element_id, element_text); setclass_by_id(element_id, (status == 'error' ? 'border_error' : null)); if (auth_failed) { auth('fail'); } } function update_uplinkstatus(status, content) { var auth_failed; var element_id = 'home_uplinkstatus'; var element_text = '...'; if (status == 'loaded') { var uplink; var lines = content.split(/\r?\n/); for (var i = 0; i < lines.length; i++) { var line = lines[i]; if (!line) { continue; } var fields = line.split(/[\|\;]/); if (fields.length != 3 || !fields[0] || !fields[1] || !fields[2]) { continue; } uplink = { time : fields[0], value : fields[1], uptime : fields[2] }; } var texts = []; if (typeof uplink == 'object') { texts.push(lang_strings.uplinkstatus_label + '\n' + lang_strings['uplinkstatus_' + (uplink.value || 'down')] + ' (' + uplink.uptime + ')\n' + unix_ts_to_date(uplink.time)); } if (texts.length) { element_text = texts.join(''); } else { if (content.match(/auth.+failed/i)) { element_text = lang_strings.auth_failed; auth_failed = true; } else { element_text = lang_strings.uplinkstatus_parse_error; } } } else if (status == 'error') { element_text = lang_strings.uplinkstatus_load_error; } set_first_child_textnode_value_by_id(element_id, element_text); setclass_by_id(element_id, (status == 'error' ? 'border_error' : null)); if (auth_failed) { auth('fail'); } } function generate_powercontrol_buttons(itemlist) { var prev_item_count = -1; var curr_item_count = -1; var item_names_changed; var div_id = 'tabcontainer_powercontrol'; var tab = get_element_by_id(tabids.power_control); if (!tab) { return; } if (itemlist) { var keys = []; if (itemlist) { for (var key in itemlist) { if (!key || !itemlist.hasOwnProperty(key)) { continue; } keys.push(key); if (itemlist[key] != powercontrol_current_itemlist[key]) { item_names_changed = true; } } } keys.sort(); itemlist = {}; for (var i = 0; i < keys.length; i++) { itemlist[keys[i]] = null; } prev_item_count = powercontrol_current_itemlist.length; curr_item_count = keys.length; powercontrol_current_itemlist = keys; } if (element_exists_by_id(div_id)) { if (item_names_changed || curr_item_count != prev_item_count) { remove_child_from_parent(tab, div_id); } else { return; } } var div = create_element('div'); div.id = div_id; if (itemlist) { for (var name in itemlist) { if (!name || !itemlist.hasOwnProperty(name)) { continue; } var baseid = name.toLowerCase().replace(/ /g, '_'); var label = name.replace(/_/g, ' '); var input_label = create_element('input'); input_label.className = 'label'; input_label.type = 'text'; input_label.value = label; input_label.readOnly = true; input_label.tabIndex = -1; var input_status = create_element('input'); input_status.id = baseid + '_status'; input_status.className = 'status status_init'; input_status.type = (features.powercontrol_status_is_button ? 'button' : 'text'); input_status.value = '...'; input_status.shcp_baseid = baseid; var input_on, input_off; if (features.powercontrol_status_is_button) { input_status.disabled = true; add_handler(input_status, 'click', eventhandler_powercontrol_toggle); } else { input_status.readOnly = true; input_status.tabIndex = -1; input_on = create_element('input'); input_on.id = baseid + '_on'; input_on.className = 'power_button power_button_on_disabled'; input_on.type = 'button'; input_on.value = lang_strings.powercontrol_button_on; input_on.disabled = true; input_on.shcp_baseid = baseid; add_handler(input_on, 'click', eventhandler_powercontrol_on); input_off = create_element('input'); input_off.id = baseid + '_off'; input_off.className = 'power_button power_button_off_disabled'; input_off.type = 'button'; input_off.value = lang_strings.powercontrol_button_off; input_off.disabled = true; input_off.shcp_baseid = baseid; add_handler(input_off, 'click', eventhandler_powercontrol_off); } var div_singleitem = create_element('div'); div_singleitem.id = 'powercontrol_singleitem_wrapper_' + baseid; div_singleitem.className = 'powercontrol_singleitem_wrapper'; div_singleitem.appendChild(input_label); div_singleitem.appendChild(input_status); if (!features.powercontrol_status_is_button) { div_singleitem.appendChild(input_on); div_singleitem.appendChild(input_off); } div.appendChild(div_singleitem); } } tab.appendChild(div); } function powercontrol_set_item_status(baseid, status) { if (!baseid) { return; } return server_request('powercontrol', 'manual', baseid, status); } function powercontrol_item_fail(baseid, init, target_status) { if (init == 'no' && config.log_enabled) { var name = baseid.replace(/_/g, ' '); var target_status_uppercase = (target_status || 'n/a').toUpperCase(); msg('Failed to turn ' + target_status_uppercase + ' ' + name); } var status = get_element_by_id(baseid + '_status'); if (!status) { return; } status.value = lang_strings.powercontrol_status_fail; status.className = 'status status_fail'; if (features.powercontrol_status_is_button) { status.disabled = true; } else { var onbutton = get_element_by_id(baseid + '_on'); var offbutton = get_element_by_id(baseid + '_off'); onbutton .disabled = true; offbutton.disabled = true; onbutton.className = 'power_button power_button_on_disabled'; offbutton.className = 'power_button power_button_off_disabled'; } } function powercontrol_fail_all_items() { var items = powercontrol_current_itemlist; if (!items) { return; } var init = 'yes'; for (var i = 0; i < items.length; i++) { var baseid = items[i]; powercontrol_item_fail(baseid, init); } } function powercontrol_item_wait(baseid, target_status) { if (config.log_enabled) { var name = baseid.replace(/_/g, ' '); var target_status_uppercase = (target_status || 'n/a').toUpperCase(); if (features.logline_short) { msg(name + ' = ' + target_status_uppercase); } else { msg('Trying to turn ' + name + ' ' + target_status_uppercase); } } var status = get_element_by_id(baseid + '_status'); if (!status) { return; } if (features.powercontrol_use_wait_value) { status.value = lang_strings.powercontrol_status_wait; } status.className = 'status status_wait' + (features.powercontrol_use_different_wait_classnames ? '_' + target_status : ''); if (features.powercontrol_status_is_button) { status.disabled = true; } else { var onbutton = get_element_by_id(baseid + '_on'); var offbutton = get_element_by_id(baseid + '_off'); onbutton .disabled = true; offbutton.disabled = true; onbutton.className = 'power_button power_button_on_disabled'; offbutton.className = 'power_button power_button_off_disabled'; } } function powercontrol_item_on(baseid, init) { if (init == 'yes') { if (config.log_enabled && powercontrol_statuses[baseid] != 'on') { var name = baseid.replace(/_/g, ' '); if (features.logline_short) { msg(name + ' is ON'); } else { msg('Server said ' + name + ' is ON'); } } } else if (init == 'no') { if (powercontrol_set_item_status(baseid, 'on')) { powercontrol_item_wait(baseid, 'on'); } else { powercontrol_item_fail(baseid, init, 'on'); } return; } var status = get_element_by_id(baseid + '_status'); if (!status) { return; } powercontrol_statuses[baseid] = 'on'; status.value = lang_strings.powercontrol_status_on; status.className = 'status status_on'; if (features.powercontrol_status_is_button) { status.disabled = false; } else { var onbutton = get_element_by_id(baseid + '_on'); var offbutton = get_element_by_id(baseid + '_off'); onbutton .disabled = true; offbutton.disabled = false; if (features.powercontrol_two_alternating_buttons) { onbutton.className = 'power_button power_button_on_disabled powerbutton_hide'; offbutton.className = 'power_button power_button_off_enabled powerbutton_show'; } else { onbutton.className = 'power_button power_button_on_disabled'; offbutton.className = 'power_button power_button_off_enabled'; } } } function powercontrol_item_off(baseid, init) { if (init == 'yes') { if (config.log_enabled && powercontrol_statuses[baseid] != 'off') { var name = baseid.replace(/_/g, ' '); if (features.logline_short) { msg(name + ' is OFF'); } else { msg('Server said ' + name + ' is OFF'); } } } else if (init == 'no') { if (powercontrol_set_item_status(baseid, 'off')) { powercontrol_item_wait(baseid, 'off'); } else { powercontrol_item_fail(baseid, init, 'off'); } return; } var status = get_element_by_id(baseid + '_status'); if (!status) { return; } powercontrol_statuses[baseid] = 'off'; status.value = lang_strings.powercontrol_status_off; status.className = 'status status_off'; if (features.powercontrol_status_is_button) { status.disabled = false; } else { var onbutton = get_element_by_id(baseid + '_on'); var offbutton = get_element_by_id(baseid + '_off'); onbutton .disabled = false; offbutton.disabled = true; if (features.powercontrol_two_alternating_buttons) { onbutton.className = 'power_button power_button_on_enabled powerbutton_show'; offbutton.className = 'power_button power_button_off_disabled powerbutton_hide'; } else { onbutton.className = 'power_button power_button_on_enabled'; offbutton.className = 'power_button power_button_off_disabled'; } } } function generate_tabs() { var tab_containers_id = 'tab_containers'; var tab_containers = get_element_by_id(tab_containers_id); var tabbar_buttons_id = 'tabbar_buttons'; var tabbar_buttons = get_element_by_id(tabbar_buttons_id); if (!tab_containers || !tabbar_buttons || !tabbar_order) { return; } for (var i = 0; i < tabbar_order.length; i++) { var tabid = tabbar_order[i]; var tabname = get_tabname(tabid); var div = create_element('div'); div.id = tabid; div.className = 'tabcontent_' + (tabid == config.tabid_active ? 'show' : 'hide'); var input = create_element('input'); input.id = 'tabbar_button_' + tabid; input.className = 'tab tab_' + (tabid == config.tabid_active ? '' : 'in') + 'active' + (bgjobs_active(tabid) ? '_bgjobs' : ''); input.type = 'button'; input.value = tabname; input.shcp_tabid = tabid; add_handler(input, 'click', eventhandler_tabswitch); if (tabid == config.tabid_active) { var input_active = create_element('input'); input_active.id = 'tabbar_active_tab'; input_active.className = 'tabbar_active_tab tabbar_active_tab_' + (features.active_tab_always_visible ? 'show' : 'hide'); input_active.type = 'button'; input_active.value = tabname; add_handler(input_active, 'click', eventhandler_toggle_tabbar); var tabbar_active = get_element_by_id('tabbar_active'); if (tabbar_active) { tabbar_active.appendChild(input_active); } } tab_containers.appendChild(div); tabbar_buttons.appendChild(input); if (tabid == config.tabid_active) { tab_event(tabid, 'load'); } } if (features.hide_tabbuttons_on_tabswitch) { tabbar_buttons_show = false; setclass_by_id('tabbar_buttons', 'tabbar_buttons_hide'); } else { tabbar_buttons_show = true; setclass_by_id('tabbar_buttons', 'tabbar_buttons_show'); } } function eventhandler_system_init() { if (typeof reloads != 'number') { reloads = 0; } authdata.user_canceled = false; authdata.fail_count = 0; authdata.prompt_active = false; if (reloads <= 0) { init_time = timestamp_ms(); config = {}; if (config_default) { for (var current_key in config_default) { if (!config_default.hasOwnProperty(current_key)) { continue; } config[current_key] = config_default[current_key]; } } urlbases.dynamic = ''; urlbases.static = 'static'; websocket.url = window.location.protocol.replace(/^http/, 'ws') + '//' + window.location.host + window.location.pathname; if (tabids) { for (var current_tabname in tabids) { if (!current_tabname || !tabids.hasOwnProperty(current_tabname)) { continue; } var current_tabid = tabids[current_tabname]; if (!current_tabid) { continue; } tabid_to_tabname[current_tabid] = current_tabname; } } } features = features_default; var argstring = ''; if (window.location.search) { argstring += '?' + window.location.search; } if (window.location.hash) { argstring += window.location.hash; } var arg_match_lang = argstring.match(/lang=(\w+)/); var arg_match_client = argstring.match(/client=([\w\-]+)/); var arg_match_log = argstring.match(/log=(1)/); var arg_match_tab = argstring.match(/(?:(?:init|start)_)?tab=(\w+)/); var arg_lang = ((arg_match_lang && arg_match_lang[1]) ? arg_match_lang[1] : null); var arg_client = ((arg_match_client && arg_match_client[1]) ? arg_match_client[1] : null); var arg_log = ((arg_match_log && arg_match_log[1]) ? arg_match_log[1] : null); var arg_tab = ((arg_match_tab && arg_match_tab[1]) ? arg_match_tab[1] : null); if (arg_lang) { config.lang = (lang_strings_default[arg_lang] ? arg_lang : config_default.lang); } else { config.lang = config_default.lang; } if (arg_client) { config.client_detect = arg_client; } else { config.client_detect = config_default.client_detect; } if (arg_log) { config.log_enabled = true; } else { config.log_enabled = config_default.log_enabled; } if (arg_tab) { var custom_init_tabid = tabids[arg_tab.toLowerCase()]; if (custom_init_tabid) { config.tabid_active = custom_init_tabid; } else { config.tabid_active = config_default.tabid_active; } } else { config.tabid_active = config_default.tabid_active; } if (config.client_detect == 'auto') { if (navigator.userAgent.match(/(symbian|android|maemo|meego|jolla|p[ao]d|mobile|phone|fennec|nokia)/i)) { if (navigator.userAgent.match(/nokia.*5800/i)) { config.client_type = 'mobile-nokia-5800'; } else { config.client_type = 'mobile'; } } else { if (features.mobile_mode_by_viewport_size) { var viewport_size = get_viewport_size(); if (typeof viewport_size.width == 'number' && typeof viewport_size.height == 'number') { if (viewport_size.width <= 640 && viewport_size.height <= 480) { config.client_type = 'mobile'; } else { config.client_type = config_default.client_type; } } else { config.client_type = config_default.client_type; } } else { config.client_type = config_default.client_type; } } } else if (config.client_detect == 'mobile' || config.client_detect == 'mobile-nokia-5800') { config.client_type = config.client_detect; } else { config.client_type = config_default.client_type; } if (config.client_type.match(/^mobile/)) { features.powercontrol_status_is_button = true; features.active_tab_always_visible = true; features.long_tabnames = true; features.hide_tabbuttons_on_tabswitch = true; features.log_short_scrollback = true; features.logline_short = true; features.use_a_element_wrappers = true; features.debugtab_add_br_separators = true; features.set_hash = false; features.empty_named_timezone_remove_hack = true; if (config.client_type == 'mobile-nokia-5800') { config.styles = 'styles-' + config.client_type + '.css'; } else { config.styles = 'styles-mobile.css'; } } else { config.styles = config_default.styles; } if (features.log_short_scrollback) { config.max_loglines = 7; } else { config.max_loglines = config_default.max_loglines; } log_init(); tabbar_buttons_show = (features.hide_tabbuttons_on_tabswitch ? false : true); lang_strings = lang_strings_default[config.lang]; var stylesheet_url = urlbases.static + '/' + config.styles + generate_url_suffix('css'); var stylesheet_id = 'stylesheet'; var body_wrapper_block_id = 'body_wrapper_block'; var tabbar_clock_id = 'tabbar_clock'; var stylesheet = create_element('link'); var body_wrapper_block = create_element('div'); var header_block = create_element('div'); var main_block = create_element('div'); var header_tabs = create_element('div'); var tabbar_clock = create_element('div'); var tabbar_active = create_element('div'); var tabbar_buttons = create_element('div'); var tab_containers = create_element('div'); stylesheet.id = stylesheet_id; stylesheet.rel = 'stylesheet'; stylesheet.type = 'text/css'; stylesheet.href = stylesheet_url; body_wrapper_block.id = body_wrapper_block_id; body_wrapper_block.className = 'body_wrapper_block'; header_block.id = 'header_block'; header_block.className = 'header_block'; main_block.id = 'main_block'; main_block.className = 'main_block'; header_tabs.id = 'header_tabs'; header_tabs.className = 'header_tabs'; tabbar_clock.id = tabbar_clock_id; tabbar_clock.className = 'tabbar_clock'; tabbar_active.id = 'tabbar_active'; tabbar_active.className = 'tabbar_active'; tabbar_buttons.id = 'tabbar_buttons'; tabbar_buttons.className = 'tabbar_buttons_show'; tab_containers.id = 'tab_containers'; tab_containers.className = 'tab_containers'; var clock = create_element(features.clock_uses_textnode ? 'div' : 'input'); clock.id = 'clock'; clock.className = 'clock'; if (features.clock_uses_textnode) { clock.appendChild(create_text_node('clock')); } else { clock.type = 'text'; clock.readOnly = true; } add_handler(clock, 'click', eventhandler_toggle_tabbar); tabbar_clock.appendChild(clock); header_tabs.appendChild(tabbar_clock); header_tabs.appendChild(tabbar_active); header_tabs.appendChild(tabbar_buttons); header_block.appendChild(header_tabs); main_block.appendChild(tab_containers); body_wrapper_block.appendChild(header_block); body_wrapper_block.appendChild(main_block); var body = get_elements_by_tag('body')[0]; var head = get_elements_by_tag('head')[0]; if (!body || !head) { return; } if (reloads > 0) { tab_event(config.tabid_active, 'unload'); } interval_clear('clock'); remove_child_from_parent(body, body_wrapper_block_id); remove_child_from_parent(head, stylesheet_id); head.appendChild(stylesheet); body.appendChild(body_wrapper_block); if (reloads <= 0 && config.websocket_enabled) { websocket_init(); } auth('init'); generate_tabs(); interval_set('clock', eventhandler_interval_clock_update, 1000); setclass_by_id('js_ui_loading', 'js_ui_loading_hide'); if (reloads <= 0) { first_load_duration = timediff(timestamp_ms(), init_time); } reloads++; } function handle_response(args) { var success = args.status; var response = args.response; var status = args.status; var auto = args.auto; var method = args.method; var httpreqs = args.httpreqs; var time_diff = args.time_diff; var type = args.type; var plaintext_item = args.plaintext_item; if (success) { var success_message = ''; if (config.log_enabled) { success_message = 'HTTP ' + status + ': (' + (auto == 'yes' ? 'A' : 'M') + ' ' + method + ' #' + httpreqs + ' @ ' + time_diff + ')'; } if (type == 'plaintext') { if (config.log_enabled) { success_message = '\'' + plaintext_item + '\': ' + success_message + '\n\n\n'; } update_plaintext_item(plaintext_item, 'loaded', (success_message ? success_message : '') + response); } else if (type == 'powercontrol') { var powercontrol_items, json_error; try { powercontrol_items = JSON.parse(response); } catch (exception) { json_error = exception; } if (json_error) { if (response.match(/auth.+failed/i)) { powercontrol_message(lang_strings.auth_failed); auth('fail'); } else { powercontrol_message(lang_strings.powercontrol_json_error + ': ' + json_error); } } else { generate_powercontrol_buttons(powercontrol_items); var item_count = 0; var init = 'yes'; if (powercontrol_items) { for (var item in powercontrol_items) { if (!item || !powercontrol_items.hasOwnProperty(item)) { continue; } var value = powercontrol_items[item]; if (!value) { continue; } var power_status = value; if (power_status == 'on') { powercontrol_item_on(item, init); } else if (power_status == 'off') { powercontrol_item_off(item, init); } else { powercontrol_item_fail(item, init); } item_count++; } } if (config.log_enabled) { success_message += ': ' + item_count + ' item' + (item_count == 1 ? '' : 's'); } if (item_count == 0) { powercontrol_message(lang_strings.powercontrol_no_items_found); powercontrol_fail_all_items(); } else { powercontrol_message(success_message); } } } else if (type == 'auth') { if (response.match(/auth.+failed/i)) { auth('fail'); } else { if (response) { authdata.cached_session_id = response.replace(/\s+$/, ''); } auth('ok'); } } else if (type == 'temperatures') { update_temperatures('loaded', response); } else if (type == 'uplinkstatus') { update_uplinkstatus('loaded', response); } } else { var error_message_suffix = ': ' + status + ' (' + (auto == 'yes' ? 'A' : 'M') + ' ' + method + ' #' + httpreqs + ' @ ' + time_diff + ')'; if (type == 'plaintext') { update_plaintext_item(plaintext_item, 'error', lang_strings.plaintext_http_error + error_message_suffix); } else if (type == 'powercontrol') { powercontrol_message(lang_strings.powercontrol_http_error + error_message_suffix); powercontrol_fail_all_items(); } else if (type == 'auth') { auth('fail'); } else if (type == 'temperatures') { update_temperatures('error'); } else if (type == 'uplinkstatus') { update_uplinkstatus('error'); } } } function eventhandler_http_callback(event_object) { var request = event_object.target; if (request.readyState == 4) { var type = request.shcp_type; var time = request.shcp_time; var method = request.shcp_method; var auto = request.shcp_auto; var plaintext_item = request.shcp_plaintext_item; var status = request.status; httpreqs_active_count--; httpreqs_active[type]--; if (httpreqs_active[type] > 0 && auto == 'yes') { return; } var time_diff = timediff(timestamp_ms(), time); var httpreqs = httpreq_stats[auto == 'yes' ? 'auto' : 'manual']; handle_response ({ success : (status == 200 ? true : false), response : request.responseText, status : status, auto : auto, method : method, httpreqs : httpreqs, time_diff : time_diff, type : type, plaintext_item : plaintext_item, }); if (config.log_enabled) { if (features.logline_short) { msgo('[' + type + ':' + method + ' #' + httpreqs + ', took ' + time_diff + '] ' + status + ' ' + (status == 200 ? 'OK' : 'ERROR'), auto); } else if (features.logline_medium) { msgo('[Req #' + httpreqs + ', ' + type + ':' + method + ', took ' + time_diff + '] ' + (status == 200 ? 'success' : 'error') + ', status is ' + status, auto); } else { msgo('[Req #' + httpreqs + ', ' + type + ':' + method + ', took ' + time_diff + '] XMLHttpRequest() ' + (status == 200 ? 'success' : 'error') + ', status is ' + status, auto); } } } } function eventhandler_interval_powercontrol() { server_request('powercontrol', 'auto'); } function eventhandler_interval_temperatures() { setclass_by_id('home_temperatures', 'border_loading'); server_request('temperatures', 'auto'); } function eventhandler_interval_uplinkstatus() { setclass_by_id('home_uplinkstatus', 'border_loading'); server_request('uplinkstatus', 'auto'); } function eventhandler_interval_kitchentimer() { var time_human = get_element_by_id('input_kitchentimer_time_human'); kitchentimer.current_milliseconds -= 1000; if (kitchentimer.current_milliseconds <= 0) { interval_clear('kitchentimer'); kitchentimer.current_milliseconds = 0; audio_play_by_id('audio_kitchentimer'); } time_human.value = ms_to_h_m_s(kitchentimer.current_milliseconds); } function eventhandler_interval_clock_update() { if (features.clock_uses_textnode) { set_first_child_textnode_value_by_id('clock', time_str()); } else { setval_by_id('clock', time_str()); } } function eventhandler_powercontrol_on(event_object) { var baseid = event_object.target.shcp_baseid; var init = 'no'; powercontrol_item_on(baseid, init); } function eventhandler_powercontrol_off(event_object) { var baseid = event_object.target.shcp_baseid; var init = 'no'; powercontrol_item_off(baseid, init); } function eventhandler_powercontrol_toggle(event_object) { var baseid = event_object.target.shcp_baseid; var status = powercontrol_statuses[baseid]; var init = 'no'; if (status == 'off') { powercontrol_item_on(baseid, init); } else if (status == 'on') { powercontrol_item_off(baseid, init); } else { powercontrol_item_fail(baseid, init); } } function eventhandler_temperatures() { setclass_by_id('home_temperatures', 'border_loading'); server_request('temperatures', 'manual'); } function eventhandler_uplinkstatus() { setclass_by_id('home_uplinkstatus', 'border_loading'); server_request('uplinkstatus', 'manual'); } function eventhandler_toggle_request_type(event_object) { if (config.request_type == 'GET') { config.request_type = 'POST'; } else if (config.request_type == 'POST') { config.request_type = 'GET'; } event_object.target.value = config.request_type; } function eventhandler_toggle_make_server_delay(event_object) { if (config.server_delay == 0) { config.server_delay = 1; } else if (config.server_delay == 1) { config.server_delay = 0; } event_object.target.value = config.server_delay; } function eventhandler_toggle_debug_log(event_object) { config.log_enabled = (config.log_enabled ? false : true); event_object.target.value = (config.log_enabled ? 1 : 0); if (features.set_hash) { sethash(config.tabid_active); } } function eventhandler_soft_reload(event_object) { event_object.target.value = '...'; event_object.target.disabled = true; eventhandler_system_init(); } function eventhandler_page_reload(event_object) { event_object.target.value = '...'; event_object.target.disabled = true; if (features.reload_hack || features.reload_hack2 || features.reload_hack3 || features.reload_hack4) { var location = window.location.href; if (features.reload_hack) { location = location.replace(/^.+\//, '/'); } else if (features.reload_hack2) { location = '/' + location.substring(0, location.lastIndexOf('/')); } else if (features.reload_hack3) { location = location.replace(/^.+\//, '/').replace(/#/, '?'); } else if (features.reload_hack4) { location = location.replace(/^.+\//, '/').replace(/#.*$/, ''); } window.location.replace(location); } else { window.location.reload(true); } } function eventhandler_switch_lang(event_object) { event_object.target.value = '...'; event_object.target.disabled = true; if (config.lang == 'eng') { config.lang = 'est'; } else if (config.lang == 'est') { config.lang = 'eng'; } if (features.set_hash) { sethash(config.tabid_active); } eventhandler_system_init(); } function eventhandler_tabswitch(event_object) { var tabid = event_object.target.shcp_tabid; if (!tabid) { return; } setval_by_id('tabbar_active_tab', get_tabname(tabid)); if (!features.active_tab_always_visible) { setclass_by_id('tabbar_active_tab', 'tabbar_active_tab tabbar_active_tab_hide'); } if (features.hide_tabbuttons_on_tabswitch) { tabbar_buttons_show = false; setclass_by_id('tabbar_buttons', 'tabbar_buttons_hide'); } if (tabid == config.tabid_active) { return; } var tabid_previous = config.tabid_active; if (tabid_previous) { tab_event(tabid_previous, 'unload'); setclass_by_id(tabid_previous, 'tabcontent_hide'); setclass_by_id('tabbar_button_' + tabid_previous, 'tab tab_inactive' + (bgjobs_active(tabid_previous) ? '_bgjobs' : '')); } config.tabid_active = tabid; event_object.target.className = 'tab tab_active' + (bgjobs_active(tabid) ? '_bgjobs' : ''); setclass_by_id(tabid, 'tabcontent_show'); tab_event(tabid, 'load'); } function eventhandler_img_click(event_object) { var img_orig_src = event_object.target.shcp_img_orig_src; if (!img_orig_src) { return; } var url = img_orig_src + generate_url_suffix('img'); event_object.target.className = 'border_loading'; if (features.img_overlay_text_enabled) { setclass_by_id(event_object.target.id + '_overlay_loading', 'img_overlay img_overlay_loading'); setclass_by_id(event_object.target.id + '_overlay_error', 'img_overlay img_overlay_error img_overlay_hide'); } event_object.target.src = url; } function eventhandler_img_load(event_object) { event_object.target.className = null; if (features.img_overlay_text_enabled) { setclass_by_id(event_object.target.id + '_overlay_loading', 'img_overlay img_overlay_loading img_overlay_hide'); setclass_by_id(event_object.target.id + '_overlay_error', 'img_overlay img_overlay_error img_overlay_hide'); } } function eventhandler_img_error(event_object) { event_object.target.className = 'border_error'; if (features.img_overlay_text_enabled) { setclass_by_id(event_object.target.id + '_overlay_loading', 'img_overlay img_overlay_loading img_overlay_hide'); setclass_by_id(event_object.target.id + '_overlay_error', 'img_overlay img_overlay_error'); } auth('imgerror'); } function eventhandler_pre_click(event_object) { var name = event_object.target.shcp_name; if (!name) { return; } var name_idsafe = textgets[name].name_idsafe; if (!textgets[name].parent_id || !name_idsafe) { return; } setclass_by_id('tabtext_' + name_idsafe, 'border_loading'); server_request('plaintext', 'manual', name); } function eventhandler_mplayer_remove() { var tabid = tabids.mplayer; remove_child(tabid, 'tabcontainer_mplayer'); setclass_by_id('tabbar_button_' + tabid, 'tab tab_active'); bgjobs[tabid] = false; } function eventhandler_kitchentimer_up(event_object) { kitchentimer.current_milliseconds += (event_object.target.shcp_minutes_up || 1) * 60 * 1000; if (kitchentimer.current_milliseconds > config.kitchentimer_max_milliseconds) { kitchentimer.current_milliseconds = config.kitchentimer_max_milliseconds; } setval_by_id('input_kitchentimer_time_human', ms_to_h_m_s(kitchentimer.current_milliseconds)); } function eventhandler_kitchentimer_down(event_object) { kitchentimer.current_milliseconds -= (event_object.target.shcp_minutes_down || 1) * 60 * 1000; if (kitchentimer.current_milliseconds < 0) { kitchentimer.current_milliseconds = 0; } setval_by_id('input_kitchentimer_time_human', ms_to_h_m_s(kitchentimer.current_milliseconds)); } function eventhandler_kitchentimer_set() { var time_human = get_element_by_id('input_kitchentimer_time_human'); audio_stop_by_id('audio_kitchentimer'); if (kitchentimer.current_milliseconds > 0 && kitchentimer.current_milliseconds <= config.kitchentimer_max_milliseconds) { time_human.className = 'kitchentimer_input_time_human kitchentimer_active'; if (!intervals.kitchentimer) { time_human.value = ms_to_h_m_s(kitchentimer.current_milliseconds); interval_set('kitchentimer', eventhandler_interval_kitchentimer, 1000); } } else { time_human.className = 'kitchentimer_input_time_human kitchentimer_error'; } } function eventhandler_kitchentimer_clear() { interval_clear('kitchentimer'); kitchentimer.current_milliseconds = 0; var time_human = get_element_by_id('input_kitchentimer_time_human'); if (time_human) { time_human.value = ms_to_h_m_s(kitchentimer.current_milliseconds); time_human.className = 'kitchentimer_input_time_human kitchentimer_inactive'; } audio_stop_by_id('audio_kitchentimer'); } function eventhandler_kitchentimer_play() { audio_play_by_id('audio_kitchentimer'); } function eventhandler_kitchentimer_stop() { audio_stop_by_id('audio_kitchentimer'); } function eventhandler_kitchentimer_remove() { var tabid = tabids.kitchen_timer; interval_clear('kitchentimer'); kitchentimer.current_milliseconds = 0; remove_child(tabid, 'tabcontainer_kitchentimer'); setclass_by_id('tabbar_button_' + tabid, 'tab tab_active'); bgjobs[tabid] = false; } function eventhandler_toggle_tabbar() { tabbar_buttons_show = (tabbar_buttons_show ? false : true); if (features.active_tab_always_visible) { setval_by_id('tabbar_active_tab', (tabbar_buttons_show ? '' : get_tabname(config.tabid_active))); } else { setclass_by_id('tabbar_active_tab', 'tabbar_active_tab tabbar_active_tab_' + (tabbar_buttons_show ? 'hide' : 'show')); } setclass_by_id('tabbar_buttons', 'tabbar_buttons_' + (tabbar_buttons_show ? 'show' : 'hide')); } function eventhandler_window_focus() { if (!features.pause_intervals_on_window_blur) { return; } if (!window_focused) { window_focused = true; intervals_resume(); } } function eventhandler_window_blur() { if (!features.pause_intervals_on_window_blur) { return; } if (window_focused) { window_focused = false; intervals_pause(); } } tab_eventhandlers[tabids.power_control] = function (tabid, mode) { var message_container_id = 'powercontrol_message'; if (mode == 'load') { var div = create_element('div'); div.id = message_container_id; div.className = 'powercontrol_message'; div.appendChild(create_text_node('')); var tab = get_element_by_id(tabid); tab.appendChild(div); powercontrol_current_itemlist = []; powercontrol_message(lang_strings.powercontrol_loading_items + ' ...'); interval_set('powercontrol', eventhandler_interval_powercontrol, 5000 + Math.floor(Math.random() * 1000)); } else if (mode == 'unload') { interval_clear('powercontrol'); powercontrol_current_itemlist = []; remove_child(tabid, 'tabcontainer_powercontrol'); remove_child(tabid, message_container_id); } }; tab_eventhandlers[tabids.temperatures] = function (tabid, mode) { var imgs = [ 'weather-temp-1d.png', 'weather-temp-out-3days.png' ]; img_add_remove(tabid, mode, imgs); }; tab_eventhandlers[tabids.network_uplink_status] = function (tabid, mode) { var imgs = [ 'stats-traffic-vdsl-traffic-1d.png', 'stats-adsl-line-adsl-line-1d.png', 'stats-physlinespeed-physlinespeed-1d.png', 'stats-physlinespeed-physlatency-1d.png', 'stats-physlinespeed-attndr-1d.png' ]; img_add_remove(tabid, mode, imgs); }; tab_eventhandlers[tabids.debug] = function (tabid, mode) { var div_id = 'debugtab_container'; var div_id_logcontainer = 'debugtab_container_uilog'; var viewport_size = get_viewport_size(); var text = ''; text += 'Existing functions, variables & objects:\n'; text += '\n'; text += 'window.location = \'' + window.location + '\'\n'; text += 'window.location.hash = \'' + window.location.hash + '\'\n'; text += 'window.location.host = \'' + window.location.host + '\'\n'; text += 'window.location.hostname = \'' + window.location.hostname + '\'\n'; text += 'window.location.href = \'' + window.location.href + '\'\n'; text += 'window.location.origin = \'' + window.location.origin + '\'\n'; text += 'window.location.pathname = \'' + window.location.pathname + '\'\n'; text += 'window.location.port = \'' + window.location.port + '\'\n'; text += 'window.location.protocol = \'' + window.location.protocol + '\'\n'; text += 'window.location.search = \'' + window.location.search + '\'\n'; text += '\n'; text += 'document.title = \'' + document.title + '\'\n'; text += 'document.location = \'' + document.location + '\'\n'; text += 'document.width = \'' + document.width + '\'\n'; text += 'document.height = \'' + document.height + '\'\n'; text += 'document.cookie = \'' + document.cookie + '\'\n'; text += '\n'; text += 'navigator.appName = \'' + navigator.appName + '\'\n'; text += 'navigator.appVersion = \'' + navigator.appVersion + '\'\n'; text += 'navigator.userAgent = \'' + navigator.userAgent + '\'\n'; text += '\n'; text += 'screen.width = \'' + screen.width + '\'\n'; text += 'screen.height = \'' + screen.height + '\'\n'; text += 'screen.availWidth = \'' + screen.availWidth + '\'\n'; text += 'screen.availHeight = \'' + screen.availHeight + '\'\n'; text += 'screen.colorDepth = \'' + screen.colorDepth + '\'\n'; text += 'screen.pixelDepth = \'' + screen.pixelDepth + '\'\n'; text += '\n'; text += '\n'; text += 'Custom functions / variables:\n'; text += '\n'; text += 'iso_date_ms() = \'' + iso_date_ms() + '\'\n'; text += 'timestamp_ms() = \'' + timestamp_ms() + '\'\n'; text += 'unix_ts_to_date(timestamp_ms() / 1000) = \'' + unix_ts_to_date(timestamp_ms() / 1000) + '\'\n'; text += 'to_iso_format(init_time) = \'' + to_iso_format(init_time) + '\'\n'; text += 'duration(timestamp_ms() - init_time) = \'' + duration(timestamp_ms() - init_time) + '\'\n'; text += '\n'; text += 'viewport_size.width = \'' + viewport_size.width + '\'\n'; text += 'viewport_size.height = \'' + viewport_size.height + '\'\n'; text += '\n'; text += 'config.request_type = \'' + config.request_type + '\'\n'; text += 'config.server_delay = \'' + config.server_delay + '\'\n'; text += 'config.log_enabled = \'' + config.log_enabled + '\'\n'; text += 'config.client_detect = \'' + config.client_detect + '\'\n'; text += 'config.client_type = \'' + config.client_type + '\'\n'; text += 'config.styles = \'' + config.styles + '\'\n'; text += 'config.lang = \'' + config.lang + '\'\n'; text += '\n'; text += 'httpreqs_active_count = \'' + httpreqs_active_count + '\'\n'; text += 'httpreq_stats.auto = \'' + httpreq_stats.auto + '\'\n'; text += 'httpreq_stats.manual = \'' + httpreq_stats.manual + '\'\n'; text += '\n'; text += 'authdata.cached_session_id = \'' + authdata.cached_session_id + '\'\n'; text += 'authdata.user_canceled = \'' + authdata.user_canceled + '\'\n'; text += 'authdata.fail_count = \'' + authdata.fail_count + '\'\n'; text += 'authdata.prompt_active = \'' + authdata.prompt_active + '\'\n'; text += '\n'; if (httpreqs_active) { for (var key in httpreqs_active) { if (!httpreqs_active.hasOwnProperty(key)) { continue; } text += 'httpreqs_active[\'' + key + '\'] = \'' + httpreqs_active[key] + '\'\n'; } } text += '\n'; text += 'reloads = \'' + reloads + '\'\n'; text += 'init_time = \'' + init_time + '\'\n'; text += 'first_load_duration = \'' + first_load_duration + '\'\n'; text += '\n'; text += '\n'; text += 'Unicode Estonian language letters:\n'; text += '\n'; text += 'capital 2 = \u00c4\n'; text += 'capital 6 = \u00d5\n'; text += 'capital 8 = \u00d6\n'; text += 'capital y = \u00dc\n'; text += 'capital s + \'roof\' = \u0160\n'; text += 'capital z + \'roof\' = \u017d\n'; text += 'small 2 = \u00e4\n'; text += 'small 6 = \u00f5\n'; text += 'small 8 = \u00f6\n'; text += 'small y = \u00fc\n'; text += 'small s + \'roof\' = \u0161\n'; text += 'small z + \'roof\' = \u017e\n'; text += '\n'; text += '\n'; text += 'Unicode special symbols:\n'; text += '\n'; text += '\'trigram for heaven\' (\\u2630) = \u2630\n'; text += '\'identical to\' (\\u2261) = \u2261\n'; var texts = { debug: text }; if (mode == 'load') { var set_request_type = create_element('input'); set_request_type.id = 'set_request_type'; set_request_type.className = 'set_request_type'; set_request_type.type = 'button'; set_request_type.value = config.request_type; add_handler(set_request_type, 'click', eventhandler_toggle_request_type); var make_server_delay = create_element('input'); make_server_delay.id = 'make_server_delay'; make_server_delay.className = 'make_server_delay'; make_server_delay.type = 'button'; make_server_delay.value = config.server_delay; add_handler(make_server_delay, 'click', eventhandler_toggle_make_server_delay); var debug_log = create_element('input'); debug_log.id = 'debug_log'; debug_log.className = 'debug_log'; debug_log.type = 'button'; debug_log.value = (config.log_enabled ? 1 : 0); add_handler(debug_log, 'click', eventhandler_toggle_debug_log); var soft_reload = create_element('input'); soft_reload.id = 'soft_reload'; soft_reload.className = 'soft_reload'; soft_reload.type = 'button'; soft_reload.value = 'SR'; add_handler(soft_reload, 'click', eventhandler_soft_reload); var page_reload = create_element('input'); page_reload.id = 'page_reload'; page_reload.className = 'page_reload'; page_reload.type = 'button'; page_reload.value = 'R'; add_handler(page_reload, 'click', eventhandler_page_reload); var switch_lang = create_element('input'); switch_lang.id = 'switch_lang'; switch_lang.className = 'switch_lang'; switch_lang.type = 'button'; switch_lang.value = config.lang; add_handler(switch_lang, 'click', eventhandler_switch_lang); var button_container = create_element('div'); button_container.className = 'debugtab_button_container'; button_container.appendChild(create_text_node('Reload page: ')); button_container.appendChild(page_reload); button_container.appendChild(create_element('br')); button_container.appendChild(create_element('br')); button_container.appendChild(create_text_node(' Soft reload (HTML / JS not reloaded): ')); button_container.appendChild(soft_reload); if (features.debugtab_add_br_separators) { button_container.appendChild(create_element('br')); } if (features.debugtab_switch_http_request_type) { button_container.appendChild(create_text_node(' HTTP request type: ')); button_container.appendChild(set_request_type); if (features.debugtab_add_br_separators) { button_container.appendChild(create_element('br')); } } if (features.debugtab_set_server_delay) { button_container.appendChild(create_text_node(' Server delay: ')); button_container.appendChild(make_server_delay); if (features.debugtab_add_br_separators) { button_container.appendChild(create_element('br')); } } button_container.appendChild(create_text_node(' Debug log: ')); button_container.appendChild(debug_log); if (features.debugtab_add_br_separators) { button_container.appendChild(create_element('br')); } button_container.appendChild(create_text_node(' Switch lang: ')); button_container.appendChild(switch_lang); var div = create_element('div'); div.id = div_id; div.appendChild(button_container); var div_log = create_element('div'); div_log.id = 'message_div'; div_log.className = 'message_div'; var div_logcontainer = create_element('div'); div_logcontainer.id = div_id_logcontainer; div_logcontainer.appendChild(div_log); var tab = get_element_by_id(tabid); tab.appendChild(div); tab.appendChild(div_logcontainer); logwin_update_and_scroll(); } else if (mode == 'unload') { remove_child(tabid, div_id); if (config.log_enabled) { msgclear(); } remove_child(tabid, div_id_logcontainer); } text_add_remove(tabid, mode, texts); }; tab_eventhandlers[tabids.lan_status] = function (tabid, mode) { var texts = [ 'textget:lanstatus.txt' ]; text_add_remove(tabid, mode, texts); }; tab_eventhandlers[tabids.mplayer] = function (tabid, mode) { if (mode == 'load') { var div_id = 'tabcontainer_mplayer'; if (!element_exists_by_id(div_id)) { var embed = create_element('embed'); embed.id = 'embed_mplayer'; embed.className = 'embed_mplayer'; embed.type = 'video/mpeg'; embed.src = config.mplayer_src_url; embed.width = 640; embed.height = 480; embed.setAttribute('nocache', 1); embed.setAttribute('showcontrols', true); embed.setAttribute('autostart', 1); var input = create_element('input'); input.id = 'input_mplayer'; input.className = 'button_removeelement_mplayer'; input.type = 'button'; input.value = lang_strings.mplayer_remove; add_handler(input, 'click', eventhandler_mplayer_remove); var div = create_element('div'); div.id = div_id; div.appendChild(embed); div.appendChild(create_element('br')); div.appendChild(input); var tab = get_element_by_id(tabid); tab.appendChild(div); setclass_by_id('tabbar_button_' + tabid, 'tab tab_active_bgjobs'); bgjobs[tabid] = true; } } }; tab_eventhandlers[tabids.lightning_radars] = function (tabid, mode) { var imgs = [ 'flcenter-tutka1-fullscreen.gif', 'vaski-thu1.png', 'meteorage-euclid_last_lightnings.gif', 'blitzortung-europe-baltic_big.png' ]; var content_source = lang_strings.image_content_source + ': Finnish Lightning Center, Vaski.net, EUCLID EUropean Cooperation for LIghtning Detection, Blitzortung.org'; img_add_remove(tabid, mode, imgs, content_source); }; tab_eventhandlers[tabids.kitchen_timer] = function (tabid, mode) { if (mode == 'load') { var div_id = 'tabcontainer_kitchentimer'; if (!element_exists_by_id(div_id)) { kitchentimer.current_milliseconds = 0; var source = create_element('source'); source.src = urlbases.static + '/' + config.kitchentimer_audio_file; var audio = create_element('audio'); audio.id = 'audio_kitchentimer'; audio.controls = (features.kitchentimer_hide_player ? 0 : 1); audio.loop = 1; audio.preload = 'auto'; audio.appendChild(source); var input_time_human = create_element('input'); input_time_human.id = 'input_kitchentimer_time_human'; input_time_human.className = 'kitchentimer_input_time_human kitchentimer_inactive'; input_time_human.type = 'text'; input_time_human.value = ms_to_h_m_s(kitchentimer.current_milliseconds); input_time_human.readOnly = true; input_time_human.tabIndex = -1; var input_up_1min = create_element('input'); input_up_1min.id = 'input_kitchentimer_up_1min'; input_up_1min.className = 'kitchentimer_input_up_1min'; input_up_1min.type = 'button'; input_up_1min.value = '+1min'; input_up_1min.shcp_minutes_up = 1; add_handler(input_up_1min, 'click', eventhandler_kitchentimer_up); var input_up_10min = create_element('input'); input_up_10min.id = 'input_kitchentimer_up_10min'; input_up_10min.className = 'kitchentimer_input_up_10min'; input_up_10min.type = 'button'; input_up_10min.value = '+10min'; input_up_10min.shcp_minutes_up = 10; add_handler(input_up_10min, 'click', eventhandler_kitchentimer_up); var input_up_30min = create_element('input'); input_up_30min.id = 'input_kitchentimer_up_30min'; input_up_30min.className = 'kitchentimer_input_up_30min'; input_up_30min.type = 'button'; input_up_30min.value = '+30min'; input_up_30min.shcp_minutes_up = 30; add_handler(input_up_30min, 'click', eventhandler_kitchentimer_up); var input_down_1min = create_element('input'); input_down_1min.id = 'input_kitchentimer_down_1min'; input_down_1min.className = 'kitchentimer_input_down_1min'; input_down_1min.type = 'button'; input_down_1min.value = '-1min'; input_down_1min.shcp_minutes_down = 1; add_handler(input_down_1min, 'click', eventhandler_kitchentimer_down); var input_down_10min = create_element('input'); input_down_10min.id = 'input_kitchentimer_down_10min'; input_down_10min.className = 'kitchentimer_input_down_10min'; input_down_10min.type = 'button'; input_down_10min.value = '-10min'; input_down_10min.shcp_minutes_down = 10; add_handler(input_down_10min, 'click', eventhandler_kitchentimer_down); var input_down_30min = create_element('input'); input_down_30min.id = 'input_kitchentimer_down_30min'; input_down_30min.className = 'kitchentimer_input_down_30min'; input_down_30min.type = 'button'; input_down_30min.value = '-30min'; input_down_30min.shcp_minutes_down = 30; add_handler(input_down_30min, 'click', eventhandler_kitchentimer_down); var input_set = create_element('input'); input_set.id = 'input_kitchentimer_set'; input_set.className = 'kitchentimer_input_set'; input_set.type = 'button'; input_set.value = 'Set'; add_handler(input_set, 'click', eventhandler_kitchentimer_set); var input_clear = create_element('input'); input_clear.id = 'input_kitchentimer_clear'; input_clear.className = 'kitchentimer_input_clear'; input_clear.type = 'button'; input_clear.value = 'Clear'; add_handler(input_clear, 'click', eventhandler_kitchentimer_clear); var input_play = create_element('input'); input_play.id = 'input_kitchentimer_play'; input_play.className = 'kitchentimer_input_play'; input_play.type = 'button'; input_play.value = 'Play'; add_handler(input_play, 'click', eventhandler_kitchentimer_play); var input_stop = create_element('input'); input_stop.id = 'input_kitchentimer_stop'; input_stop.className = 'kitchentimer_input_stop'; input_stop.type = 'button'; input_stop.value = 'Stop'; add_handler(input_stop, 'click', eventhandler_kitchentimer_stop); var input_remove = create_element('input'); input_remove.id = 'input_kitchentimer_remove'; input_remove.className = 'button_removeelement_kitchentimer'; input_remove.type = 'button'; input_remove.value = lang_strings.kitchentimer_remove; add_handler(input_remove, 'click', eventhandler_kitchentimer_remove); var div = create_element('div'); div.id = div_id; div.appendChild(create_element('br')); div.appendChild(create_element('br')); div.appendChild(input_down_30min); div.appendChild(input_down_10min); div.appendChild(input_down_1min); div.appendChild(input_time_human); div.appendChild(input_up_1min); div.appendChild(input_up_10min); div.appendChild(input_up_30min); div.appendChild(input_set); div.appendChild(input_clear); div.appendChild(create_element('br')); div.appendChild(create_element('br')); if (!features.kitchentimer_hide_player) { div.appendChild(create_text_node('Music: ')); div.appendChild(input_play); div.appendChild(input_stop); div.appendChild(create_element('br')); div.appendChild(create_element('br')); } div.appendChild(audio); if (!features.kitchentimer_hide_player) { div.appendChild(create_element('br')); div.appendChild(create_element('br')); div.appendChild(create_element('br')); } div.appendChild(input_remove); var tab = get_element_by_id(tabid); tab.appendChild(div); setclass_by_id('tabbar_button_' + tabid, 'tab tab_active_bgjobs'); bgjobs[tabid] = true; } } }; tab_eventhandlers[tabids.ip_cameras] = function (tabid, mode) { var imgs = [ 'shcp-ipcam1.jpg', 'shcp-ipcam2.jpg', 'shcp-ipcam3.jpg' ]; img_add_remove(tabid, mode, imgs); }; tab_eventhandlers[tabids.networking_extra] = function (tabid, mode) { var imgs = [ 'stats-netifs-tl0-traffic-1d.png', 'stats-netifs-dc0-traffic-1d.png', 'stats-netifs-gif3-traffic-1d.png', 'stats-netifs-vlan13-traffic-1d.png', 'stats-netifs-vlan7-traffic-1d.png', 'stats-netifs-vlan9-traffic-1d.png' ]; img_add_remove(tabid, mode, imgs); }; tab_eventhandlers[tabids.estonian_weather] = function (tabid, mode) { var imgs = [ 'emhi-ilmakaart.jpg', 'emhi-precmap.png', 'emhi-snowmap.png', 'emhi-uvgraph.png', 'emhi-tuleohuindeks.png', 'emhi-prob_prec5mm_est_1.jpg', 'emhi-prob_prec5mm_est_2.jpg' ]; var content_source = lang_strings.image_content_source + ': EMHI (/ Estonian Weather Service)'; img_add_remove(tabid, mode, imgs, content_source); }; tab_eventhandlers[tabids.all_temperature_graphs] = function (tabid, mode) { var imgs = [ 'weather-temp-1d.png', 'weather-temp-1w.png', 'weather-temp-1m.png', 'weather-temp-1y.png', 'weather-temp-10y.png', 'weather-temp-out-1day.png', 'weather-temp-out-2days.png', 'weather-temp-out-3days.png' ]; img_add_remove(tabid, mode, imgs); }; tab_eventhandlers[tabids.backend_uptime] = function (tabid, mode) { var texts = [ 'textget:uprecords.exec' ]; text_add_remove(tabid, mode, texts); }; tab_eventhandlers[tabids.home] = function (tabid, mode) { var temperatures_container_id = 'home_temperatures_container'; var uplinkstatus_container_id = 'home_uplinkstatus_container'; if (mode == 'load') { var div_temperatures = create_element('div'); div_temperatures.id = temperatures_container_id; div_temperatures.className = 'home_temperatures_container'; var div_uplinkstatus = create_element('div'); div_uplinkstatus.id = uplinkstatus_container_id; div_uplinkstatus.className = 'home_uplinkstatus_container'; var pre_temperatures = create_element('pre'); pre_temperatures.id = 'home_temperatures'; var pre_uplinkstatus = create_element('pre'); pre_uplinkstatus.id = 'home_uplinkstatus'; pre_temperatures.appendChild(create_text_node(lang_strings.temperatures_loading + '...')); pre_uplinkstatus.appendChild(create_text_node(lang_strings.uplinkstatus_loading + '...')); if (features.use_a_element_wrappers) { var a_temperatures = create_element('a'); var a_uplinkstatus = create_element('a'); a_temperatures.className = 'a_wrapper'; a_uplinkstatus.className = 'a_wrapper'; a_temperatures.href = 'javascript:;'; a_uplinkstatus.href = 'javascript:;'; a_temperatures.appendChild(pre_temperatures); a_uplinkstatus.appendChild(pre_uplinkstatus); div_temperatures.appendChild(a_temperatures); div_uplinkstatus.appendChild(a_uplinkstatus); } else { div_temperatures.appendChild(pre_temperatures); div_uplinkstatus.appendChild(pre_uplinkstatus); } add_handler(div_temperatures, 'click', eventhandler_temperatures); add_handler(div_uplinkstatus, 'click', eventhandler_uplinkstatus); var tab = get_element_by_id(tabid); tab.appendChild(div_temperatures); tab.appendChild(div_uplinkstatus); interval_set('temperatures', eventhandler_interval_temperatures, 30000 + Math.floor(Math.random() * 10000)); interval_set('uplinkstatus', eventhandler_interval_uplinkstatus, 100000 + Math.floor(Math.random() * 30000)); } else if (mode == 'unload') { interval_clear('temperatures'); interval_clear('uplinkstatus'); remove_child(tabid, temperatures_container_id); remove_child(tabid, uplinkstatus_container_id); } }; tab_eventhandlers[tabids.networking_extra_2] = function (tabid, mode) { var imgs = [ 'stats-traffic-vdsl-traffic-1w.png', 'stats-traffic-vdsl-traffic-1m.png', 'stats-traffic-vdsl-traffic-1y.png', 'stats-adsl-line-adsl-line-1w.png', 'stats-adsl-line-adsl-line-1m.png', 'stats-adsl-line-adsl-line-1y.png', 'stats-adsl-line-adsl-line-10y.png', 'stats-physlinespeed-physlinespeed-1w.png', 'stats-physlinespeed-physlinespeed-1m.png', 'stats-physlinespeed-physlinespeed-1y.png', 'stats-physlinespeed-physlinespeed-10y.png', 'stats-physlinespeed-physlatency-1w.png', 'stats-physlinespeed-physlatency-1m.png', 'stats-physlinespeed-physlatency-1y.png', 'stats-physlinespeed-physlatency-10y.png', 'stats-physlinespeed-attndr-1w.png', 'stats-physlinespeed-attndr-1m.png', 'stats-physlinespeed-attndr-1y.png', 'stats-physlinespeed-attndr-10y.png', 'stats-netifs-tl0-traffic-1w.png', 'stats-netifs-tl0-traffic-1m.png', 'stats-netifs-tl0-traffic-1y.png', 'stats-netifs-dc0-traffic-1w.png', 'stats-netifs-dc0-traffic-1m.png', 'stats-netifs-dc0-traffic-1y.png', 'stats-netifs-gif3-traffic-1w.png', 'stats-netifs-gif3-traffic-1m.png', 'stats-netifs-gif3-traffic-1y.png', 'stats-netifs-vlan13-traffic-1w.png', 'stats-netifs-vlan13-traffic-1m.png', 'stats-netifs-vlan13-traffic-1y.png', 'stats-netifs-vlan7-traffic-1w.png', 'stats-netifs-vlan7-traffic-1m.png', 'stats-netifs-vlan7-traffic-1y.png', 'stats-netifs-vlan9-traffic-1w.png', 'stats-netifs-vlan9-traffic-1m.png', 'stats-netifs-vlan9-traffic-1y.png' ]; img_add_remove(tabid, mode, imgs); }; add_handler(window, 'load', eventhandler_system_init); add_handler(window, 'focus', eventhandler_window_focus); add_handler(window, 'blur', eventhandler_window_blur);