CAICP/js/core.js
2018-11-22 21:02:44 +03:00

2277 lines
84 KiB
JavaScript

// MIT License
//
// Copyright (c) 2016-2018, Alexander I. Chebykin
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
/**
* CAI CP v.0.9.1
*
* @module : Core
* @author : Alexander I. Chebykin <alex.chebykin@gmail.com>
* @copyright : Copyright (c) 2016-2018 Alexander I. Chebykin
* @version : 0.9.1
* @build date : 2018-06-05
* @license : MIT
* @link : https://github.com/CAI79/CAI-CP
******************************************************************/
(function () {
"use strict";
/**
* Return GET parameter
*
* @param {string} key Key name
*
* returns {string}
*/
function $_GET(key) {
var s = window.location.search;
s = s.match(new RegExp(key + "=([^&=]+)"));
return s ? s[1] : false;
}
/**
* Check value is numeric
*
* @param {variant} value Value to be checked
*
* @returns {Boolean}
*/
function isNumeric(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
}
/**
* Return string with formatted numeric value. ex: 12345,6 -> 12'345,6
*
* @param {variant} value Source value
* @param {separator} separator Character used to separate thousands
*
* @returns {String}
*/
function numFormatted(value, separator) {
var result = "",
splitted = value.toString().split(" ");
for (var i = 0; i < splitted.length; i++) {
if (isNumeric(splitted[i])) {
result += " " +
splitted[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g,
separator);
} else {
result += " " + splitted[i].toString();
}
}
return result;
}
/**
* Add message with timestamp to browser's console
*
* @param {string} log_message Message text
*
* @returns {undefined}
*/
function console_log(log_message) {
var now = new Date();
console.log(now + ": " + log_message);
}
/**
* Application constructor
*
* @returns {undefined}
*/
function Application() {
/* Object types */
this.OT_TABLE_H = 1;
this.OT_TABLE_V = 2;
this.OT_IFRAME = 3;
this.OT_CANVAS = 4;
// this.OT_DIV = 5;
this.timers = [];
this.apps_list = {};
this.lang = {};
this.menu = {};
this.settings = {};
this.widgets = {};
this.blocks_rotation = ["system",
"system_pulse",
"storage",
"network",
"smb"];
this.cur_block = 0;
/* Monitoring variables */
this.mon_users = 0;
this.mon_users_info = {
"count" : 0,
"last_user": "",
"last_addr": ""
};
/* Ctrl pressed flag */
this.ctrl_on = false;
/* Down point for swipe event on header */
this.hdr_x_down = null;
this.hdr_y_down = null;
this.init(1);
}
/**
* Add events handlers
*
* @returns {undefined}
*/
Application.prototype.add_evt_handlers = function () {
var app_instance = this;
/* Add swipe handler to header */
document.getElementById("app_header").addEventListener("touchstart",
function (event) {
app_instance.hdr_x_down = event.touches[0].clientX;
app_instance.hdr_y_down = event.touches[0].clientY;
},
false);
document.getElementById("app_header").addEventListener("touchmove",
function (event) {
if (!app_instance.hdr_x_down || !app_instance.hdr_y_down) {
return;
}
var x_up = event.touches[0].clientX,
y_up = event.touches[0].clientY,
delta_x = app_instance.hdr_x_down - x_up,
delta_y = app_instance.hdr_y_down - y_up;
if (Math.abs(delta_x) > Math.abs(delta_y)) {
if (delta_x > 0) {
/* left swipe */
app_instance.cur_block += 1;
if (app_instance.cur_block > app_instance.blocks_rotation.length - 1) {
app_instance.cur_block = 0;
}
} else {
/* right swipe */
app_instance.cur_block -= 1;
if (app_instance.cur_block < 0) {
app_instance.cur_block = app_instance.blocks_rotation.length - 1;
}
}
app_instance.widgets_run(app_instance.blocks_rotation[app_instance.cur_block]);
if (app_instance.blocks_rotation[app_instance.cur_block] === "system") {
app_instance.os_logo_draw();
}
// } else {
// if (delta_y > 0) {
/* up swipe */
// } else {
/* down swipe */
// }
}
/* reset values */
app_instance.hdr_x_down = null;
app_instance.hdr_y_down = null;
},
false);
/* Add ctrl pressed flag switcher */
document.addEventListener("keydown", function (event) {
if ((event.which === 17) && !app_instance.ctrl_on) {
app_instance.ctrl_on = true;
}
if (app_instance.ctrl_on) {
/* Temporary turn off ctrl flag */
app_instance.ctrl_on = false;
switch (event.which) {
case 37: // Ctrl + <-
app_instance.cur_block -= 1;
if (app_instance.cur_block < 0) {
app_instance.cur_block = app_instance.blocks_rotation.length - 1;
}
app_instance.widgets_run(app_instance.blocks_rotation[app_instance.cur_block]);
if (app_instance.blocks_rotation[app_instance.cur_block] === "system") {
app_instance.os_logo_draw();
}
event.preventDefault();
break;
case 39: // Ctrl + ->
app_instance.cur_block += 1;
if (app_instance.cur_block > app_instance.blocks_rotation.length - 1) {
app_instance.cur_block = 0;
}
app_instance.widgets_run(app_instance.blocks_rotation[app_instance.cur_block]);
if (app_instance.blocks_rotation[app_instance.cur_block] === "system") {
app_instance.os_logo_draw();
}
event.preventDefault();
break;
case 49: // Ctrl + 1
app_instance.widgets_run("system");
app_instance.os_logo_draw();
event.preventDefault();
break;
case 50: // Ctrl + 2
app_instance.widgets_run("system_pulse");
event.preventDefault();
break;
case 51: // Ctrl + 3
app_instance.widgets_run("storage");
event.preventDefault();
break;
case 52: // Ctrl + 4
app_instance.widgets_run("network");
event.preventDefault();
break;
case 53: // Ctrl + 5
app_instance.widgets_run("smb");
event.preventDefault();
break;
case 112: // Ctrl + F1
app_instance.help_show(false);
event.preventDefault();
break;
}
app_instance.ctrl_on = true;
}
});
document.addEventListener("keyup", function (event) {
if ((event.which === 17) && app_instance.ctrl_on) {
app_instance.ctrl_on = false;
}
});
};
/**
* Get data by uri
*
* @param {string} uri Data uri
*
* returns {undefined}
*/
Application.prototype.get_data = function (uri) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(this.responseText);
};
xhr.onerror = reject;
xhr.open("GET", uri);
xhr.send();
});
};
/**
* Initialize application
*
* @param {numeric} init_level Initialization level:
* 1 - Load settings,
* 2 - Load localization
* 3 - Initializa interface
*
* @returns {Boolean}
*/
Application.prototype.init = function (init_level) {
var app_instance = this,
json_file;
switch (init_level) {
case 1:
/* Add events handlers */
this.add_evt_handlers();
/* Load user defined settings */
this.get_data("system/json/settings.json")
.then(function(result) {
app_instance.settings = JSON.parse(result);
app_instance.init(2);
})
.catch(function(result) {
console_log("init 1 error: " + result);
});
break;
case 2:
/* Load general settings */
this.get_data("system/json/general_settings/")
.then(function(result) {
var general_settings = JSON.parse(result);
app_instance.settings.shutdown_enabled =
general_settings.shutdown_enabled;
app_instance.settings.reboot_enabled =
general_settings.reboot_enabled;
app_instance.settings.w_transmission_enabled =
general_settings.w_transmission_enabled;
app_instance.init(3);
})
.catch(function(result) {
console_log("init 2 error: " + result);
});
break;
case 3:
/* Load locale */
if ($_GET("lang")) {
json_file = "system/json/locale/" + $_GET("lang") + ".json";
} else {
json_file = "system/json/locale/" + this.settings.lang + ".json";
window.history.pushState(null, null, "?lang=" + this.settings.lang);
}
this.get_data(json_file)
.then(function(result) {
app_instance.lang = JSON.parse(result);
app_instance.init(4);
})
.catch(function(result) {
console_log("init 3 error: " + result);
});
break;
case 4:
/* Files rights check */
if (this.settings.check_files_rights) {
this.get_data("system/scripts/check_files.php")
.then(function(result) {
if (JSON.parse(result).length > 0) {
var div_info = document.createElement("div"),
text_info = document.createTextNode(app_instance.lang.fs_errors);
div_info.style.cursor = "pointer";
div_info.appendChild(text_info);
div_info.addEventListener("click", function () {
app_instance.page_clear();
app_instance.widget_run(app_instance.w_table_files_check);
});
document.getElementById("div_attention_content").appendChild(div_info);
document.getElementById("div_attention").classList.remove("hidden");
}
app_instance.init(5);
})
.catch(function(result) {
console_log("init 4 error: " + result);
});
} else {
this.init(5);
return;
}
break;
case 5:
/* Interface init */
/* Menu elements */
this.menu = {
"div_menu_info": {
"id" : "div_menu_info",
"caption" : this.lang.information,
"visible" : true,
"separator" : false,
"elements": {
"info_system": {
"icon" : "gfx/icons/server.png",
"caption" : this.lang.system,
"callback" : function () {
app_instance.widgets_run("system");
app_instance.os_logo_draw();
}
},
"info_pulse": {
"icon" : "gfx/icons/sysinfo.png",
"caption" : this.lang.system_pulse,
"callback" : function () {
app_instance.widgets_run("system_pulse");
}
},
"info_storage": {
"icon" : "gfx/icons/storage.png",
"caption" : this.lang.storage,
"callback" : function () {
app_instance.widgets_run("storage");
}
},
"info_network": {
"icon" : "gfx/icons/network.png",
"caption" : this.lang.network,
"callback" : function () {
app_instance.widgets_run("network");
}
},
"info_smb": {
"icon" : "gfx/icons/samba.png",
"caption" : this.lang.smb,
"callback" : function () {
app_instance.widgets_run("smb");
}
}
}
},
"div_menu_app": {
"id" : "div_menu_app",
"caption" : this.lang.applications,
"visible" : false,
"separator" : true,
"elements": {}
},
"div_settings": {
"id" : "div_menu_settings",
"caption" : "",
"visible" : true,
"separator" : true,
"elements" : {
"cp_settings": {
"icon" : "gfx/icons/settings.png",
"caption" : this.lang.settings,
"callback" : function () {
app_instance.settings_show();
}
},
"cp_help_about": {
"icon" : "gfx/icons/about.png",
"caption" : this.lang.about,
"callback" : function () {
app_instance.help_show(true);
}
},
"cp_help": {
"icon" : "gfx/icons/help.png",
"caption" : this.lang.help,
"callback" : function () {
app_instance.help_show(false);
}
}
}
},
"div_shutdown": {
"id" : "div_menu_shutdown",
"caption" : "",
"visible" : true,
"separator" : true,
"elements": {
"srv_reboot": {
"icon" : "gfx/icons/reboot.png",
"caption" : this.lang.reboot,
"callback" : function () {
app_instance.shutdown(true);
}
},
"srv_shutdown": {
"icon" : "gfx/icons/shutdown.png",
"caption" : this.lang.shutdown,
"callback" : function () {
app_instance.shutdown(false);
}
}
}
}
};
if (!this.settings.shutdown_enabled && !this.settings.reboot_enabled) {
delete this.menu.div_shutdown;
} else {
if (!this.settings.shutdown_enabled) {
delete this.menu.div_shutdown.elements.srv_shutdown;
}
if (!this.settings.reboot_enabled) {
delete this.menu.div_shutdown.elements.srv_reboot;
}
}
/* Widgets declarations */
this.w_table_drv_temp = {
parent : "page_content",
id : "drv_temp_info",
type : this.OT_TABLE_H,
label : this.lang.drv_temp_info,
class_name : "tbl_info",
json_uri : "system/scripts/?widget=hdd_temp",
raw_num : true,
refresh : 60
};
this.w_table_drv_smart = {
parent : "page_content",
id : "drv_smart_info",
type : this.OT_TABLE_H,
label : this.lang.drv_smart_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=hdd_smart",
raq_num : true,
refresh : 3600
};
this.w_table_fs_info = {
parent : "page_content",
id : "fs_info",
type : this.OT_TABLE_H,
label : this.lang.fs_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=fs",
raw_num : true,
refresh : 30
};
this.w_table_iostat_info = {
parent : "page_content",
id : "iostat_info",
type : this.OT_TABLE_H,
label : this.lang.iostat_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=io_stat",
raw_num : false,
refresh : 30
};
this.w_table_general_info = {
parent : "page_content",
id : "general_info",
type : this.OT_TABLE_V,
label : this.lang.general_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=general_info",
raw_num : true,
refresh : 10
};
this.w_table_cpu_info = {
parent : "page_content",
id : "cpu_info",
type : this.OT_TABLE_V,
label : this.lang.cpu_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=cpu_info",
raw_num : false,
refresh : 0
};
this.w_table_memory_info = {
parent : "page_content",
id : "memory_info",
type : this.OT_TABLE_V,
label : this.lang.memory_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=mem_info",
raw_num : false,
refresh : 0
};
this.w_table_processes = {
parent : "page_content",
id : "proc_info",
type : this.OT_TABLE_H,
label : this.lang.proc_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=processes",
raw_num : false,
refresh : 15
};
this.w_table_arp_cache = {
parent : "page_content",
id : "net_arp_cache_info",
type : this.OT_TABLE_H,
label : this.lang.net_arp_cache_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=arp_cache",
raw_num : true,
refresh : 0
};
this.w_table_ip_addr = {
parent : "page_content",
id : "net_ip_addr_info",
type : this.OT_TABLE_H,
label : this.lang.net_ip_addr_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=ip_addr",
raw_num : true,
refresh : 0
};
this.w_table_ip_route = {
parent : "page_content",
id : "net_ip_route_info",
type : this.OT_TABLE_H,
label : this.lang.net_ip_route_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=ip_route",
raw_num : true,
refresh : 0
};
this.w_table_net_band = {
parent : "page_content",
id : "net_band_info",
type : this.OT_TABLE_H,
label : this.lang.net_band_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=net_band",
raw_num : false,
refresh : 15
};
this.w_table_net_conn = {
parent : "page_content",
id : "net_conn_info",
type : this.OT_TABLE_H,
label : this.lang.net_conn_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=net_conn",
raw_num : true,
refresh : 15
};
this.w_table_net_mcast = {
parent : "page_content",
id : "net_mcast_info",
type : this.OT_TABLE_H,
label : this.lang.net_mcast_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=net_multicast",
raw_num : true,
refresh : 0
};
this.w_table_lstn_socks = {
parent : "page_content",
id : "net_lstn_socks_info",
type : this.OT_TABLE_H,
label : this.lang.net_lstn_socks_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=listen_socks",
raw_num : true,
refresh : 0
};
this.w_table_unix_socks = {
parent : "page_content",
id : "net_unix_socks_info",
type : this.OT_TABLE_H,
label : this.lang.net_unix_socks_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=active_unix_socks",
raw_num : true,
refresh : 0
};
this.w_table_transmission = {
parent : "page_content",
id : "transmission_info",
type : this.OT_TABLE_H,
label : this.lang.transmission_info,
class_name : "tbl_info",
json_uri : "system/scripts/json_transmission.php",
raw_num : false,
refresh : 30
};
this.w_table_users_online = {
parent : "page_content",
id : "users_online_info",
type : this.OT_TABLE_H,
label : this.lang.users_online_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=users_online",
raw_num : true,
refresh : 30
};
this.w_table_smb_shares = {
parent : "page_content",
id : "smb_shares_info",
type : this.OT_TABLE_H,
label : this.lang.smb_shares_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=smb_shares",
raw_num : true,
refresh : 30
};
this.w_table_smb_proc = {
parent : "page_content",
id : "smb_proc_info",
type : this.OT_TABLE_H,
label : this.lang.smb_proc_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=smb_proc",
raw_num : true,
refresh : 30
};
this.w_table_smb_locks = {
parent : "page_content",
id : "smb_locks_info",
type : this.OT_TABLE_H,
label : this.lang.smb_locks_info,
class_name : "tbl_info",
json_uri : "system/json/?widget=smb_locks",
raw_num : true,
refresh : 30
};
this.w_canvas_cpu_graph = {
parent : "page_content",
id : "cpu_graph",
type : this.OT_CANVAS,
label : this.lang.cpu_info,
class_name : "canvas_info",
json_uri : "system/json/?widget=cpu_load",
refresh : 5,
min_val : 0,
max_val : 100,
raw_num : true,
measure : "%"
};
this.w_canvas_mem_graph = {
parent : "page_content",
id : "mem_graph",
type : this.OT_CANVAS,
label : this.lang.memory_info,
class_name : "canvas_info",
json_uri : "system/json/?widget=mem",
refresh : 5,
min_val : 0,
max_val : "auto",
raw_num : true,
measure : "MB"
};
this.w_canvas_net_down_graph = {
parent : "page_content",
id : "net_down_graph",
type : this.OT_CANVAS,
label : this.lang.net_down_info,
class_name : "canvas_info",
json_uri : "system/json/?widget=net_download_transfer_rate",
refresh : 5,
min_val : 0,
max_val : "auto",
raw_num : true,
measure : "KB/s"
};
this.w_canvas_net_up_graph = {
parent : "page_content",
id : "net_up_graph",
type : this.OT_CANVAS,
label : this.lang.net_up_info,
class_name : "canvas_info",
json_uri : "system/json/?widget=net_upload_transfer_rate",
refresh : 5,
min_val : 0,
max_val : "auto",
raw_num : true,
measure : "KB/s"
};
this.w_canvas_swap_graph = {
parent : "page_content",
id : "swap_graph",
type : this.OT_CANVAS,
label : this.lang.swap_info,
class_name : "canvas_info",
json_uri : "system/json/?widget=swap",
refresh : 5,
min_val : 0,
max_val : "auto",
raw_num : true,
measure : "MB"
};
this.w_table_files_check = {
parent : "page_content",
id : "files_check",
type : this.OT_TABLE_H,
label : this.lang.fs_check,
class_name : "tbl_info",
raw_num : true,
json_uri : "system/scripts/check_files.php"
};
this.w_reboot_iframe = {
parent : "page_content",
id : "reboot_iframe",
type : this.OT_IFRAME,
label : this.lang.reboot,
class_name : "app_widget",
json_uri : "system/action/?lang=" + $_GET("lang") + "&do=reboot"
};
this.w_shutdown_iframe = {
parent : "page_content",
id : "shutdown_iframe",
type : this.OT_IFRAME,
label : this.lang.shutdown,
class_name : "app_widget",
json_uri : "system/action/?lang=" + $_GET("lang") + "&do=shutdown"
};
this.w_settings_iframe = {
parent : "page_content",
id : "iframe_settings",
type : this.OT_IFRAME,
label : this.lang.settings,
class_name : "app_widget",
json_uri : "system/ui/forms/settings/?lang=" + $_GET("lang")
};
this.w_about_iframe = {
parent : "page_content",
id : "iframe_cp_about",
type : this.OT_IFRAME,
label : this.lang.help,
class_name : "app_widget",
json_uri : "system/help/?lang=" + $_GET("lang") + "#about"
};
this.w_help_iframe = {
parent : "page_content",
id : "iframe_cp_help",
type : this.OT_IFRAME,
label : this.lang.help,
class_name : "app_widget",
json_uri : "system/help/?lang=" + $_GET("lang")
};
/* Widgets lists */
this.widgets_lists = {
"storage": [
{
"page_title" : this.lang.storage
},
this.w_table_drv_temp,
this.w_table_drv_smart,
this.w_table_fs_info,
this.w_table_iostat_info
],
"network": [
{
"page_title" : this.lang.network
},
this.w_canvas_net_down_graph,
this.w_canvas_net_up_graph,
{
"break" : true
},
this.w_table_ip_addr,
this.w_table_net_band,
this.w_table_ip_route,
this.w_table_users_online,
this.w_table_net_mcast,
this.w_table_arp_cache,
this.w_table_lstn_socks,
{
"widget_css" : "div_widget_full_width"
},
this.w_table_unix_socks,
{
"widget_css" : "div_widget_full_width"
},
this.w_table_net_conn,
this.w_table_transmission
],
"smb": [
{
"page_title" : this.lang.smb
},
this.w_table_smb_proc,
this.w_table_smb_shares,
{
"widget_css" : "div_widget_full_width"
},
this.w_table_smb_locks
],
"system": [
{
"page_title" : this.lang.system,
"widget_css" : "div_widget_type_a"
},
this.w_table_general_info,
this.w_table_memory_info,
this.w_table_cpu_info
],
"system_pulse": [
{
"page_title" : this.lang.system_pulse
},
this.w_canvas_cpu_graph,
this.w_canvas_mem_graph,
this.w_canvas_swap_graph,
this.w_canvas_net_down_graph,
this.w_canvas_net_up_graph,
{
"widget_css" : "div_widget_full_width"
},
this.w_table_processes
]
};
this.server_name_fill();
this.language_selector_add();
var m_menu = new MainMenu(this.lang);
m_menu.clear_menu(m_menu.main_menu);
m_menu.build_menu(this.menu);
this.apps_list_load();
// app.check_apps();
if (window.location.hash.substr(1) !== "") {
if (window.location.hash.substr(1) === "settings") {
this.settings_show();
} else if (window.location.hash.substr(1) === "cp_help") {
this.help_show(false);
} else if (window.location.hash.substr(1) === "cp_about") {
this.help_show(true);
} else if (window.location.hash.substr(1, 3) !== "app") {
this.widgets_run(window.location.hash.substr(1));
if (window.location.hash.substr(1) === "system") {
this.os_logo_draw();
}
} else {
this.app_execute(window.location.hash.substr(1));
}
} else {
this.widgets_run("system");
this.os_logo_draw();
}
/* Enable S.M.A.R.T and temperature monitoring */
this.monitoring_enable();
return true;
}
};
/**
* Add language selector to page's header
*
* @returns {undefined}
*/
Application.prototype.language_selector_add = function () {
var header = document.getElementById("app_header"),
select_lang = document.createElement("select");
select_lang.id = "lang";
select_lang.classList.add("select_lang");
if ($_GET("lang")) {
select_lang.classList.add("input_" + $_GET("lang"));
} else {
select_lang.classList.add("input_" + this.settings.lang);
}
select_lang.onchange = function () {
/*
* window.open(URL,name,specs,replace): where name:
*
* _blank - URL is loaded into a new window. This is default
* _parent - URL is loaded into the parent frame
* _self - URL replaces the current page
* _top - URL replaces any framesets that may be loaded
* name - The name of the window (Note: the name does not specify
* the title of the new window)
*/
window.open(this.options[this.selectedIndex].value, "_self");
};
for (var language in this.settings.langs) {
if (this.settings.langs.hasOwnProperty(language)) {
var opt_lang = document.createElement("option");
opt_lang.value = "?lang=" + language;
opt_lang.appendChild(document.createTextNode(this.settings.langs[language]));
if ($_GET("lang") && $_GET("lang") === language) {
opt_lang.selected = true;
} else if (!$_GET("lang") && this.settings.lang === language){
opt_lang.selected = true;
}
select_lang.appendChild(opt_lang);
}
}
header.appendChild(select_lang);
};
/**
* Change page title
*
* @param {string} new_title New page title
*
* @returns {undefined}
*/
Application.prototype.page_title_change = function (new_title) {
var srv_title = document.getElementById("s_header").textContent;
document.title = document.getElementById("s_header").textContent =
srv_title.substring(0, srv_title.indexOf("#") + 1) + " " + new_title;
};
/**
* Check application existance and remove from menu if unexisted
*
* @param {string} app_name Application name
* @param {string} app_exe Application executable
*
* @returns {undefined}
*/
Application.prototype.app_remove_unexisted = function (app_name, app_exe) {
this.get_data("system/json/?widget=check_app&param=" + app_exe)
.then(function(result) {
var element = document.getElementById("div_menu_" + app_name),
json_data = JSON.parse(result);
if ((json_data.exec !== "") && (!json_data.installed)) {
element.parentNode.removeChild(element);
} else {
element.classList.remove("hidden");
}
})
.catch(function(result) {
console_log("app_remove_unexisted error: " + result);
});
};
/**
* Draw OS distro logo
*
* @returns {undefined}
*/
Application.prototype.os_logo_draw = function () {
this.get_data("system/json/?widget=os_distr")
.then(function(result) {
var json_data = JSON.parse(result),
div_gi = document.getElementById("general_info");
if (!div_gi) {
return;
}
var img_logo = document.createElement("img");
img_logo.classList.add("distro_logo");
if (json_data.Distr.match(/opensuse/i)) {
img_logo.src = "gfx/distros/opensuse.png";
} else if (json_data.Distr.match(/arch/i)) {
img_logo.src = "gfx/distros/arch.png";
} else if (json_data.Distr.match(/bsd/i)) {
img_logo.src = "gfx/distros/bsd.png";
} else if (json_data.Distr.match(/debian/i)) {
img_logo.src = "gfx/distros/debian.png";
} else if (json_data.Distr.match(/fedora/i)) {
img_logo.src = "gfx/distros/fedora.png";
} else if (json_data.Distr.match(/ubuntu/i)) {
img_logo.src = "gfx/distros/ubuntu.png";
} else if (json_data.Family.match(/linux/i)) {
img_logo.src = "gfx/distros/linux.png";
} else if (json_data.Family.match(/darwin/i)) {
img_logo.src = "gfx/distros/apple.png";
} else {
img_logo.src = "gfx/distros/unknown.png";
}
div_gi.appendChild(img_logo);
})
.catch(function(result) {
console_log("Can't get disto info: " + result);
});
};
/**
* Clear page content
*
* returns {undefined}
*/
Application.prototype.page_clear = function () {
var parent_node = document.getElementById("page_content");
/* Clear timers */
for (var key in this.timers) {
if (this.timers.hasOwnProperty(key)) {
clearInterval(this.timers[key]);
}
}
this.timers = [];
/* Remove widgets */
while (parent_node.firstChild) {
parent_node.removeChild(parent_node.firstChild);
}
};
/**
* Open control panel with selected application or widgets screen in new
* window
*
* @param {string} hash URL hash
*
* @returns {undefined}
*/
Application.prototype.app_new_window = function (hash) {
var new_location = location.href.replace(location.hash,""),
new_win = window.open(new_location + "#" + hash, "_blank");
new_win.focus();
return;
};
/**
* Draw application widget
*
* @param {object} w_info Widget info
*
* @returns {undefined}
*/
Application.prototype.app_widget_draw = function (w_info) {
var app_hash = w_info.id.substring(7);
if (this.ctrl_on) {
this.app_new_window(app_hash);
return;
}
var app_widget = new Widget(this, w_info);
this.page_clear();
this.page_title_change(w_info.label);
app_widget.draw();
location.hash = app_hash;
document.getElementById(w_info.id).classList.remove("slightly_visible");
};
/**
* Fill server name on HTML page
*
* @returns {undefined}
*/
Application.prototype.server_name_fill = function () {
this.get_data("system/json/?widget=srv_name")
.then(function(result) {
var s_header = document.getElementById("s_header"),
json_data = JSON.parse(result);
if (s_header.textContent !== "Loading...") {
var temp = s_header.textContent;
s_header.removeChild(s_header.childNodes[0]);
s_header.appendChild(document.createTextNode(
json_data.server_name + " #" + temp));
} else {
s_header.removeChild(s_header.childNodes[0]);
s_header.appendChild(document.createTextNode(
json_data.server_name + " #"));
}
document.title = s_header.textContent;
})
.catch(function(result) {
console_log("server_name_fill error: " + result);
});
};
/**
* Execute application
*
* @param {string} app_name application name
*
* @returns {undefined}
*/
Application.prototype.app_execute = function (app_name) {
var app_instance = this;
this.get_data("system/apps/" + app_name.substr(4) + "/app.json")
.then(function(result) {
// TODO: Check why https_uri
var json_data = JSON.parse(result),
uri = json_data.https_uri,
app_iframe = {
parent : "page_content",
id : "iframe_" + json_data.app_name,
type : app_instance.OT_IFRAME,
label : json_data.caption,
class_name : "app_widget",
json_uri : uri.replace("[server_name]",
window.location.hostname)
};
app_instance.app_widget_draw(app_iframe);
})
.catch(function(result) {
console_log("app_execute error: " + result);
});
};
/**
* Enable HDD S.M.A.R.T. monitoring
*
* @param {numeric} timeout Timeout in seconds
*
* @returns {undefined}
*/
Application.prototype.monitor_hdd_smart = function (timeout) {
var app_instance = this;
setTimeout(function () {
app_instance.get_data("system/json/?widget=hdd_smart")
.then(function(result) {
var hdd_smart = JSON.parse(result),
cur_date = new Date();
for (var hdd in hdd_smart) {
if ((hdd_smart[hdd].status.toLowerCase() !== "passed") &&
(hdd_smart[hdd].status.toLowerCase() !== "ok")) {
app_instance.notify(app_instance.lang.attention,
{body: cur_date.toLocaleString() + ": " +
app_instance.lang.hdd_smart_error + " " +
hdd_smart[hdd].drive + " (" +
hdd_smart[hdd].status + ")",
tag: "cai_cp",
icon: "../gfx/icons/attention.png",
dir: "auto"},
function () {
app_instance.widgets_run("storage");
});
}
}
console_log("HDD SMART monitor");
app_instance.monitor_hdd_smart(timeout);
})
.catch(function(result) {
console_log("monitor_hdd_smart error: " + result);
app_instance.monitor_hdd_smart(timeout);
});
},
timeout * 1000);
};
/**
* Enable HDD temperature monitoring
*
* @param {numeric} timeout Timeout in seconds
*
* @returns {undefined}
*/
Application.prototype.monitor_hdd_temp = function (timeout) {
var app_instance = this;
setTimeout(function () {
app_instance.get_data("system/scripts/?widget=hdd_temp")
.then(function(result) {
var hdd_temp = JSON.parse(result),
cur_date = new Date();
for (var hdd in hdd_temp) {
if (hdd_temp[hdd].temperature.substring(0,
hdd_temp[hdd].temperature.length - 2) > app_instance.settings.max_hdd_temp) {
app_instance.notify(app_instance.lang.attention,
{body: cur_date.toLocaleString() + ": " +
app_instance.lang.hdd_overheat + " " +
hdd_temp[hdd].drive + " (" +
hdd_temp[hdd].model + "): " +
hdd_temp[hdd].temperature,
tag: "cai_cp",
icon: "../gfx/icons/attention.png",
dir: "auto"},
function () {
app_instance.widgets_run("storage");
});
}
}
console_log("HDD temperature monitor");
app_instance.monitor_hdd_temp(timeout);
})
.catch(function(result) {
console_log("monitor_hdd_temp error: " + result);
app_instance.monitor_hdd_temp(timeout);
});
},
timeout * 1000);
};
/**
* Enable online users monitoring
*
* @param {numeric} timeout Timeout in seconds
*
* @returns {undefined}
*/
Application.prototype.monitor_users_online = function (timeout) {
var app_instance = this;
setTimeout(function () {
app_instance.get_data("system/scripts/?widget=users_online")
.then(function(result) {
var users_online = JSON.parse(result),
cur_date = new Date();
if (users_online.length > app_instance.mon_users_info.count ||
users_online[users_online.length - 1].from !== app_instance.mon_users_info.last_addr ||
users_online[users_online.length - 1].user !== app_instance.mon_users_info.last_user) {
app_instance.notify(app_instance.lang.attention,
{body: cur_date.toLocaleString() + ": " +
app_instance.lang.new_user_connected +
" (" +
users_online[users_online.length - 1].user +
", " +
users_online[users_online.length - 1].from +
")",
tag: "cai_cp",
icon: "../gfx/icons/attention.png",
dir: "auto"},
function () {
app_instance.widgets_run("network");
});
}
app_instance.mon_users_info.count = users_online.length;
app_instance.mon_users_info.last_user = users_online[users_online.length - 1].user;
app_instance.mon_users_info.last_addr = users_online[users_online.length - 1].from;
console_log("Online users monitor");
app_instance.monitor_users_online(timeout);
})
.catch(function(result) {
console_log("monitor_users_online error: " + result);
app_instance.monitor_users_online(timeout);
});
},
timeout * 1000);
};
/**
* Enable monitoring functions
*
* @returns {undefined}
*/
Application.prototype.monitoring_enable = function () {
/* Set HDD temperature monitoring */
if (isNaN(this.settings.check_hdd_temp_interval)) {
this.settings.check_hdd_temp_interval = 0;
} else {
this.monitor_hdd_temp(this.settings.check_hdd_temp_interval);
}
/* Set S.M.A.R.T. monitoring */
if (isNaN(this.settings.check_smart_interval)) {
this.settings.check_smart_interval = 0;
} else {
this.monitor_hdd_smart(this.settings.check_smart_interval);
}
/* Set connected users monitoring */
if (isNaN(this.settings.check_users_online_interval)) {
this.settings.check_users_online_interval = 0;
} else {
this.monitor_users_online(this.settings.check_users_online_interval);
}
};
/**
* Show browser notification
*
* @param {string} title Notigication title
* @param {object} options Notification options
* @param {function} callback Callback function
*
* @returns {undefined}
*/
Application.prototype.notify = function (title, options, callback) {
if (!("Notification" in window) ||
(Notification.permission.toLowerCase() === "denied")) {
/* Notifications not supported or denied */
return;
}
if (Notification.permission === "granted") { // Notifications allowed
var notification = new Notification(title, options);
notification.onclick = callback;/* function () {
console.log("notification clicked");
}; */
} else { // Trying to get permissions
Notification.requestPermission(function (permission) {
if (permission === "granted") {
var notification = new Notification(title, options);
} /*else {
console.log("notifications prohibited");
} */
});
}
};
/**
* Register applications in menu
*
* @returns {undefined}
*/
Application.prototype.apps_register = function () {
var m_menu = new MainMenu(this.lang);
for (var key in this.apps_list) {
if (this.apps_list.hasOwnProperty(key)) {
m_menu.register_app(this, this.apps_list[key]);
document.getElementById("div_menu_app").classList.remove("hidden");
}
}
};
/**
* Load applications list
*
* @returns {undefined}
*/
Application.prototype.apps_list_load = function () {
var app_instance = this;
this.get_data("system/apps/apps.json")
.then(function(result) {
var json_data = JSON.parse(result);
app_instance.apps_list = json_data;
app_instance.apps_register();
})
.catch(function(result) {
console_log("apps_list_load error:" + result);
});
};
/**
* Run widget
*
* @param {object} widget_info Widget description
*
* @returns {undefined}
*/
Application.prototype.widget_run = function (widget_info) {
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
var w_index = Object.size(this.widgets); //this.widgets.length;
this.widgets[w_index] = new Widget(this, widget_info);
this.widgets[w_index].draw(this.widgets[w_index]);
if (widget_info.type === this.OT_TABLE_H ||
widget_info.type === this.OT_TABLE_V) {
this.widgets[w_index].update_table_data(this, w_index);
if (widget_info.refresh > 0) {
this.timers[widget_info.id] =
setInterval(this.widgets[w_index].update_table_data,
widget_info.refresh * 1000,
this, w_index);
}
} else if (widget_info.type === this.OT_CANVAS) {
this.widgets[w_index].update_canvas_data(this, w_index);
if (widget_info.refresh > 0) {
this.timers[widget_info.id] =
setInterval(this.widgets[w_index].update_canvas_data,
widget_info.refresh * 1000,
this, w_index);
}
}
};
/**
* Draws application widgets
*
* @param {array} block_name Name of widgets block
*
* @returns {undefined}
*/
Application.prototype.widgets_run = function (block_name) {
/* Open in new window if ctrl is pressed */
if (this.ctrl_on) {
this.app_new_window(block_name);
return;
}
if (typeof block_name === "undefined") {
return;
}
this.cur_block = this.blocks_rotation.indexOf(block_name);
var class_name = "div_widget",
no_widgets = false;
this.page_clear();
location.hash = block_name;
this.widgets = {};
for (var i = 0; i < this.widgets_lists[block_name].length; i++) {
no_widgets = false;
if (this.widgets_lists[block_name][i].widget_css !== undefined) {
/* Apply widget css */
no_widgets = true;
class_name = this.widgets_lists[block_name][i].widget_css;
} else if (this.widgets_lists[block_name][i].break !== undefined &&
this.widgets_lists[block_name][i].break === true) {
/* Insert break */
var div_break = document.createElement("div");
div_break.className = "div_clear";
document.getElementById("page_content").appendChild(div_break);
no_widgets = true;
}
if (this.widgets_lists[block_name][i].page_title !== undefined) {
this.page_title_change(this.widgets_lists[block_name][i].page_title);
no_widgets = true;
}
/* If widget info */
if (!no_widgets) {
if (!this.settings.w_transmission_enabled &&
this.widgets_lists[block_name][i].id === "transmission_info") {
/* Skip transmission widget if disabled */
} else {
this.widget_run(this.widgets_lists[block_name][i]);
/* Apply widget style class */
if (class_name !== "div_widget") {
document.getElementById(this.widgets_lists[block_name][i].id).classList.remove("div_widget");
document.getElementById(this.widgets_lists[block_name][i].id).classList.add(class_name);
}
}
}
}
};
/**
* Show help
*
* @param {bool} about_info Show "About" info
*
* @returns {undefined}
*/
Application.prototype.help_show = function (about_info) {
if (!this.ctrl_on) {
this.page_clear();
}
if (about_info) {
this.app_widget_draw(this.w_about_iframe);
} else {
this.app_widget_draw(this.w_help_iframe);
}
};
/**
* Show settings form
*
* @returns {undefined}
*/
Application.prototype.settings_show = function () {
if (!this.ctrl_on) {
this.page_clear();
}
this.app_widget_draw(this.w_settings_iframe);
};
/**
* Shutdown server
*
* @param {bool} reboot Reboot system flag
*
* @returns {undefined}
*/
Application.prototype.shutdown = function (reboot) {
if (reboot && window.confirm (this.lang.reboot_confirm)) {
this.page_clear();
this.app_widget_draw(this.w_reboot_iframe);
} else if (!reboot && window.confirm (this.lang.shutdown_confirm)) {
this.page_clear();
this.app_widget_draw(this.w_shutdown_iframe);
}
};
/**
* Main menu constructor
*
* @param {string} lang Language
*
* @returns {undefined}
*/
function MainMenu(lang) {
this.main_menu = document.getElementById("div_menu");
this.info_menu = document.getElementById("div_menu_info");
this.app_menu = document.getElementById("div_menu_app");
this.settings_menu = document.getElementById("div_menu_settings");
this.lang = lang;
}
/**
* Add icons block to menu
*
* @param {array} block_info Menu block information
*
* @returns {object} Menu block's div
*/
MainMenu.prototype.add_block = function (block_info) {
var div_menu_block = document.createElement("div"),
div_menu_block_caption = document.createElement("div");
div_menu_block.id = block_info.id;
div_menu_block.classList.add("div_menu_block");
if (!block_info.visible) {
div_menu_block.classList.add("hidden");
}
this.main_menu.appendChild(div_menu_block);
div_menu_block_caption.classList.add("div_menu_block_caption");
div_menu_block_caption.appendChild(document.createTextNode(block_info.caption));
div_menu_block.appendChild(div_menu_block_caption);
if (block_info.separator) {
div_menu_block.appendChild(document.createElement("hr"));
}
return div_menu_block;
};
/**
* Add menu item to menu block
*
* @param {object} parent_block Parent block for icon
* @param {string} id Menu item id
* @param {string} icon_src Path to icon file
* @param {string} caption Menu caption
* @param {bool} hidden Add menu in hidden state
* @param {object} callback_function OnClick callback function
*
* @returns {undefined}
*/
MainMenu.prototype.add_item = function (parent_block,
id,
icon_src,
caption,
hidden,
callback_function) {
var m_item_div = document.createElement("div"),
m_item_img = document.createElement("img"),
m_item_footer_div = document.createElement("div");
m_item_div.id = "div_" + id;
m_item_div.classList.add("div_m_item");
m_item_div.onclick = callback_function;
/*
m_item_div.addEventListener("contextmenu", function(e) {
e.preventDefault();
});
*/
if (hidden) {
m_item_div.classList.add("hidden");
}
m_item_img.classList.add("menu_icon");
m_item_img.src = icon_src;
m_item_div.appendChild(m_item_img);
m_item_footer_div.classList.add("div_m_item_footer");
m_item_footer_div.appendChild(document.createTextNode(caption));
m_item_div.appendChild(m_item_footer_div);
parent_block.appendChild(m_item_div);
};
/**
* Build menu structure
*
* @param {object} menu_items menu structure
*
* @returns {undefined}
*/
MainMenu.prototype.build_menu = function (menu_items) {
var div_ctrl_hint = document.createElement("div");
div_ctrl_hint.classList.add("top_right_hint");
div_ctrl_hint.appendChild(document.createTextNode(this.lang.ctrl_click_hint));
this.main_menu.appendChild(div_ctrl_hint);
for (var menu_block in menu_items) {
if (menu_items.hasOwnProperty(menu_block)) {
var div_menu_block = this.add_block(menu_items[menu_block]);
for (var menu_item in menu_items[menu_block].elements) {
if (menu_items[menu_block].elements.hasOwnProperty(menu_item)) {
this.add_item(
div_menu_block,
menu_item,
menu_items[menu_block].elements[menu_item].icon,
menu_items[menu_block].elements[menu_item].caption,
false,
menu_items[menu_block].elements[menu_item].callback
);
}
}
var div_clear = document.createElement("div");
div_clear.classList.add("div_clear");
div_menu_block.appendChild(div_clear);
this.main_menu.appendChild(div_menu_block);
}
}
};
/**
* Clear menu or submenu
*
* @param {object} menu Menu object to clear
*
* @returns {undefined}
*/
MainMenu.prototype.clear_menu = function (menu) {
while (menu.firstChild) {
menu.removeChild(menu.firstChild);
}
};
/**
* Register application in menu
*
* @param {object} app_instance Application instance
* @param {string} app_dir Directory containing app.json file with
* application info
*
* @returns {undefined}
*/
MainMenu.prototype.register_app = function (app_instance, app_dir) {
var menu_obj = this;
app_instance.get_data("system/apps/" + app_dir + "/app.json")
.then(function(result) {
var json_data = JSON.parse(result),
parent_block = document.getElementById("div_menu_app"),
uri,
app_iframe;
switch (window.location.protocol) {
case "https:":
if (json_data.use_https && json_data.https_uri !== "") {
if (json_data.frame_support) {
uri = json_data.https_uri;
/* run in frame */
app_iframe = {
parent : "page_content",
id : "iframe_" + json_data.app_name,
type : app_instance.OT_IFRAME,
label : json_data.caption,
class_name : "app_widget",
json_uri : uri.replace("[server_name]",
window.location.hostname)
};
menu_obj.add_item(parent_block,
"menu_" + json_data.app_name,
"system/apps/" + app_dir + "/icon.png",
json_data.caption,
json_data.exec !== "",
function () {
app_instance.app_widget_draw(app_iframe);
}
);
} else {
menu_obj.add_item(parent_block,
"menu_" + json_data.app_name,
"system/apps/" + app_dir + "/icon.png",
json_data.caption,
json_data.exec !== "",
function () {
var uri = json_data.https_uri;
window.open(uri.replace("[server_name]",
window.location.hostname),
"_blank");
}
);
}
} else if (json_data.use_http && json_data.http_uri !== "") {
menu_obj.add_item(parent_block,
"menu_" + json_data.app_name,
"system/apps/" + app_dir + "/icon.png",
json_data.caption,
json_data.exec !== "",
function () {
var uri = json_data.http_uri;
window.open(uri.replace("[server_name]",
window.location.hostname),
"_blank");
}
);
}
break;
case "http:":
if (json_data.use_http && json_data.http_uri !== "") {
if (json_data.frame_support) {
uri = json_data.http_uri;
/* run in frame */
app_iframe = {
parent : "page_content",
id : "iframe_" + json_data.app_name,
type : app_instance.OT_IFRAME,
label : json_data.caption,
class_name : "app_widget",
json_uri : uri.replace("[server_name]",
window.location.hostname)
};
menu_obj.add_item(parent_block,
"menu_" + json_data.app_name,
"system/apps/" + app_dir + "/icon.png",
json_data.caption,
json_data.exec !== "",
function () {
app_instance.app_widget_draw(app_iframe);
}
);
} else {
menu_obj.add_item(parent_block,
"menu_" + json_data.app_name,
"system/apps/" + app_dir + "/icon.png",
json_data.caption,
json_data.exec !== "",
function () {
var uri = json_data.http_uri;
window.open(uri.replace("[server_name]",
window.location.hostname),
"_blank");
}
);
}
} else if (json_data.use_https && json_data.https_uri !== "") {
menu_obj.add_item(parent_block,
"menu_" + json_data.app_name,
"system/apps/" + app_dir + "/icon.png",
json_data.caption,
json_data.exec !== "",
function () {
var uri = json_data.https_uri;
window.open(uri.replace("[server_name]",
window.location.hostname),
"_blank");
}
);
}
break;
}
for (var i = 0; i < json_data.require.length; i++) {
app_instance.app_remove_unexisted(json_data.app_name,
json_data.require[i].data);
}
})
.catch(function(result) {
console_log("register_app error: " + result);
});
};
/**
* Widgets constructor
*
* @param {object} caller Caller object
* @param {array} w_info Array with Widget information
* @param {string} w_data Widget data
*
* @returns {undefined}
*/
function Widget(caller, w_info, w_data) {
this.parent_app = caller;
this.info = w_info;
this.data = w_data || null;
this.parent_el = document.getElementById(w_info.parent);
/* Double tap on header handler vars */
this.dt_hdr_timeout = null;
this.dt_hdr_tap_time = 0;
}
/**
* Toggle maximized widget state
*
* @returns {undefined}
*/
Widget.prototype.toggle_maximized = function () {
var parent_node = document.getElementById(this.parentNode.id);
if (parent_node.classList.contains("canvas_info")) {
return;
}
document.getElementById(this.parentNode.id).classList.toggle("div_maximized");
for (var i = 0; i < parent_node.childNodes.length; i++) {
if (parent_node.childNodes[i].classList.contains("div_w_content_container")) {
parent_node.childNodes[i].classList.toggle("div_maximized_content");
}
}
};
/**
* Draw widget
*
* @returns {undefined}
*/
Widget.prototype.draw = function () {
var widget_instance = this,
widget_node,
widget_c_container;
if (document.getElementById(this.info.id) !== null) {
widget_node = document.getElementById(this.info.id);
widget_c_container = widget_node.childNodes[1];
widget_c_container.removeChild(widget_c_container.childNodes[0]);
} else {
var widget_head = document.createElement("div");
widget_node = document.createElement("div");
widget_node.classList.add("div_widget");
if (this.parent_app.settings.dim_on_create) {
widget_node.classList.add("slightly_visible");
}
widget_node.id = this.info.id;
if (this.info.class_name !== "") {
widget_node.classList.add(this.info.class_name);
}
widget_head.classList.add("div_w_head");
widget_head.appendChild(document.createTextNode(this.info.label));
widget_head.addEventListener("dblclick", this.toggle_maximized);
/* Add double tap event */
widget_head.addEventListener("touchend", function(event) {
var cur_time = new Date().getTime(),
tap_len = cur_time - this.dt_hdr_tap_time;
clearTimeout(widget_instance.dt_hdr_timeout);
if (tap_len < 500 && tap_len > 0) {
event.preventDefault();
widget_instance.toggle_maximized();
} else {
widget_instance.dt_hdr_timeout = setTimeout(function() {
clearTimeout(widget_instance.dt_hdr_timeout);
}, 500);
}
widget_instance.dt_hdr_tap_time = cur_time;
});
widget_c_container = document.createElement("div");
widget_c_container.classList.add("div_w_content_container");
widget_node.appendChild(widget_head);
widget_node.appendChild(widget_c_container);
this.parent_el.appendChild(widget_node);
}
var widget_content = document.createElement("div");
widget_content.classList.add("div_w_content");
widget_c_container.appendChild(widget_content);
switch (this.info.type) {
case this.parent_app.OT_TABLE_H:
case this.parent_app.OT_TABLE_V:
var table_node = this.html_table(this.info.type === this.parent_app.OT_TABLE_V);
if (this.info.class_name !== "") {
table_node.classList.add(this.info.class_name);
}
widget_content.appendChild(table_node);
break;
case this.parent_app.OT_IFRAME:
var iframe_node = document.createElement("iframe");
iframe_node.src = this.info.json_uri;
widget_content.appendChild(iframe_node);
break;
case this.parent_app.OT_CANVAS:
var canvas_node = document.createElement("canvas"),
s_settings = {interpolation: this.info.interpolation,
//interpolation : "linear",
//interpolation : "step",
grid : {sharpLines : true,
borderVisible : false,
verticalSections : 4,
millisPerLine : 10000},
labels : {disabled : false},
timestampFormatter : SmoothieChart.timeFormatter,
millisPerPixel : 100 //tooltip : true
};
canvas_node.id = "canvas_" + this.info.id;
canvas_node.width = 400;
canvas_node.height = 154;
widget_content.appendChild(canvas_node);
if (this.info.max_val !== "auto") {
s_settings.maxValue = this.info.max_val;
}
if (this.info.min_val !== "auto") {
s_settings.minValue = this.info.min_val;
}
this.smoothie = new SmoothieChart(s_settings);
this.lines = [];
this.smoothie.streamTo(document.getElementById(canvas_node.id),
this.info.refresh * 1000);
}
};
/**
* Fill table headers
*
* @param {object} table Parent table
*
* @returns {object}
*/
Widget.prototype.fill_table_headers = function (table) {
var col_set = [];
if (this.data !== null) {
var tr = document.createElement("tr");
for (var i = 0, l = this.data.length; i < l; i++) {
for (var key in this.data[i]) {
if (this.data[i].hasOwnProperty(key) && col_set.indexOf(key) === -1) {
col_set.push(key);
var th = document.createElement("th");
th.appendChild(document.createTextNode(key));
tr.appendChild(th);
}
}
}
table.appendChild(tr);
}
return col_set;
};
/**
* Return HTML table filled with data
*
* @returns {object}
*/
Widget.prototype.html_table = function () {
var table = document.createElement("table"),
tr;
if (this.data !== null) {
if (this.info.type === this.parent_app.OT_TABLE_V) {
var even_line = false;
for (var key in this.data[0]) {
if (this.data[0].hasOwnProperty(key)) {
var td_key = document.createElement("td"),
td_val = document.createElement("td");
tr = document.createElement("tr");
td_key.appendChild(document.createTextNode(key));
td_key.classList.add("table_header");
if (this.info.raw_num) {
td_val.appendChild(document.createTextNode(this.data[0][key] || ""));
} else {
td_val.appendChild(
document.createTextNode(
numFormatted(this.data[0][key], "'") || ""
)
);
}
tr.appendChild(td_key);
tr.appendChild(td_val);
if (even_line) {
tr.classList.add("even_line");
}
even_line = !even_line;
table.appendChild(tr);
}
}
} else {
var columns = this.fill_table_headers(table);
for (var i = 0, max_i = this.data.length; i < max_i; ++i) {
tr = document.createElement("tr");
for (var j = 0, max_j = columns.length; j < max_j ; ++j) {
var td = document.createElement("td");
if (this.info.raw_num) {
td.appendChild(
document.createTextNode(
this.data[i][columns[j]] || ""
)
);
} else {
td.appendChild(
document.createTextNode(
numFormatted(this.data[i][columns[j]], "'") || ""
)
);
}
tr.appendChild(td);
}
if (i % 2 !== 0) {
tr.classList.add("even_line");
}
table.appendChild(tr);
}
}
}
return table;
};
/**
* Update canvas widget data
*
* @param {object} app_instance Application object instance
* @param {numeric} index Widget index
*
* @returns {undefined}
*/
Widget.prototype.update_canvas_data = function (app_instance, index) {
var w_instance = app_instance.widgets[index],
colors = [
["rgb(0, 255, 0)", "rgba(0, 255, 0, 0.4)"], // green
["rgb(255, 0, 0)", "rgba(255, 0, 0, 0.4)"], // red
["rgb(255, 255, 0)", "rgba(255, 255, 0, 0.4)"], // yellow
["rgb(0, 255, 255)", "rgba(0, 255, 255, 0.4)"],
["rgb(0, 0, 255)", "rgba(0, 0, 255, 0.4)"], // blue
["rgb(255, 255, 255)", "rgba(255, 255, 255, 0.4)"],
["rgb(128, 255, 255)", "rgba(128, 255, 255, 0.4)"],
["rgb(255, 128, 255)", "rgba(255, 128, 255, 0.4)"],
["rgb(255, 255, 128)", "rgba(255, 255, 128, 0.4)"],
["rgb(128, 128, 255)", "rgba(128, 128, 255, 0.4)"],
["rgb(255, 128, 128)", "rgba(255, 128, 128, 0.4)"],
["rgb(128, 255, 128)", "rgba(128, 255, 128, 0.4)"],
["rgb(0, 128, 255)", "rgba(0, 128, 255, 0.4)"],
["rgb(255, 0, 128)", "rgba(255, 0, 128, 0.4)"],
["rgb(128, 255, 0)", "rgba(128, 255, 0, 0.4)"],
["rgb(0, 0, 128)", "rgba(0, 0, 128, 0.4)"]
];
app_instance.get_data(w_instance.info.json_uri)
.then(function(result) {
var json_data = JSON.parse(result),
i = 0;
if (document.getElementById(w_instance.info.id) === null) {
return;
}
var content_container = document.getElementById(w_instance.info.id).children[1],
div_legend;
for (var key in json_data) {
if (json_data.hasOwnProperty(key)) {
if (w_instance.lines.length < i + 1) {
div_legend = document.createElement("div");
div_legend.id = w_instance.info.id + "_" + key;
div_legend.style.color = colors[i][0];
div_legend.classList.add("canvas_legend");
div_legend.appendChild(document.createTextNode (key));
content_container.appendChild(div_legend);
w_instance.lines.push(new TimeSeries());
w_instance.smoothie.addTimeSeries(
w_instance.lines[i],
{strokeStyle : colors[i][0],
fillStyle : colors[i][1],
lineWidth : 3}
);
} else {
div_legend = document.getElementById(
w_instance.info.id + "_" + key
);
if (div_legend === null) {
return;
}
}
div_legend.textContent = key + ": "
+ json_data[key]
+ w_instance.info.measure;
div_legend.classList.remove("slightly_visible");
w_instance.lines[i].append(new Date().getTime(),
Math.floor(json_data[key]));
document.getElementById(w_instance.info.id).classList.remove("slightly_visible");
i++;
}
}
})
.catch(function(result) {
console_log("update_canvas_data error: " + result);
});
};
/**
* Draw table widget
*
* @param {object} app_instance Application object instance
* @param {numeric} index Widget index
*
* @returns {undefined}
*/
Widget.prototype.update_table_data = function (app_instance, index) {
var w_instance = app_instance.widgets[index];
app_instance.get_data(w_instance.info.json_uri)
.then(function(result) {
var json_data = JSON.parse(result);
if (document.getElementById(w_instance.info.id) !== null) {
w_instance.data = json_data;
w_instance.draw();
document.getElementById(w_instance.info.id).classList.remove("slightly_visible");
}
})
.catch(function(result) {
console_log("update_table_data error: " + result);
});
};
document.addEventListener("DOMContentLoaded", function () {
/**
* Initialize application object
*/
var app = new Application();
});
}());