libs/web: fix ip6addr js validation, fixes for live validation
[project/luci.git] / libs / web / htdocs / luci-static / resources / cbi.js
index 4af6e58..74a2576 100644 (file)
@@ -70,34 +70,25 @@ var cbi_validators = {
                                        addr = addr.substr(0, off) + ':0:0';
                                }
 
-                               if( addr.indexOf('::') < 0 )
+                               if( addr.indexOf('::') >= 0 )
                                {
-                                       return (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null);
-                               }
+                                       var colons = 0;
+                                       var fill = '0';
 
-                               var fields = 0;
+                                       for( var i = 0; i < addr.length; i++ )
+                                               if( addr.charAt(i) == ':' )
+                                                       colons++;
 
-                               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;
-                                       }                               
+                                       if( colons > 7 )
+                                               return false;
+
+                                       for( var i = 0; i < (7 - colons); i++ )
+                                               fill += ':0';
+
+                                       addr = addr.replace(/::/, ':' + fill + ':');
                                }
 
-                               return (fields == 8);
+                               return (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null);
                        }
                }
 
@@ -264,7 +255,7 @@ function cbi_d_update() {
                }
        }
 
-       if (entry.parent) {
+       if (entry && entry.parent) {
                cbi_t_update();
        }
 
@@ -437,6 +428,8 @@ function cbi_t_switch(section, tab) {
 }
 
 function cbi_t_update() {
+       var hl_tabs = [ ];
+
        for( var sid in cbi_t )
                for( var tid in cbi_t[sid] )
                        if( cbi_c[cbi_t[sid][tid].cid] == 0 ) {
@@ -446,14 +439,24 @@ function cbi_t_update() {
                                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';
+                               t.className += ' cbi-tab-highlighted';
+                               hl_tabs.push(t);
                        }
+
+       if( hl_tabs.length > 0 )
+               window.setTimeout(function() {
+                       for( var i = 0; i < hl_tabs.length; i++ )
+                               hl_tabs[i].className = hl_tabs[i].className.replace(/ cbi-tab-highlighted/g, '');
+               }, 750);
 }
 
 
 function cbi_validate_form(form, errmsg)
 {
+       /* if triggered by a section removal or addition, don't validate */
+       if( form.cbi_state == 'add-section' || form.cbi_state == 'del-section' )
+               return true;
+
        if( form.cbi_validators )
        {
                for( var i = 0; i < form.cbi_validators.length; i++ )
@@ -486,7 +489,7 @@ function cbi_validate_field(cbid, optional, type)
 
        if( field && vldcb )
        {
-               var validator = function(reset)
+               var validator = function()
                {
                        // is not detached
                        if( field.form )
@@ -516,3 +519,175 @@ function cbi_validate_field(cbid, optional, type)
        }
 }
 
+if( ! String.serialize )
+       String.serialize = function(o)
+       {
+               switch(typeof(o))
+               {
+                       case 'object':
+                               // null
+                               if( o == null )
+                               {
+                                       return 'null';
+                               }
+
+                               // array
+                               else if( o.length )
+                               {
+                                       var i, s = '';
+
+                                       for( var i = 0; i < o.length; i++ )
+                                               s += (s ? ', ' : '') + String.serialize(o[i]);
+
+                                       return '[ ' + s + ' ]';
+                               }
+
+                               // object
+                               else
+                               {
+                                       var k, s = '';
+
+                                       for( k in o )
+                                               s += (s ? ', ' : '') + k + ': ' + String.serialize(o[k]);
+
+                                       return '{ ' + s + ' }';
+                               }
+
+                               break;
+
+                       case 'string':
+                               // complex string
+                               if( o.match(/[^a-zA-Z0-9_,.: -]/) )
+                                       return 'decodeURIComponent("' + encodeURIComponent(o) + '")';
+
+                               // simple string
+                               else
+                                       return '"' + o + '"';
+
+                               break;
+
+                       default:
+                               return o.toString();
+               }
+       }
+
+
+if( ! String.format )
+       String.format = function()
+       {
+               if (!arguments || arguments.length < 1 || !RegExp)
+                       return;
+
+               var html_esc = [/&/g, '&#38;', /"/g, '&#34;', /'/g, '&#39;', /</g, '&#60;', />/g, '&#62;'];
+               var quot_esc = [/"/g, '&#34;', /'/g, '&#39;'];
+
+               function esc(s, r) {
+                       for( var i = 0; i < r.length; i += 2 )
+                               s = s.replace(r[i], r[i+1]);
+                       return s;
+               }
+
+               var str = arguments[0];
+               var out = '';
+               var re = /^(([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X|q|h|j))/;
+               var a = b = [], numSubstitutions = 0, numMatches = 0;
+
+               while( a = re.exec(str) )
+               {
+                       var m = a[1];
+                       var leftpart = a[2], pPad = a[3], pJustify = a[4], pMinLength = a[5];
+                       var pPrecision = a[6], pType = a[7];
+
+                       numMatches++;
+
+                       if (pType == '%')
+                       {
+                               subst = '%';
+                       }
+                       else
+                       {
+                               if (numSubstitutions++ < arguments.length)
+                               {
+                                       var param = arguments[numSubstitutions];
+
+                                       var pad = '';
+                                       if (pPad && pPad.substr(0,1) == "'")
+                                               pad = leftpart.substr(1,1);
+                                       else if (pPad)
+                                               pad = pPad;
+
+                                       var justifyRight = true;
+                                       if (pJustify && pJustify === "-")
+                                               justifyRight = false;
+
+                                       var minLength = -1;
+                                       if (pMinLength)
+                                               minLength = parseInt(pMinLength);
+
+                                       var precision = -1;
+                                       if (pPrecision && pType == 'f')
+                                               precision = parseInt(pPrecision.substring(1));
+
+                                       var subst = param;
+
+                                       switch(pType)
+                                       {
+                                               case 'b':
+                                                       subst = (parseInt(param) || 0).toString(2);
+                                                       break;
+
+                                               case 'c':
+                                                       subst = String.fromCharCode(parseInt(param) || 0);
+                                                       break;
+
+                                               case 'd':
+                                                       subst = (parseInt(param) || 0);
+                                                       break;
+
+                                               case 'u':
+                                                       subst = Math.abs(parseInt(param) || 0);
+                                                       break;
+
+                                               case 'f':
+                                                       subst = (precision > -1)
+                                                               ? Math.round((parseFloat(param) || 0.0) * Math.pow(10, precision)) / Math.pow(10, precision)
+                                                               : (parseFloat(param) || 0.0);
+                                                       break;
+
+                                               case 'o':
+                                                       subst = (parseInt(param) || 0).toString(8);
+                                                       break;
+
+                                               case 's':
+                                                       subst = param;
+                                                       break;
+
+                                               case 'x':
+                                                       subst = ('' + (parseInt(param) || 0).toString(16)).toLowerCase();
+                                                       break;
+
+                                               case 'X':
+                                                       subst = ('' + (parseInt(param) || 0).toString(16)).toUpperCase();
+                                                       break;
+
+                                               case 'h':
+                                                       subst = esc(param, html_esc);
+                                                       break;
+
+                                               case 'q':
+                                                       subst = esc(param, quot_esc);
+                                                       break;
+
+                                               case 'j':
+                                                       subst = String.serialize(param);
+                                                       break;
+                                       }
+                               }
+                       }
+
+                       out += leftpart + subst;
+                       str = str.substr(m.length);
+               }
+
+               return out + str;
+       }