diff options
Diffstat (limited to 'libs/web/htdocs/luci-static/resources/cbi.js')
-rw-r--r-- | libs/web/htdocs/luci-static/resources/cbi.js | 518 |
1 files changed, 518 insertions, 0 deletions
diff --git a/libs/web/htdocs/luci-static/resources/cbi.js b/libs/web/htdocs/luci-static/resources/cbi.js new file mode 100644 index 000000000..4af6e58d9 --- /dev/null +++ b/libs/web/htdocs/luci-static/resources/cbi.js @@ -0,0 +1,518 @@ +/* + LuCI - Lua Configuration Interface + + Copyright 2008 Steven Barth <steven@midlink.org> + Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org> + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +*/ + +var cbi_d = []; +var cbi_t = []; +var cbi_c = []; + +var cbi_validators = { + + 'integer': function(v) + { + return (v.match(/^-?[0-9]+$/) != null); + }, + + 'uinteger': function(v) + { + return (cbi_validators.integer(v) && (v >= 0)); + }, + + 'ipaddr': function(v) + { + return cbi_validators.ip4addr(v) || cbi_validators.ip6addr(v); + }, + + 'ip4addr': function(v) + { + if( v.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\/(\d+))?$/) ) + { + return (RegExp.$1 >= 0) && (RegExp.$1 <= 255) && + (RegExp.$2 >= 0) && (RegExp.$2 <= 255) && + (RegExp.$3 >= 0) && (RegExp.$3 <= 255) && + (RegExp.$4 >= 0) && (RegExp.$4 <= 255) && + (!RegExp.$5 || ((RegExp.$6 >= 0) && (RegExp.$6 <= 32))) + ; + } + + return false; + }, + + 'ip6addr': function(v) + { + if( v.match(/^([a-fA-F0-9:.]+)(\/(\d+))?$/) ) + { + if( !RegExp.$2 || ((RegExp.$3 >= 0) && (RegExp.$3 <= 128)) ) + { + var addr = RegExp.$1; + + if( addr == '::' ) + { + return true; + } + + if( addr.indexOf('.') > 0 ) + { + var off = addr.lastIndexOf(':'); + + if( !(off && cbi_validators.ip4addr(addr.substr(off+1))) ) + return false; + + addr = addr.substr(0, off) + ':0:0'; + } + + if( addr.indexOf('::') < 0 ) + { + return (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null); + } + + var fields = 0; + + for( var i = 0, last = 0, comp = false; i <= addr.length; i++ ) + { + if( (addr.charAt(i) == ':') || (i == addr.length) ) + { + if( (i == last) && !comp ) + { + comp = true; + } + else + { + var f = addr.substring(last, i); + if( !(f && f.match(/^[a-fA-F0-9]{1,4}$/)) ) + return false; + } + + fields++; + last = i + 1; + } + } + + return (fields == 8); + } + } + + return false; + }, + + 'port': function(v) + { + return cbi_validators.integer(v) && (v >= 0) && (v <= 65535); + }, + + 'portrange': function(v) + { + if( v.match(/^(\d+)-(\d+)$/) ) + { + var p1 = RegExp.$1; + var p2 = RegExp.$2; + + return cbi_validators.port(p1) && + cbi_validators.port(p2) && + (parseInt(p1) <= parseInt(p2)) + ; + } + else + { + return cbi_validators.port(v); + } + }, + + 'macaddr': function(v) + { + return (v.match(/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/) != null); + }, + + 'host': function(v) + { + return cbi_validators.hostname(v) || cbi_validators.ipaddr(v); + }, + + 'hostname': function(v) + { + return (v.match(/^[a-zA-Z_][a-zA-Z0-9_\-.]*$/) != null); + }, + + 'wpakey': function(v) + { + if( v.length == 64 ) + return (v.match(/^[a-fA-F0-9]{64}$/) != null); + else + return (v.length >= 8) && (v.length <= 63); + }, + + 'wepkey': function(v) + { + if( v.substr(0,2) == 's:' ) + v = v.substr(2); + + if( (v.length == 10) || (v.length == 26) ) + return (v.match(/^[a-fA-F0-9]{10,26}$/) != null); + else + return (v.length == 5) || (v.length == 13); + }, + +}; + + +function cbi_d_add(field, dep, next) { + var obj = document.getElementById(field); + if (obj) { + var entry + for (var i=0; i<cbi_d.length; i++) { + if (cbi_d[i].id == field) { + entry = cbi_d[i]; + break; + } + } + if (!entry) { + entry = { + "node": obj, + "id": field, + "parent": obj.parentNode.id, + "next": next, + "deps": [] + }; + cbi_d.unshift(entry); + } + entry.deps.push(dep) + } +} + +function cbi_d_checkvalue(target, ref) { + var t = document.getElementById(target); + var value; + + if (!t) { + var tl = document.getElementsByName(target); + + if( tl.length > 0 && tl[0].type == 'radio' ) + for( var i = 0; i < tl.length; i++ ) + if( tl[i].checked ) { + value = tl[i].value; + break; + } + + value = value ? value : ""; + } else if (!t.value) { + value = ""; + } else { + value = t.value; + + if (t.type == "checkbox") { + value = t.checked ? value : ""; + } + } + + return (value == ref) +} + +function cbi_d_check(deps) { + var reverse; + var def = false; + for (var i=0; i<deps.length; i++) { + var istat = true; + reverse = false; + for (var j in deps[i]) { + if (j == "!reverse") { + reverse = true; + } else if (j == "!default") { + def = true; + istat = false; + } else { + istat = (istat && cbi_d_checkvalue(j, deps[i][j])) + } + } + if (istat) { + return !reverse; + } + } + return def; +} + +function cbi_d_update() { + var state = false; + for (var i=0; i<cbi_d.length; i++) { + var entry = cbi_d[i]; + var next = document.getElementById(entry.next) + var node = document.getElementById(entry.id) + var parent = document.getElementById(entry.parent) + + if (node && node.parentNode && !cbi_d_check(entry.deps)) { + node.parentNode.removeChild(node); + state = true; + if( entry.parent ) + cbi_c[entry.parent]--; + } else if ((!node || !node.parentNode) && cbi_d_check(entry.deps)) { + if (!next) { + parent.appendChild(entry.node); + } else { + next.parentNode.insertBefore(entry.node, next); + } + state = true; + if( entry.parent ) + cbi_c[entry.parent]++; + } + } + + if (entry.parent) { + cbi_t_update(); + } + + if (state) { + cbi_d_update(); + } +} + +function cbi_bind(obj, type, callback, mode) { + if (typeof mode == "undefined") { + mode = false; + } + if (!obj.addEventListener) { + ieCallback = function(){ + var e = window.event; + if (!e.target && e.srcElement) { + e.target = e.srcElement; + }; + e.target['_eCB' + type + callback] = callback; + e.target['_eCB' + type + callback](e); + e.target['_eCB' + type + callback] = null; + }; + obj.attachEvent('on' + type, ieCallback); + } else { + obj.addEventListener(type, callback, mode); + } + return obj; +} + +function cbi_combobox(id, values, def, man) { + var selid = "cbi.combobox." + id; + if (document.getElementById(selid)) { + return + } + + var obj = document.getElementById(id) + var sel = document.createElement("select"); + sel.id = selid; + sel.className = 'cbi-input-select'; + if (obj.className && obj.className.match(/cbi-input-invalid/)) { + sel.className += ' cbi-input-invalid'; + } + if (obj.nextSibling) { + obj.parentNode.insertBefore(sel, obj.nextSibling); + } else { + obj.parentNode.appendChild(sel); + } + + if (!values[obj.value]) { + if (obj.value == "") { + var optdef = document.createElement("option"); + optdef.value = ""; + optdef.appendChild(document.createTextNode(def)); + sel.appendChild(optdef); + } else { + var opt = document.createElement("option"); + opt.value = obj.value; + opt.selected = "selected"; + opt.appendChild(document.createTextNode(obj.value)); + sel.appendChild(opt); + } + } + + for (var i in values) { + var opt = document.createElement("option"); + opt.value = i; + + if (obj.value == i) { + opt.selected = "selected"; + } + + opt.appendChild(document.createTextNode(values[i])); + sel.appendChild(opt); + } + + var optman = document.createElement("option"); + optman.value = ""; + optman.appendChild(document.createTextNode(man)); + sel.appendChild(optman); + + obj.style.display = "none"; + + cbi_bind(sel, "change", function() { + if (sel.selectedIndex == sel.options.length - 1) { + obj.style.display = "inline"; + sel.parentNode.removeChild(sel); + obj.focus(); + } else { + obj.value = sel.options[sel.selectedIndex].value; + sel.className = (!obj.validate || obj.validate()) + ? 'cbi-input-select' : 'cbi-input-select cbi-input-invalid'; + } + + try { + cbi_d_update(); + } catch (e) { + //Do nothing + } + }) +} + +function cbi_combobox_init(id, values, def, man) { + var obj = document.getElementById(id); + cbi_bind(obj, "blur", function() { + cbi_combobox(id, values, def, man) + }); + cbi_combobox(id, values, def, man); +} + +function cbi_filebrowser(id, url, defpath) { + var field = document.getElementById(id); + var browser = window.open( + url + ( field.value || defpath || '' ) + '?field=' + id, + "luci_filebrowser", "width=300,height=400,left=100,top=200,scrollbars=yes" + ); + + browser.focus(); +} + +//Hijacks the CBI form to send via XHR (requires Prototype) +function cbi_hijack_forms(layer, win, fail, load) { + var forms = layer.getElementsByTagName('form'); + for (var i=0; i<forms.length; i++) { + $(forms[i]).observe('submit', function(event) { + // Prevent the form from also submitting the regular way + event.stop(); + + // Submit via XHR + event.element().request({ + onSuccess: win, + onFailure: fail + }); + + if (load) { + load(); + } + }); + } +} + + +function cbi_t_add(section, tab) { + var t = document.getElementById('tab.' + section + '.' + tab); + var c = document.getElementById('container.' + section + '.' + tab); + + if( t && c ) { + cbi_t[section] = (cbi_t[section] || [ ]); + cbi_t[section][tab] = { 'tab': t, 'container': c, 'cid': c.id }; + } +} + +function cbi_t_switch(section, tab) { + if( cbi_t[section] && cbi_t[section][tab] ) { + var o = cbi_t[section][tab]; + var h = document.getElementById('tab.' + section); + for( var tid in cbi_t[section] ) { + var o2 = cbi_t[section][tid]; + if( o.tab.id != o2.tab.id ) { + o2.tab.className = o2.tab.className.replace(/(^| )cbi-tab( |$)/, " cbi-tab-disabled "); + o2.container.style.display = 'none'; + } + else { + if(h) h.value = tab; + o2.tab.className = o2.tab.className.replace(/(^| )cbi-tab-disabled( |$)/, " cbi-tab "); + o2.container.style.display = 'block'; + } + } + } + return false +} + +function cbi_t_update() { + for( var sid in cbi_t ) + for( var tid in cbi_t[sid] ) + if( cbi_c[cbi_t[sid][tid].cid] == 0 ) { + cbi_t[sid][tid].tab.style.display = 'none'; + } + else if( cbi_t[sid][tid].tab && cbi_t[sid][tid].tab.style.display == 'none' ) { + cbi_t[sid][tid].tab.style.display = ''; + + var t = cbi_t[sid][tid].tab; + window.setTimeout(function() { t.className = t.className.replace(/ cbi-tab-highlighted/g, '') }, 750); + cbi_t[sid][tid].tab.className += ' cbi-tab-highlighted'; + } +} + + +function cbi_validate_form(form, errmsg) +{ + if( form.cbi_validators ) + { + for( var i = 0; i < form.cbi_validators.length; i++ ) + { + var validator = form.cbi_validators[i]; + if( !validator() && errmsg ) + { + alert(errmsg); + return false; + } + } + } + + return true; +} + +function cbi_validate_reset(form) +{ + window.setTimeout( + function() { cbi_validate_form(form, null) }, 100 + ); + + return true; +} + +function cbi_validate_field(cbid, optional, type) +{ + var field = document.getElementById(cbid); + var vldcb = cbi_validators[type]; + + if( field && vldcb ) + { + var validator = function(reset) + { + // is not detached + if( field.form ) + { + field.className = field.className.replace(/ cbi-input-invalid/g, ''); + + // validate value + var value = (field.options) ? field.options[field.options.selectedIndex].value : field.value; + if( !(((value.length == 0) && optional) || vldcb(value)) ) + { + // invalid + field.className += ' cbi-input-invalid'; + return false; + } + } + + return true; + }; + + if( ! field.form.cbi_validators ) + field.form.cbi_validators = [ ]; + + field.form.cbi_validators.push(validator); + field.onblur = field.onkeyup = field.validate = validator; + + validator(); + } +} + |