|
@@ -0,0 +1,1538 @@
|
|
|
+function $(id) {return document.getElementById(id);}
|
|
|
+
|
|
|
+function getCookie(name){
|
|
|
+ "use strict";
|
|
|
+ var strCookie = document.cookie,
|
|
|
+ arrCookie = strCookie.split('; ');
|
|
|
+ for (var i = 0; i < arrCookie.length; i++){
|
|
|
+ var arr = arrCookie[i].split('=');
|
|
|
+ if (arr[0] == name) return window.unescape(arr[1]);
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+}
|
|
|
+
|
|
|
+function setCookie(name,value,expirehours){
|
|
|
+ var cookieString = name + '=' + window.escape(value);
|
|
|
+ if (expirehours > 0) {
|
|
|
+ var date = new Date();
|
|
|
+ date.setTime(date.getTime() + expirehours * 3600 * 1000);
|
|
|
+ cookieString = cookieString + '; expires=' + date.toGMTString();
|
|
|
+ }
|
|
|
+ document.cookie = cookieString;
|
|
|
+}
|
|
|
+
|
|
|
+function deleteCookie(name) {
|
|
|
+ document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
|
|
+}
|
|
|
+
|
|
|
+// ############### Mobile Device ################
|
|
|
+
|
|
|
+if (window.screen.width < 769) {
|
|
|
+ $('nav').style.display = 'none';
|
|
|
+}
|
|
|
+
|
|
|
+$('menu-icon').onclick = function(){
|
|
|
+ $('nav').style.display = $('nav').style.display == 'none' ? 'block' : 'none';
|
|
|
+};
|
|
|
+
|
|
|
+//########## Main Page Alert Handler ############
|
|
|
+
|
|
|
+// fadeIn animation special for alerts
|
|
|
+function fadeIns(el){
|
|
|
+ el.style.opacity = 0;
|
|
|
+ (function fade() {
|
|
|
+ var val = parseFloat(el.style.opacity);
|
|
|
+ if (((val += 0.03) > 1) !== true) {
|
|
|
+ el.style.opacity = val;
|
|
|
+ var request = requestFrame('request');
|
|
|
+ request(fade);
|
|
|
+ }
|
|
|
+ })();
|
|
|
+}
|
|
|
+
|
|
|
+var ac = $('AC'),
|
|
|
+ dc = $('DC'),
|
|
|
+ in_freq = $('in_freq'),
|
|
|
+ out_freq = $('out_freq'),
|
|
|
+ pwr = $('pwr'),
|
|
|
+ bat_cap = $('bat_cap'),
|
|
|
+ inner_temp = $('inner_temp'),
|
|
|
+ battimeleft = $('bat_time_left'),
|
|
|
+ alarm = $('alarm'),
|
|
|
+ sPower = $('sPower'),
|
|
|
+ sBattery = $('sBattery');
|
|
|
+var battempCtrlChecked;
|
|
|
+
|
|
|
+function dataFadeIn(){
|
|
|
+ var x = [
|
|
|
+ ac,
|
|
|
+ dc,
|
|
|
+ in_freq,
|
|
|
+ out_freq,
|
|
|
+ pwr,
|
|
|
+ bat_cap,
|
|
|
+ inner_temp,
|
|
|
+ battimeleft,
|
|
|
+ sPower,
|
|
|
+ sBattery
|
|
|
+ ];
|
|
|
+ for (var i = 0; i < x.length; i++){
|
|
|
+ fadeIns(x[i]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Alarm colors
|
|
|
+var ALARM_RED = '#ff5050',
|
|
|
+ ALARM_YELLOW = '#f0ad4e',
|
|
|
+ ALARM_GREEN = '#33cc00';
|
|
|
+
|
|
|
+function checkState() {
|
|
|
+
|
|
|
+ // Asign variable to alarm bit mask number
|
|
|
+ var INPUT_VOLTAGE_H = 0,
|
|
|
+ INPUT_VOLTAGE_L = 1,
|
|
|
+ OUTPUT_VOLTAGE = 2,
|
|
|
+ CURRENT_CONS = 3,
|
|
|
+ LOAD_VOLTAGE = 4,
|
|
|
+ LOAD_CURRENT = 5,
|
|
|
+ INNER_TEMP = 6,
|
|
|
+ DOOR_SENS = 7,
|
|
|
+ ACB_TEMP = 8,
|
|
|
+ ACB_VOLTAGE = 9,
|
|
|
+ ACB_CURRENT = 10,
|
|
|
+ ACB_SYMMETRY = 11,
|
|
|
+ CURRENT_CONS_A = 12;
|
|
|
+
|
|
|
+ // Alarm bit mask parser
|
|
|
+ function A (num) {
|
|
|
+ var a = alarm.innerHTML;
|
|
|
+ var b = parseInt(a.split('').reverse().join(''), 2);
|
|
|
+ var answ = (b & (1 << num)) >> num;
|
|
|
+ return answ;
|
|
|
+ }
|
|
|
+ function rgb2hex(rgb) {
|
|
|
+ if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb;
|
|
|
+
|
|
|
+ rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
|
|
+ function hex(x) {
|
|
|
+ return ("0" + parseInt(x).toString(16)).slice(-2);
|
|
|
+ }
|
|
|
+ return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
|
|
|
+ }
|
|
|
+}
|
|
|
+function panelState(stateControl, panelID){
|
|
|
+ var title = panelID.textContent;
|
|
|
+ if (stateControl){
|
|
|
+ panelID.style.color = ALARM_GREEN;
|
|
|
+ panelID.innerHTML = '<span class="mark-ok"></span>' + title;
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ panelID.style.color = ALARM_RED;
|
|
|
+ panelID.innerHTML = '<span class="mark-almaj"></span>' + title;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//########## Settings Inform Boxes ############
|
|
|
+
|
|
|
+function HTMLcreate(htmlStr) {
|
|
|
+ var frag = document.createDocumentFragment(),
|
|
|
+ temp = document.createElement('div');
|
|
|
+ temp.innerHTML = htmlStr;
|
|
|
+ while (temp.firstChild) {
|
|
|
+ frag.appendChild(temp.firstChild);
|
|
|
+ }
|
|
|
+ return frag;
|
|
|
+}
|
|
|
+// fade out animation
|
|
|
+function fadeOut(el){
|
|
|
+ el.style.opacity = 1;
|
|
|
+
|
|
|
+ (function fade() {
|
|
|
+ if ((val -= 0.05) < 0) {
|
|
|
+ el.style.display = "none";
|
|
|
+ } else {
|
|
|
+ var request = requestFrame('request');
|
|
|
+ request(fade);
|
|
|
+ }
|
|
|
+ })();
|
|
|
+}
|
|
|
+// fade in animation
|
|
|
+function fadeIn(el, display){
|
|
|
+ el.style.opacity = 0;
|
|
|
+ el.style.display = display || 'block';
|
|
|
+
|
|
|
+ (function fade() {
|
|
|
+ var val = parseFloat(el.style.opacity);
|
|
|
+ if (((val += 0.05) > 1) !== true) {
|
|
|
+ el.style.opacity = val;
|
|
|
+ var request = requestFrame('request');
|
|
|
+ request(fade);
|
|
|
+ }
|
|
|
+ })();
|
|
|
+}
|
|
|
+// Shows confirm box if Network settings were changed
|
|
|
+var netsettings_changed;
|
|
|
+var netsettings_executed = false;
|
|
|
+function netsettings_changedCheck() {
|
|
|
+ if (netsettings_changed == 'true') {
|
|
|
+ if (!netsettings_executed) {
|
|
|
+ netsettings_executed = true;
|
|
|
+ var ch_element = HTMLcreate(
|
|
|
+ '<div id="apply-settings">'+
|
|
|
+ '<p>Внимание, для применения сетевых настроек необходимо их подтвердить.'+
|
|
|
+ ' Иначе они будут сброшены в течении 10 минут.</p>'+
|
|
|
+ '<a href="confirm.cgi" class="btn btn-danger">Подтвердить</a>'+
|
|
|
+ '</div>'
|
|
|
+ );
|
|
|
+ document.body.insertBefore(ch_element, document.body.childNodes[0]);
|
|
|
+ fadeIn($('apply-settings'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+setInterval(netsettings_changedCheck, 100);
|
|
|
+
|
|
|
+var connect_monitor;
|
|
|
+var conmon_executed = false;
|
|
|
+function connect_monitorCheck() {
|
|
|
+ if (connect_monitor) {
|
|
|
+ if (!conmon_executed) {
|
|
|
+ conmon_executed = true;
|
|
|
+ var ch_element = HTMLcreate(
|
|
|
+ '<div>'+
|
|
|
+ '<div id="device-error">'+
|
|
|
+ '<b>Внимание, связь с UPS не установлена!</b>'+
|
|
|
+ '</div>'+
|
|
|
+ '</div>'
|
|
|
+ );
|
|
|
+ document.body.insertBefore(ch_element, document.body.childNodes[0]);
|
|
|
+ fadeIn($('device-error'));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (conmon_executed) {
|
|
|
+ conmon_executed = false;
|
|
|
+ $('device-error').parentNode.innerHTML = '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+setInterval(connect_monitorCheck, 100);
|
|
|
+
|
|
|
+//########## Settings Form ############
|
|
|
+
|
|
|
+function formValidation(){
|
|
|
+ var read_community = $('read_community'),
|
|
|
+ write_community = $('write_community'),
|
|
|
+ managerIP = $('managerIP'),
|
|
|
+ managerIP2 = $('managerIP2'),
|
|
|
+ managerIP3 = $('managerIP3'),
|
|
|
+ ipaddr = $('ipaddr'),
|
|
|
+ gw = $('gw'),
|
|
|
+ mask = $('mask'),
|
|
|
+ ntpservip = $('ntpservip');
|
|
|
+
|
|
|
+ var flag = true;
|
|
|
+ if (!$('dhcp').checked) {
|
|
|
+ if(!ValidateIPaddress(ipaddr, ' IP-адрес устройства')) flag = false;
|
|
|
+ if(!ValidateIPaddress(gw, ' IP-адрес шлюза')) flag = false;
|
|
|
+ if(!ValidateIPaddress(mask, 'а Маска подсети')) flag = false;
|
|
|
+ }
|
|
|
+ if(!ValidateIPaddress(managerIP, ' Сервер SNMP 1')) flag = false;
|
|
|
+ if(!ValidateAlphanumeric(read_community, 'Read Community')) flag = false;
|
|
|
+ if(!ValidateAlphanumeric(write_community, 'Write Community')) flag = false;
|
|
|
+ if(!ValidateIPaddress(managerIP2, ' Сервер SNMP 2')) flag = false;
|
|
|
+ if(!ValidateIPaddress(managerIP3, ' Сервер SNMP 3')) flag = false;
|
|
|
+
|
|
|
+ return flag;
|
|
|
+}
|
|
|
+
|
|
|
+function ValidateIPaddress(ipaddress, z) {
|
|
|
+ var warn = document.createElement('li');
|
|
|
+ warn.innerHTML = 'Неправильно задан' + z + '!';
|
|
|
+ if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress.value)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ $('validation-box').appendChild(warn);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function ValidateTemperature(minTemp, maxTemp) {
|
|
|
+ var warn = document.createElement('li');
|
|
|
+ warn.innerHTML = 'Верхняя граница температуры должна превышать нижнюю!';
|
|
|
+ if (Number(minTemp.value) < Number(maxTemp.value)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ $('validation-box').appendChild(warn);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function ValidateMinMax(elem, ID, name) {
|
|
|
+ var warn = document.createElement('li');
|
|
|
+ var minValue = elem.options.minimum;
|
|
|
+ var maxValue = elem.options.maximum;
|
|
|
+ var curValue = $(ID).childNodes[0].value;
|
|
|
+ var boolVale = true;
|
|
|
+ if (curValue < minValue) {
|
|
|
+ warn.innerHTML = 'Значение ' + name + ' не может быть ниже ' + minValue;
|
|
|
+ $('validation-box').appendChild(warn);
|
|
|
+ boolVale = false;
|
|
|
+ }
|
|
|
+ else if (curValue > maxValue) {
|
|
|
+ warn.innerHTML = 'Значение ' + name + ' не может быть выше ' + maxValue;
|
|
|
+ $('validation-box').appendChild(warn);
|
|
|
+ boolVale = false;
|
|
|
+ } else { boolVale = true; }
|
|
|
+ return boolVale;
|
|
|
+}
|
|
|
+
|
|
|
+function ValidateAlphanumeric(uadd, z) {
|
|
|
+ var warn = document.createElement('li');
|
|
|
+ var letter = /^[0-9a-zA-Z]+$/;
|
|
|
+ warn.innerHTML = 'Поле ' + z + ' может содержать только латинские буквы и цифры';
|
|
|
+ if (letter.test(uadd.value)) {return true;}
|
|
|
+ $('validation-box').appendChild(warn);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function submitForms() {
|
|
|
+ if (confirm("Вы уверены что хотите применить настройки?")) {
|
|
|
+ if ($('ntp-inp')) {
|
|
|
+ $('ntpservip').options[3].value = $('ntp-inp').value;
|
|
|
+ }
|
|
|
+ if (formValidation()) {
|
|
|
+ $('form1').submit();
|
|
|
+ netsettings_changedCheck();
|
|
|
+ connect_monitor_changedCheck();
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ $('validation-box').style.display = 'block';
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+var pwdIsCorrect;
|
|
|
+function loadXMLDoc(url, method, callback) {
|
|
|
+ var xmlhttp;
|
|
|
+ if (window.XMLHttpRequest) {
|
|
|
+ xmlhttp = new XMLHttpRequest();
|
|
|
+ } else {
|
|
|
+ xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
|
|
|
+ }
|
|
|
+ xmlhttp.open(method, url, true);
|
|
|
+ var status;
|
|
|
+ xmlhttp.onreadystatechange = function () {
|
|
|
+ if (xmlhttp.readyState == 4) {
|
|
|
+ status = xmlhttp.status;
|
|
|
+ if (status == 200) {
|
|
|
+ pwdIsCorrect = xmlhttp.responseText;
|
|
|
+ if (typeof callback == 'function') {
|
|
|
+ callback.apply(xmlhttp);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log('Error');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ xmlhttp.send();
|
|
|
+}
|
|
|
+function checkPWD(){
|
|
|
+ var pass = $('pwd').value;
|
|
|
+ var letter = /^[0-9a-zA-Z]+$/;
|
|
|
+ var postPass;
|
|
|
+ if (letter.test(pass)) {
|
|
|
+ loadXMLDoc(
|
|
|
+ 'checkpwd.cgi?password='+pass,
|
|
|
+ 'POST',
|
|
|
+ function() {
|
|
|
+ postPass = parseInt(this.responseText);
|
|
|
+ if (postPass == 1) {
|
|
|
+ $('checkUpdatePass').style.display = 'none';
|
|
|
+ $('countdown').style.display = 'block';
|
|
|
+ countdown();
|
|
|
+ } else {
|
|
|
+ alert('Пароль задан неправильно');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ } else if (pass.length === 0){
|
|
|
+ alert('Введите пароль');
|
|
|
+ }else {
|
|
|
+ alert('Пароль задан неправильно');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function countdown(rel) {
|
|
|
+ var countDown = 5;
|
|
|
+ setInterval(function () {
|
|
|
+ if (countDown == 1 && rel === true) {
|
|
|
+ location.reload(true);
|
|
|
+ }
|
|
|
+ else if (countDown == 1 && rel !== true){
|
|
|
+ window.location.href = '/';
|
|
|
+ }
|
|
|
+ if (countDown > 0){countDown--;}
|
|
|
+ $('count-number').innerHTML = countDown;
|
|
|
+ return countDown;
|
|
|
+ }, 1000);
|
|
|
+}
|
|
|
+
|
|
|
+function dhcpState() {
|
|
|
+ if ($('dhcp').checked) {
|
|
|
+ $('ipaddr').setAttribute('disabled', 'disabled');
|
|
|
+ $('gw').setAttribute('disabled', 'disabled');
|
|
|
+ $('mask').setAttribute('disabled', 'disabled');
|
|
|
+ } else {
|
|
|
+ $('ipaddr').removeAttribute('disabled');
|
|
|
+ $('gw').removeAttribute('disabled');
|
|
|
+ $('mask').removeAttribute('disabled');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//########## Info Form Validation ############
|
|
|
+
|
|
|
+function infoValidation(){
|
|
|
+ var owner = $('owner').value,
|
|
|
+ location = $('location').value,
|
|
|
+ comment = $('comment').value;
|
|
|
+ var flag = true;
|
|
|
+ if(!ValidateAlphanumeric2(owner, 'Владелец')){flag = false;}
|
|
|
+ if(!ValidateAlphanumeric2(location, 'Местоположение')){flag = false;}
|
|
|
+ if(!ValidateAlphanumeric2(comment, 'Комментарии')){flag = false;}
|
|
|
+
|
|
|
+ return flag;
|
|
|
+}
|
|
|
+
|
|
|
+function ValidateAlphanumeric2(uadd, z) {
|
|
|
+ var warn = document.createElement('li');
|
|
|
+ // var letter = /^[0-9a-zA-Z]+[^\u0430-\u044f\u0410-\u042f\u0451\u0401\?]+$/m;
|
|
|
+ var letter = /^[0-9a-zA-Z\ ]+$/m;
|
|
|
+ warn.innerHTML = 'Поле ' + z + ' может содержать только латинские буквы и цифры';
|
|
|
+ if (letter.test(uadd) || !uadd) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ $('validation-box').appendChild(warn);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+function submitInfo() {
|
|
|
+ if (confirm("Вы уверены что хотите применить изменения?")) {
|
|
|
+ if (infoValidation()) {
|
|
|
+ $('SNMPinfo').submit();
|
|
|
+ // loadXMLDoc('info.cgi?owner='+ $('owner').value + '&sysLocation='+ $('location').value + '&comment='+ decodeURIComponent($('comment').value), 'GET', function(){
|
|
|
+ // console.log('Сохранено');
|
|
|
+ // });
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $('validation-box').style.display = 'block';
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function getJSON(url, successHandler, errorHandler) {
|
|
|
+ var xhr;
|
|
|
+ xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
|
|
|
+ xhr.open('GET', url, true);
|
|
|
+ xhr.onreadystatechange = function () {
|
|
|
+ var status;
|
|
|
+ var data;
|
|
|
+ if (xhr.readyState == 4) {
|
|
|
+ status = xhr.status;
|
|
|
+ if (status == 200) {
|
|
|
+ data = JSON.parse(xhr.responseText);
|
|
|
+ successHandler(data);
|
|
|
+ } else {
|
|
|
+ errorHandler(status);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ xhr.send();
|
|
|
+}
|
|
|
+
|
|
|
+function getCGI(url) {
|
|
|
+ var xmlhttp;
|
|
|
+ var q, a;
|
|
|
+ if (url == 'reset.cgi') {
|
|
|
+ q = confirm("Вы уверены что хотите сбросить на заводские настройки?");
|
|
|
+ // a = "Сброс отменен.";
|
|
|
+ }
|
|
|
+ if (url == 'reboot.cgi') {
|
|
|
+ q = confirm("Вы уверены что хотите перезагрузить устройство?");
|
|
|
+ // a = "Перезагрузка отменена.";
|
|
|
+ }
|
|
|
+ if (url == 'update.cgi') {
|
|
|
+ q = confirm("Вы уверены что хотите обновить прошивку устройства?");
|
|
|
+ // a = "Обновление отменено.";
|
|
|
+ }
|
|
|
+ if (q) {
|
|
|
+ if (window.XMLHttpRequest) {
|
|
|
+ xmlhttp = new XMLHttpRequest();
|
|
|
+ } else {
|
|
|
+ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
|
|
+ }
|
|
|
+ // xmlhttp.onreadystatechange = true;
|
|
|
+ xmlhttp.open("GET", url, true);
|
|
|
+ xmlhttp.send();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // else {alert(a);}
|
|
|
+}
|
|
|
+
|
|
|
+function paramsRefresh() {
|
|
|
+ getJSON('getJson.cgi'+'?'+Math.random(), function (data) {
|
|
|
+ panelState(!data.line_fail, $('sPower'));
|
|
|
+ panelState(!data.low_battery, $('sBattery'));
|
|
|
+ // PPS
|
|
|
+ $('AC').innerHTML = parseFloat(data.AC) + ' В';
|
|
|
+ $('AC').style.color = data.line_fail ? ALARM_RED : '#222';
|
|
|
+ $('DC').innerHTML = parseFloat(data.DC) + ' В';
|
|
|
+ $('DC').style.color = data.line_fail ? ALARM_RED : '#222';
|
|
|
+ $('in_freq').innerHTML = parseFloat(data.in_freq) + ' Гц';
|
|
|
+ $('in_freq').style.color = data.line_fail ? ALARM_RED : '#222';
|
|
|
+ $('out_freq').innerHTML = parseFloat(data.out_freq) + ' Гц';
|
|
|
+ $('out_freq').style.color = data.line_fail ? ALARM_RED : '#222';
|
|
|
+ $('pwr').innerHTML = parseFloat(data.pwr) + ' %';
|
|
|
+ $('pwr').style.color = data.load_monitor ? ALARM_RED : '#222';
|
|
|
+ // ACB
|
|
|
+ $('bat_cap').innerHTML = parseFloat(data.bat_cap) + ' %';
|
|
|
+ $('bat_cap').style.color = data.low_battery ? ALARM_RED : '#222';
|
|
|
+ $('inner_temp').innerHTML = parseFloat(data.inner_temp) + ' °C';
|
|
|
+ $('inner_temp').style.color = data.temp_monitor ? ALARM_RED : '#222';
|
|
|
+ $('bat_time_left').innerHTML = parseFloat(data.bat_time_left) + ' мин';
|
|
|
+ $('bat_time_left').style.color = data.low_battery ? ALARM_RED : '#222';
|
|
|
+ // State
|
|
|
+ $('alarm').innerHTML = data.alarm;
|
|
|
+ // General
|
|
|
+ utcParam = data.utc;
|
|
|
+ netsettings_changed = data.netsettings_changed;
|
|
|
+ connect_monitor = data.connect_monitor;
|
|
|
+ checkState();
|
|
|
+ setTimeout(paramsRefresh, 1000);
|
|
|
+ }, function (status) {
|
|
|
+ if (status !== 0){
|
|
|
+ alert('Не удалось получить данные.');
|
|
|
+ setTimeout(paramsRefresh, 15000);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function msieversion() {
|
|
|
+ var ua = window.navigator.userAgent;
|
|
|
+ var msie = ua.indexOf("MSIE ");
|
|
|
+ if (msie != -1 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) /*If IE, return version number*/ return true;
|
|
|
+ else return false;
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// ################################################################################
|
|
|
+
|
|
|
+function settingsGET(){
|
|
|
+ getJSON('settings.cgi', function(data) {
|
|
|
+ //SNMP params
|
|
|
+ $('managerIP').value = data.managerIP;
|
|
|
+ $('read_community').value = data.read_community;
|
|
|
+ $('write_community').value = data.write_community;
|
|
|
+ $('managerIP2').value = data.managerIP2;
|
|
|
+ $('managerIP3').value = data.managerIP3;
|
|
|
+ // Network params
|
|
|
+ $('ipaddr').value = data.ipaddr;
|
|
|
+ $('gw').value = data.gw;
|
|
|
+ $('mask').value = data.mask;
|
|
|
+ $('dhcp').checked = data.dhcp;
|
|
|
+ dhcpState();
|
|
|
+ netsettings_changed = data.netsettings_changed;
|
|
|
+ // profilaction_changed = data.NeedProfilaction;
|
|
|
+ }, function(status) {
|
|
|
+ alert('Не удалось получить данные.');
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+// ################################################################################
|
|
|
+
|
|
|
+/*
|
|
|
+
|
|
|
+SpinBox.js
|
|
|
+
|
|
|
+Implements a spin box interface for a text field
|
|
|
+
|
|
|
+Created by Stephen Morley - http://code.stephenmorley.org/ - and released under
|
|
|
+the terms of the CC0 1.0 Universal legal code:
|
|
|
+
|
|
|
+http://creativecommons.org/publicdomain/zero/1.0/legalcode
|
|
|
+
|
|
|
+*/
|
|
|
+
|
|
|
+/* Creates a spin box. The parameter is:
|
|
|
+ *
|
|
|
+ * container - either the DOM node to contain the spin box or the ID of the node
|
|
|
+ * options - an object containing various parameters; this optional parameter
|
|
|
+ * defaults to the empty object
|
|
|
+ *
|
|
|
+ * The options object may contain the following keys:
|
|
|
+ *
|
|
|
+ * className - a class name to apply to the container; the class name with the
|
|
|
+ * suffixes 'Up' and 'Down' will be applied to the up and down
|
|
|
+ * buttons. The default value is 'spinBox'.
|
|
|
+ * value - the initial value for the spin box. The default is 0 (subject to
|
|
|
+ * restrictions on the minimum and maximum value) if the input
|
|
|
+ * element did not already exist, or the existing value if the input
|
|
|
+ * element did already exist.
|
|
|
+ * step - the value by which to increment or decrement the value. The
|
|
|
+ * default value is 1.
|
|
|
+ * minimum - the minimum allowed value. The default is not to have a minimum
|
|
|
+ * value.
|
|
|
+ * maximum - the maximum allowed value. The default is not to have a maximum
|
|
|
+ * value.
|
|
|
+ * decimals - the number of decimal places allowed. The default is 0.
|
|
|
+ * name - input name attribute.
|
|
|
+ *
|
|
|
+ * Note that the minimum, maximum, and decimal places restrictions are enforced
|
|
|
+ * for values set by the spin box, but a value outside of these restrictions may
|
|
|
+ * be typed by the user.
|
|
|
+ */
|
|
|
+function SpinBox(container, options) {
|
|
|
+
|
|
|
+ // fetch the DOM node if a string was supplied
|
|
|
+ if (typeof container == 'string') {
|
|
|
+ container = document.getElementById(container);
|
|
|
+ }
|
|
|
+
|
|
|
+ // store the options and set the default values
|
|
|
+ this.options = (options ? options : {});
|
|
|
+ if (!('className' in this.options)) this.options.className = 'spinBox';
|
|
|
+ if (!('step' in this.options)) this.options.step = 1;
|
|
|
+ if (!('decimals' in this.options)) this.options.decimals = 0;
|
|
|
+
|
|
|
+ // check whether the input field should be created
|
|
|
+ var inputs = container.getElementsByTagName('input');
|
|
|
+ if (inputs.length === 0) {
|
|
|
+
|
|
|
+ // create the input node
|
|
|
+ this.input = document.createElement('input');
|
|
|
+ this.setValue('value' in this.options ? this.options.value : 0);
|
|
|
+ this.setName('name' in this.options ? this.options.name : '');
|
|
|
+ container.appendChild(this.input);
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // store a reference to the input node
|
|
|
+ this.input = inputs[0];
|
|
|
+ this.setValue(this.options.value ? this.options.value : this.input.value);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // create the up button
|
|
|
+ var upButton = document.createElement('span');
|
|
|
+ upButton.appendChild(document.createElement('span'));
|
|
|
+ upButton.innerHTML = '+';
|
|
|
+ container.appendChild(upButton);
|
|
|
+
|
|
|
+ // create the down button
|
|
|
+ var downButton = document.createElement('span');
|
|
|
+ downButton.appendChild(document.createElement('span'));
|
|
|
+ downButton.innerHTML = '-';
|
|
|
+ container.appendChild(downButton);
|
|
|
+
|
|
|
+ // apply the classes
|
|
|
+ container.className += ' ' + this.options.className;
|
|
|
+ upButton.className = this.options.className + 'Up';
|
|
|
+ downButton.className = this.options.className + 'Down';
|
|
|
+
|
|
|
+ // add the listeners
|
|
|
+ this.addEventListener(this.input, 'mousewheel', this.handleMouseWheel, [], true);
|
|
|
+ this.addEventListener(this.input, 'DOMMouseScroll', this.handleMouseWheel, [], true);
|
|
|
+ this.addEventListener(this.input, 'keydown', this.handleKeyDown, [], true);
|
|
|
+ this.addEventListener(this.input, 'keypress', this.handleKeyPress, [], true);
|
|
|
+ this.addEventListener(this.input, 'keyup', this.stop);
|
|
|
+ this.addEventListener(upButton, 'mousedown', this.start, [true]);
|
|
|
+ this.addEventListener(upButton, 'mouseup', this.stop);
|
|
|
+ this.addEventListener(upButton, 'mouseout', this.stop);
|
|
|
+ this.addEventListener(downButton, 'mousedown', this.start, [false]);
|
|
|
+ this.addEventListener(downButton, 'mouseup', this.stop);
|
|
|
+ this.addEventListener(downButton, 'mouseout', this.stop);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/* Returns the current value. This will be a number, or the value NaN if the
|
|
|
+ * current contents of the input field do not start with a valid number.
|
|
|
+ */
|
|
|
+SpinBox.prototype.getValue = function () {
|
|
|
+
|
|
|
+ // parse and return the value
|
|
|
+ return parseFloat(this.input.value);
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+SpinBox.prototype.setName = function (name) {
|
|
|
+
|
|
|
+ // asign input name
|
|
|
+ this.input.name = name;
|
|
|
+};
|
|
|
+/* Sets the value. Restrictions on the minimum and maximum value are enforced.
|
|
|
+ * The parameter is:
|
|
|
+ *
|
|
|
+ * value - the value
|
|
|
+ */
|
|
|
+SpinBox.prototype.setValue = function (value) {
|
|
|
+
|
|
|
+ // ensure the value is within the permitted range
|
|
|
+ if ('minimum' in this.options) value = Math.max(this.options.minimum, value);
|
|
|
+ if ('maximum' in this.options) value = Math.min(this.options.maximum, value);
|
|
|
+
|
|
|
+ // store the sign
|
|
|
+ var sign = (value < 0 ? '-' : '');
|
|
|
+ value = Math.abs(value);
|
|
|
+
|
|
|
+ // determine the multiplier for rounding
|
|
|
+ var multiplier = Math.pow(10, this.options.decimals);
|
|
|
+
|
|
|
+ // split the value in to integer and fractional parts
|
|
|
+ value = Math.round(value * multiplier);
|
|
|
+ var integer = (value - value % multiplier) / multiplier;
|
|
|
+ var fractional = '' + value % multiplier;
|
|
|
+
|
|
|
+ // add leading zeros to the fractional part
|
|
|
+ while (fractional.length < this.options.decimals) {
|
|
|
+ fractional = '0' + fractional;
|
|
|
+ }
|
|
|
+
|
|
|
+ // set the value
|
|
|
+ this.input.value =
|
|
|
+ sign + integer + (this.options.decimals > 0 ? '.' + fractional : '');
|
|
|
+
|
|
|
+ // check whether the browser can dispatch events
|
|
|
+ if ('dispatchEvent' in this.input){
|
|
|
+
|
|
|
+ // create the event
|
|
|
+ try{
|
|
|
+ var event = new Event('change', {bubbles : true, cancelable : true});
|
|
|
+ }catch (e){
|
|
|
+ var event = document.createEvent('Event');
|
|
|
+ event.initEvent('change', true, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ // dispatch the event
|
|
|
+ this.input.dispatchEvent(event);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+/* Adds an event listener to a node. The event listener is bound to the current
|
|
|
+ * value of 'this'. The parameters are:
|
|
|
+ *
|
|
|
+ * node - the node
|
|
|
+ * event - the event name
|
|
|
+ * listener - the listener functions
|
|
|
+ * parameters - an array of additional parameters to pass to the listener;
|
|
|
+ * these are placed after the event parameter
|
|
|
+ * allowDefault - true if the default action should not be prevented
|
|
|
+ */
|
|
|
+SpinBox.prototype.addEventListener = function (
|
|
|
+node, event, listener, parameters, allowDefault) {
|
|
|
+
|
|
|
+ // store a reference to the 'this' object
|
|
|
+ var thisObject = this;
|
|
|
+
|
|
|
+ // create the bound listener
|
|
|
+ function boundListener(e) {
|
|
|
+
|
|
|
+ // get the event if it is not supplied
|
|
|
+ if (!e) e = window.event;
|
|
|
+
|
|
|
+ // call the listener
|
|
|
+ listener.apply(thisObject, [e].concat(parameters));
|
|
|
+
|
|
|
+ // prevent the default action if necessary
|
|
|
+ if (!allowDefault) {
|
|
|
+ if (e.preventDefault) {
|
|
|
+ e.preventDefault();
|
|
|
+ } else {
|
|
|
+ e.returnValue = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // add the event listener
|
|
|
+ if (node.addEventListener) {
|
|
|
+ node.addEventListener(event, boundListener, false);
|
|
|
+ } else {
|
|
|
+ node.attachEvent('on' + event, boundListener);
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+/* Handles a mouse wheel event by updating the value if the field is active. The
|
|
|
+ * parameter is:
|
|
|
+ *
|
|
|
+ * e - the event object
|
|
|
+ */
|
|
|
+SpinBox.prototype.handleMouseWheel = function (e) {
|
|
|
+
|
|
|
+ // check whether the field is active
|
|
|
+ if (document.activeElement == this.input) {
|
|
|
+
|
|
|
+ // update the value
|
|
|
+ if (e.wheelDelta) {
|
|
|
+ this.start(e, e.wheelDelta > 1);
|
|
|
+ } else if (e.detail) {
|
|
|
+ this.start(e, e.detail < 1);
|
|
|
+ }
|
|
|
+ this.stop();
|
|
|
+
|
|
|
+ // prevent the default action
|
|
|
+ if (e.preventDefault) {
|
|
|
+ e.preventDefault();
|
|
|
+ } else {
|
|
|
+ e.returnValue = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+/* Handles a key down event by starting updating if appropriate. The parameter
|
|
|
+ * is:
|
|
|
+ *
|
|
|
+ * e - the event object
|
|
|
+ */
|
|
|
+SpinBox.prototype.handleKeyDown = function (e) {
|
|
|
+
|
|
|
+ // if the up or down keys were pressed, start updating
|
|
|
+ if (e.keyCode == 38) this.start(e, true);
|
|
|
+ if (e.keyCode == 40) this.start(e, false);
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+/* Handles a key press event by filtering out invalid characters. The parameter
|
|
|
+ * is:
|
|
|
+ *
|
|
|
+ * e - the event object
|
|
|
+ */
|
|
|
+SpinBox.prototype.handleKeyPress = function (e) {
|
|
|
+
|
|
|
+ // determine the character code
|
|
|
+ var charCode = ('charCode' in e ? e.charCode : e.keyCode);
|
|
|
+
|
|
|
+ // allow special key presses
|
|
|
+ if (charCode === 0 || e.altKey || e.ctrlKey || e.metaKey) return;
|
|
|
+
|
|
|
+ // allow a minus sign if the value can be negative
|
|
|
+ if (charCode == 45 && (!('minimum' in this.options) || this.options.minimum < 0)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // allow a decimal point if the value may contain decimals
|
|
|
+ if (charCode == 46 && this.options.decimals > 0) return;
|
|
|
+
|
|
|
+ // allow digits
|
|
|
+ if (charCode >= 48 && charCode <= 57) return;
|
|
|
+
|
|
|
+ // prevent the default action
|
|
|
+ if (e.preventDefault) {
|
|
|
+ e.preventDefault();
|
|
|
+ } else {
|
|
|
+ e.returnValue = false;
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+/* Starts updating the value. The parameters are:
|
|
|
+ *
|
|
|
+ * e - the event object
|
|
|
+ * up - true to increment the value, false to decrement the value
|
|
|
+ */
|
|
|
+SpinBox.prototype.start = function (e, up) {
|
|
|
+
|
|
|
+ // if the field is disabled or we are already updating, return immediately
|
|
|
+ if (this.input.disabled || 'timeout' in this) return;
|
|
|
+
|
|
|
+ // set the update step
|
|
|
+ this.updateStep = (up ? this.options.step : -this.options.step);
|
|
|
+
|
|
|
+ // initialise the timeout delay
|
|
|
+ this.timeoutDelay = 500;
|
|
|
+
|
|
|
+ // update the value
|
|
|
+ this.update();
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+// Stops update the value.
|
|
|
+SpinBox.prototype.stop = function () {
|
|
|
+
|
|
|
+ // clear the timeout if it exists
|
|
|
+ if ('timeout' in this) {
|
|
|
+ window.clearTimeout(this.timeout);
|
|
|
+ delete this.timeout;
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+// Updates the value.
|
|
|
+SpinBox.prototype.update = function () {
|
|
|
+
|
|
|
+ // determine the current value
|
|
|
+ var value = parseFloat(this.input.value);
|
|
|
+ if (isNaN(value)) value = 0;
|
|
|
+
|
|
|
+ // update the value
|
|
|
+ this.setValue(value + this.updateStep);
|
|
|
+
|
|
|
+ // reduce the delay
|
|
|
+ this.timeoutDelay = Math.max(20, Math.floor(this.timeoutDelay * 0.9));
|
|
|
+
|
|
|
+ // call this function again
|
|
|
+ var thisObject = this;
|
|
|
+ this.timeout = window.setTimeout(function () { thisObject.update(); }, this.timeoutDelay);
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ This code is from Dynamic Web Coding at dyn-web.com
|
|
|
+ Copyright 2009-12 by Sharon Paine
|
|
|
+ See Terms of Use at www.dyn-web.com/business/terms.php
|
|
|
+ regarding conditions under which you may use this code.
|
|
|
+ This notice must be retained in the code as is!
|
|
|
+*/
|
|
|
+
|
|
|
+// DYN_WEB is namespace used for code from dyn-web.com
|
|
|
+// replacing previous use of dw_ prefix for object names
|
|
|
+var DYN_WEB = DYN_WEB || {};
|
|
|
+
|
|
|
+DYN_WEB.Event = {
|
|
|
+ add: document.addEventListener ? function (obj, etype, fp, cap) {
|
|
|
+ cap = cap || false;
|
|
|
+ obj.addEventListener(etype, fp, cap);
|
|
|
+ } : function (obj, etype, fp) {
|
|
|
+ obj.attachEvent("on" + etype, fp);
|
|
|
+ },
|
|
|
+ remove: document.removeEventListener ? function (obj, etype, fp, cap) {
|
|
|
+ cap = cap || false;
|
|
|
+ obj.removeEventListener(etype, fp, cap);
|
|
|
+ } : function (obj, etype, fp) {
|
|
|
+ obj.detachEvent("on" + etype, fp);
|
|
|
+ },
|
|
|
+ DOMit: function (e) {
|
|
|
+ e = e ? e : window.event;
|
|
|
+ if (!e.target) e.target = e.srcElement;
|
|
|
+ if (!e.preventDefault) e.preventDefault = function () {
|
|
|
+ e.returnValue = false;
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+ if (!e.stopPropagation) e.stopPropagation = function () {
|
|
|
+ e.cancelBubble = true;
|
|
|
+ };
|
|
|
+ return e;
|
|
|
+ },
|
|
|
+ getTarget: function (e) {
|
|
|
+ e = dw_Event.DOMit(e);
|
|
|
+ var tgt = e.target;
|
|
|
+ if (tgt.nodeType != 1) tgt = tgt.parentNode;
|
|
|
+ return tgt;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+DYN_WEB.Cookie = {
|
|
|
+ set: function (name, value, days, path, domain, secure) {
|
|
|
+ var date, expires;
|
|
|
+ if (typeof days == "number") {
|
|
|
+ date = new Date();
|
|
|
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
|
+ expires = date.toGMTString();
|
|
|
+ }
|
|
|
+ document.cookie = name + "=" + encodeURIComponent(value) + ((expires) ? "; expires=" + expires : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
|
|
|
+ },
|
|
|
+ get: function (name) {
|
|
|
+ var c, cookies = document.cookie.split(/;\s/g);
|
|
|
+ for (var i = 0; cookies[i]; i++) {
|
|
|
+ c = cookies[i];
|
|
|
+ if (c.indexOf(name + '=') === 0) {
|
|
|
+ return decodeURIComponent(c.slice(name.length + 1, c.length));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+ del: function (name, path, domain) {
|
|
|
+ if (dw_Cookie.get(name)) {
|
|
|
+ document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+if (!DYN_WEB.Util) {
|
|
|
+ DYN_WEB.Util = {
|
|
|
+ // add props of Obj2 to Obj1
|
|
|
+ augment: function (Obj1, Obj2) {
|
|
|
+ var prop;
|
|
|
+ for (prop in Obj2) {
|
|
|
+ if (Obj2.hasOwnProperty(prop) && !Obj1[prop]) {
|
|
|
+ Obj1[prop] = Obj2[prop];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ $: function (id) {
|
|
|
+ return document.getElementById(id);
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+DYN_WEB.Tabs = (function () {
|
|
|
+
|
|
|
+ // obj holds props: id, useCookies, etc.
|
|
|
+ function Constr(obj) {
|
|
|
+ this.useCookies = obj.useCookies;
|
|
|
+ this.before_hide = obj.before_hide || function () {};
|
|
|
+ this.on_activate = obj.on_activate || function () {};
|
|
|
+ this.on_init = obj.on_init || function () {};
|
|
|
+ Constr.col[obj.id] = this;
|
|
|
+ Constr.init(obj.id);
|
|
|
+ }
|
|
|
+
|
|
|
+ Constr.col = {};
|
|
|
+
|
|
|
+ Constr.prototype = {
|
|
|
+ current: null // id of currently active pane
|
|
|
+ };
|
|
|
+
|
|
|
+ return Constr;
|
|
|
+})();
|
|
|
+
|
|
|
+(function () {
|
|
|
+ var Ut = DYN_WEB.Util,
|
|
|
+ Ev = DYN_WEB.Event,
|
|
|
+ Cookie = DYN_WEB.Cookie,
|
|
|
+ Tabs = DYN_WEB.Tabs;
|
|
|
+
|
|
|
+ Ut.augment(Tabs, {
|
|
|
+ // static props/methods for DYN_WEB.Tabs
|
|
|
+ setup: function () {
|
|
|
+ var obj, settings = [];
|
|
|
+ if (Tabs.hasBrowserSupport()) {
|
|
|
+ for (var i = 0; obj = arguments[i]; i++) {
|
|
|
+ if (obj.css) {
|
|
|
+ Ut.writeStyleSheet(obj.css);
|
|
|
+ }
|
|
|
+ settings[i] = obj; // save to pass to constructor onload
|
|
|
+ }
|
|
|
+ Ev.add(window, 'load', function () {
|
|
|
+ for (var i = 0; settings[i]; i++) {
|
|
|
+ new Tabs(settings[i]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ hasBrowserSupport: function () {
|
|
|
+ if (document.getElementById && document.getElementsByTagName && typeof decodeURI !== 'undefined' && (document.addEventListener || document.attachEvent)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+
|
|
|
+ init: function (tabsetId) {
|
|
|
+ var _this = Tabs.col[tabsetId],
|
|
|
+ links = Tabs.getTabs(tabsetId),
|
|
|
+ // code uses hash in tab links but tabs can also link to other pages
|
|
|
+ // so compare current location to link's href
|
|
|
+ loc = Ut.getURLtoHash(location),
|
|
|
+ lnk, pg, paneId, pane, sel, dflt, cur, c, q, hash;
|
|
|
+
|
|
|
+ q = Ut.getValueFromQueryString(tabsetId);
|
|
|
+ if (_this.useCookies) {
|
|
|
+ c = Tabs.checkCookie(tabsetId);
|
|
|
+ }
|
|
|
+ // tab in query string or cookie?
|
|
|
+ sel = q ? q : c ? c : null;
|
|
|
+
|
|
|
+ // add ids and event handlers to links ...
|
|
|
+ for (var i = 0; lnk = links[i]; i++) {
|
|
|
+ paneId = '', pane = ''; // reset
|
|
|
+ pg = Ut.getURLtoHash(lnk);
|
|
|
+ hash = Ut.getHash(lnk);
|
|
|
+ if (lnk.hash && (loc == pg)) { // has hash and points to current page
|
|
|
+ paneId = hash;
|
|
|
+ lnk.id = tabsetId + '__' + paneId; // double underscore between
|
|
|
+ }
|
|
|
+ // if tab associated with tabpane, set up onclick fn
|
|
|
+ if (paneId) {
|
|
|
+ try {
|
|
|
+ pane = Ut.$(paneId);
|
|
|
+ } catch (err) { // showClicked fn throws
|
|
|
+ }
|
|
|
+
|
|
|
+ // first tab/pane is default
|
|
|
+ if (!dflt) {
|
|
|
+ dflt = paneId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // if set active in markup, hold as current
|
|
|
+ if (pane && Ut.hasClass(lnk, 'activeTab') && Ut.hasClass(pane, 'activePane')) {
|
|
|
+ _this.current = cur = paneId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // to pass paneId, tabsetId to showClicked...
|
|
|
+ Ev.add(lnk, 'click', function (paneId, tabsetId) {
|
|
|
+ return function (e) {
|
|
|
+ Tabs.showClicked(e, paneId, tabsetId);
|
|
|
+ };
|
|
|
+ }(paneId, tabsetId));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // check if tab and pane for sel
|
|
|
+ if (sel && (lnk = Ut.$(tabsetId + '__' + sel)) && (pane = Ut.$(sel))) {
|
|
|
+ if (cur && cur !== sel) {
|
|
|
+ Tabs.hideCurrent(tabsetId, cur);
|
|
|
+ }
|
|
|
+ Ut.addClass(lnk, 'activeTab');
|
|
|
+ Ut.addClass(pane, 'activePane');
|
|
|
+ _this.current = sel;
|
|
|
+ } else if (!cur && dflt) {
|
|
|
+ Ut.addClass(Ut.$(tabsetId + '__' + dflt), 'activeTab');
|
|
|
+ Ut.addClass(Ut.$(dflt), 'activePane');
|
|
|
+ _this.current = dflt;
|
|
|
+ }
|
|
|
+ _this.on_init();
|
|
|
+ },
|
|
|
+
|
|
|
+ getTabs: function (id) {
|
|
|
+ var set = Ut.$(id),
|
|
|
+ list, links;
|
|
|
+ if (!set) {
|
|
|
+ throw new Error('No element matching tabset id found.');
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ list = Ut.getElementsByClassName('tabnavs', 'ul', set);
|
|
|
+ if (list.length === 0) {
|
|
|
+ throw new Error('No tabnavs were found in the tabset.');
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ links = list[0].getElementsByTagName('a');
|
|
|
+ return links;
|
|
|
+ },
|
|
|
+
|
|
|
+ showClicked: function (e, paneId, tabsetId) {
|
|
|
+ var tabId = tabsetId + '__' + paneId;
|
|
|
+ var _this = Tabs.col[tabsetId];
|
|
|
+ _this.before_hide(tabId, paneId, tabsetId);
|
|
|
+ Tabs.hideCurrent(tabsetId, _this.current);
|
|
|
+ Ut.addClass(Ut.$(tabId), 'activeTab');
|
|
|
+
|
|
|
+ try {
|
|
|
+ Ut.addClass(Ut.$(paneId), 'activePane');
|
|
|
+ } catch (err) {
|
|
|
+ throw new Error('showClicked can\'t find pane associated with tab. Check tab hash and pane id.');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ _this.current = paneId;
|
|
|
+ if (_this.useCookies) {
|
|
|
+ Tabs.setCookie(tabsetId, paneId);
|
|
|
+ }
|
|
|
+
|
|
|
+ _this.on_activate(tabId, paneId, tabsetId);
|
|
|
+ if (e) {
|
|
|
+ Ev.DOMit(e);
|
|
|
+ e.preventDefault();
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+
|
|
|
+ hideCurrent: function (tabsetId, cur) {
|
|
|
+ var tab = Ut.$(tabsetId + '__' + cur),
|
|
|
+ pane = Ut.$(cur);
|
|
|
+ Ut.removeClass(tab, 'activeTab');
|
|
|
+ Ut.removeClass(pane, 'activePane');
|
|
|
+ },
|
|
|
+
|
|
|
+ checkCookie: function (tabsetId) {
|
|
|
+ var c, cookies, tab_cookies = Cookie.get('dw_Tabs');
|
|
|
+ if (tab_cookies) {
|
|
|
+ cookies = tab_cookies.split(',');
|
|
|
+ for (var i = 0; cookies[i]; i++) {
|
|
|
+ c = cookies[i];
|
|
|
+ if (c.indexOf(tabsetId + ':') === 0) {
|
|
|
+ return decodeURI(c.slice(tabsetId.length + 1, c.length));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+
|
|
|
+ setCookie: function (tabsetId, paneId) {
|
|
|
+ // format for cookies (multiple tabsets supported): dw_Tabs=tabsetId:paneId,tabsetId:paneId;
|
|
|
+ var new_tab_cookies = '',
|
|
|
+ cookies,
|
|
|
+ tab_cookies = Cookie.get('dw_Tabs');
|
|
|
+ if (tab_cookies) {
|
|
|
+ cookies = tab_cookies.split(',');
|
|
|
+ for (var i = 0; cookies[i]; i++) {
|
|
|
+ if (cookies[i].indexOf(tabsetId + ':') === 0) {
|
|
|
+ cookies[i] = tabsetId + ':' + paneId;
|
|
|
+ new_tab_cookies = cookies.join(',');
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!new_tab_cookies) { // if no match for this tabsetId
|
|
|
+ new_tab_cookies = tab_cookies + ',' + tabsetId + ':' + paneId;
|
|
|
+ }
|
|
|
+ } else { // no dw_Tabs set yet
|
|
|
+ new_tab_cookies = tabsetId + ':' + paneId;
|
|
|
+ }
|
|
|
+ Cookie.set('dw_Tabs', new_tab_cookies, null, '/');
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+})();
|
|
|
+
|
|
|
+
|
|
|
+// util
|
|
|
+
|
|
|
+(function () {
|
|
|
+ var Ut = DYN_WEB.Util;
|
|
|
+ // add methods to DYN_WEB.Util
|
|
|
+ Ut.augment(Ut, {
|
|
|
+ trim: function (str) {
|
|
|
+ if (String.prototype.trim) {
|
|
|
+ return str.trim(); // ECMAScript 5
|
|
|
+ } else {
|
|
|
+ var re = /^\s+|\s+$/g;
|
|
|
+ return str.replace(re, '');
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ normalizeString: function (str) {
|
|
|
+ var re = /\s\s+/g;
|
|
|
+ return Ut.trim(str).replace(re, ' ');
|
|
|
+ },
|
|
|
+
|
|
|
+ hasClass: function (el, cl) {
|
|
|
+ var re = new RegExp('\\b' + cl + '\\b', 'i');
|
|
|
+ if (re.test(el.className)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+
|
|
|
+ addClass: function (el, cl) {
|
|
|
+ if (!Ut.hasClass(el, cl)) {
|
|
|
+ el.className = Ut.trim(el.className + ' ' + cl);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ removeClass: function (el, cl) {
|
|
|
+ el.className = Ut.normalizeString(el.className.replace(cl, " "));
|
|
|
+ },
|
|
|
+
|
|
|
+ getElementsByClassName: function (sClass, sTag, oCont) {
|
|
|
+ oCont = oCont ? oCont : document;
|
|
|
+ if (oCont.getElementsByClassName) {
|
|
|
+ return oCont.getElementsByClassName(sClass); // html5
|
|
|
+ } else {
|
|
|
+ sTag = sTag || '*';
|
|
|
+ var result = [],
|
|
|
+ re = new RegExp('\\b' + sClass + '\\b', 'i'),
|
|
|
+ list = oCont.getElementsByTagName(sTag);
|
|
|
+ for (var i = 0; list[i]; i++) {
|
|
|
+ if (re.test(list[i].className)) result.push(list[i]);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // obj: link or window.location
|
|
|
+ getValueFromQueryString: function (name, obj) {
|
|
|
+ obj = obj ? obj : window.location;
|
|
|
+ var pairs, set;
|
|
|
+ if (obj.search && obj.search.indexOf(name != -1)) {
|
|
|
+ pairs = obj.search.slice(1).split('&'); // name/value pairs
|
|
|
+ for (var i = 0; pairs[i]; i++) {
|
|
|
+ set = pairs[i].split('='); // Check each pair for match on name
|
|
|
+ if (set[0] == name && set[1]) {
|
|
|
+ return set[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+
|
|
|
+ getURLtoHash: function (obj) {
|
|
|
+ obj = obj ? obj : window.location;
|
|
|
+ var href = obj.href,
|
|
|
+ pt = href.indexOf('#'),
|
|
|
+ url = (pt != -1) ? href.slice(0, pt) : href; // remove hash from href
|
|
|
+ return url;
|
|
|
+ },
|
|
|
+
|
|
|
+ getHash: function (obj) {
|
|
|
+ obj = obj ? obj : window.location;
|
|
|
+ var hash = '';
|
|
|
+ if (obj.hash) { // some browsers say true if just #, some '' (ff)
|
|
|
+ hash = obj.hash.slice(1);
|
|
|
+ }
|
|
|
+ return hash;
|
|
|
+ },
|
|
|
+
|
|
|
+ // Alternate functions are available that use DOM methods instead of document.write
|
|
|
+ writeStyleSheet: function (file, bScreen) {
|
|
|
+ var screen = (bScreen !== false) ? '" media="screen" />\n' : '"/>\n';
|
|
|
+ document.write('\n<link rel="stylesheet" href="' + file + screen);
|
|
|
+ },
|
|
|
+
|
|
|
+ // used to set min-height (as on dyn-web home page)
|
|
|
+ writeStyleRule: function (rule, bScreen) {
|
|
|
+ var screen = (bScreen !== false) ? ' media="screen">' : '>';
|
|
|
+ document.write('\n<style type="text/css"' + screen + rule + '</style>');
|
|
|
+ }
|
|
|
+ });
|
|
|
+})();
|
|
|
+
|
|
|
+
|
|
|
+(function (window) {
|
|
|
+
|
|
|
+/**
|
|
|
+ * @param {String} type - request | cancel | native.
|
|
|
+ * @return {Function} Timing function.
|
|
|
+ */
|
|
|
+function requestFrame(type) {
|
|
|
+ // The only vendor prefixes required.
|
|
|
+ var vendors = ['moz', 'webkit'],
|
|
|
+
|
|
|
+ // Disassembled timing function abbreviations.
|
|
|
+ aF = 'AnimationFrame',
|
|
|
+ rqAF = 'Request' + aF,
|
|
|
+
|
|
|
+ // Final assigned functions.
|
|
|
+ assignedRequestAnimationFrame,
|
|
|
+ assignedCancelAnimationFrame,
|
|
|
+
|
|
|
+ // Initial time of the timing lapse.
|
|
|
+ previousTime = 0,
|
|
|
+
|
|
|
+ mozRAF = window.mozRequestAnimationFrame,
|
|
|
+ mozCAF = window.mozCancelAnimationFrame,
|
|
|
+
|
|
|
+ // Checks for firefox 4 - 10 function pair mismatch.
|
|
|
+ hasMozMismatch = mozRAF && !mozCAF,
|
|
|
+
|
|
|
+ func;
|
|
|
+
|
|
|
+ // Date.now polyfill, mainly for legacy IE versions.
|
|
|
+ if (!Date.now) {
|
|
|
+ Date.now = function() {
|
|
|
+ return new Date().getTime();
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * hasIOS6RequestAnimationFrameBug.
|
|
|
+ * @See {@Link https://gist.github.com/julienetie/86ac394ec41f1271ff0a}
|
|
|
+ * - for Commentary.
|
|
|
+ * @Copyright 2015 - Julien Etienne.
|
|
|
+ * @License: MIT.
|
|
|
+ */
|
|
|
+ function hasIOS6RequestAnimationFrameBug() {
|
|
|
+ var webkitRAF = window.webkitRequestAnimationFrame,
|
|
|
+ rAF = window.requestAnimationFrame,
|
|
|
+
|
|
|
+ // CSS/ Device with max for iOS6 Devices.
|
|
|
+ hasMobileDeviceWidth = screen.width <= 768 ? true : false,
|
|
|
+
|
|
|
+ // Only supports webkit prefixed requestAnimtionFrane.
|
|
|
+ requiresWebkitprefix = !(webkitRAF && rAF),
|
|
|
+
|
|
|
+ // iOS6 webkit browsers don't support performance now.
|
|
|
+ hasNoNavigationTiming = window.performance ? false : true,
|
|
|
+
|
|
|
+ iOS6Notice = 'setTimeout is being used as a substitiue for' +
|
|
|
+ 'requestAnimationFrame due to a bug within iOS 6 builds',
|
|
|
+
|
|
|
+ hasIOS6Bug = requiresWebkitprefix && hasMobileDeviceWidth &&
|
|
|
+ hasNoNavigationTiming;
|
|
|
+
|
|
|
+ function bugCheckresults(timingFnA, timingFnB, notice) {
|
|
|
+ if (timingFnA || timingFnB) {
|
|
|
+ console.warn(notice);
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function displayResults() {
|
|
|
+ if (hasIOS6Bug) {
|
|
|
+ return bugCheckresults(webkitRAF, rAF, iOS6Notice);
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return displayResults();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Native clearTimeout function.
|
|
|
+ * @return {Function}
|
|
|
+ */
|
|
|
+ function clearTimeoutWithId(id) {
|
|
|
+ clearTimeout(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Based on a polyfill by Erik, introduced by Paul Irish &
|
|
|
+ * further improved by Darius Bacon.
|
|
|
+ * @see {@link http://www.paulirish.com/2011/
|
|
|
+ * requestanimationframe-for-smart-animating}
|
|
|
+ * @see {@link https://github.com/darius/requestAnimationFrame/blob/
|
|
|
+ * master/requestAnimationFrame.js}
|
|
|
+ * @callback {Number} Timestamp.
|
|
|
+ * @return {Function} setTimeout Function.
|
|
|
+ */
|
|
|
+ function setTimeoutWithTimestamp(callback) {
|
|
|
+ var immediateTime = Date.now(),
|
|
|
+ lapsedTime = Math.max(previousTime + 16, immediateTime);
|
|
|
+ return setTimeout(function() {
|
|
|
+ callback(previousTime = lapsedTime);
|
|
|
+ },
|
|
|
+ lapsedTime - immediateTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Queries the native function, prefixed function
|
|
|
+ * or use the setTimeoutWithTimestamp function.
|
|
|
+ * @return {Function}
|
|
|
+ */
|
|
|
+ function queryRequestAnimationFrame() {
|
|
|
+ if (Array.prototype.filter) {
|
|
|
+ assignedRequestAnimationFrame = window['request' + aF] ||
|
|
|
+ window[vendors.filter(function(vendor) {
|
|
|
+ if (window[vendor + rqAF] !== undefined)
|
|
|
+ return vendor;
|
|
|
+ }) + rqAF] || setTimeoutWithTimestamp;
|
|
|
+ } else {
|
|
|
+ return setTimeoutWithTimestamp;
|
|
|
+ }
|
|
|
+ if (!hasIOS6RequestAnimationFrameBug()) {
|
|
|
+ return assignedRequestAnimationFrame;
|
|
|
+ } else {
|
|
|
+ return setTimeoutWithTimestamp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Queries the native function, prefixed function
|
|
|
+ * or use the clearTimeoutWithId function.
|
|
|
+ * @return {Function}
|
|
|
+ */
|
|
|
+ function queryCancelAnimationFrame() {
|
|
|
+ var cancellationNames = [];
|
|
|
+ if (Array.prototype.map) {
|
|
|
+ vendors.map(function(vendor) {
|
|
|
+ return ['Cancel', 'CancelRequest'].map(
|
|
|
+ function(cancellationNamePrefix) {
|
|
|
+ cancellationNames.push(vendor +
|
|
|
+ cancellationNamePrefix + aF);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ return clearTimeoutWithId;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Checks for the prefixed cancelAnimationFrame implementation.
|
|
|
+ * @param {Array} prefixedNames - An array of the prefixed names.
|
|
|
+ * @param {Number} i - Iteration start point.
|
|
|
+ * @return {Function} prefixed cancelAnimationFrame function.
|
|
|
+ */
|
|
|
+ function prefixedCancelAnimationFrame(prefixedNames, i) {
|
|
|
+ var cancellationFunction;
|
|
|
+ for (; i < prefixedNames.length; i++) {
|
|
|
+ if (window[prefixedNames[i]]) {
|
|
|
+ cancellationFunction = window[prefixedNames[i]];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return cancellationFunction;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Use truthly function
|
|
|
+ assignedCancelAnimationFrame = window['cancel' + aF] ||
|
|
|
+ prefixedCancelAnimationFrame(cancellationNames, 0) ||
|
|
|
+ clearTimeoutWithId;
|
|
|
+
|
|
|
+ // Check for iOS 6 bug
|
|
|
+ if (!hasIOS6RequestAnimationFrameBug()) {
|
|
|
+ return assignedCancelAnimationFrame;
|
|
|
+ } else {
|
|
|
+ return clearTimeoutWithId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function getRequestFn() {
|
|
|
+ if (hasMozMismatch) {
|
|
|
+ return setTimeoutWithTimestamp;
|
|
|
+ } else {
|
|
|
+ return queryRequestAnimationFrame();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function getCancelFn() {
|
|
|
+ return queryCancelAnimationFrame();
|
|
|
+ }
|
|
|
+
|
|
|
+ function setNativeFn() {
|
|
|
+ if (hasMozMismatch) {
|
|
|
+ window.requestAnimationFrame = setTimeoutWithTimestamp;
|
|
|
+ window.cancelAnimationFrame = clearTimeoutWithId;
|
|
|
+ } else {
|
|
|
+ window.requestAnimationFrame = queryRequestAnimationFrame();
|
|
|
+ window.cancelAnimationFrame = queryCancelAnimationFrame();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The type value "request" singles out firefox 4 - 10 and
|
|
|
+ * assigns the setTimeout function if plausible.
|
|
|
+ */
|
|
|
+
|
|
|
+ switch (type) {
|
|
|
+ case 'request':
|
|
|
+ case '':
|
|
|
+ func = getRequestFn();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'cancel':
|
|
|
+ func = getCancelFn();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'native':
|
|
|
+ setNativeFn();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new Error('RequestFrame parameter is not a type.');
|
|
|
+ }
|
|
|
+ return func;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Node.js/ CommonJS
|
|
|
+if (typeof module === 'object' && typeof module.exports === 'object') {
|
|
|
+module.exports = exports = requestFrame;
|
|
|
+}
|
|
|
+
|
|
|
+// AMD
|
|
|
+else if (typeof define === 'function' && define.amd) {
|
|
|
+define(function() {
|
|
|
+ return requestFrame;
|
|
|
+});
|
|
|
+}
|
|
|
+
|
|
|
+// Default to window as global
|
|
|
+else if (typeof window === 'object') {
|
|
|
+window.requestFrame = requestFrame;
|
|
|
+}
|
|
|
+/* global -module, -exports, -define */
|
|
|
+
|
|
|
+}((typeof window === "undefined" ? {} : window)));
|