luci2: support placeholder attribute for L.cbi.DummyValue widgets
[project/luci2/ui.git] / luci2 / htdocs / luci2 / luci2.js
index 5e9510504f5f840388475a656a2d477e761f8a6c..2b4a5f18b45d6f89a4055ede3b1eaa8e895e82a7 100644 (file)
@@ -4611,8 +4611,7 @@ function LuCI2()
 
                'ipaddr': function()
                {
-                       if (validation.types['ip4addr'].apply(this) ||
-                               validation.types['ip6addr'].apply(this))
+                       if (L.parseIPv4(this) || L.parseIPv6(this))
                                return true;
 
                        validation.i18n('Must be a valid IP address');
@@ -4621,17 +4620,8 @@ function LuCI2()
 
                'ip4addr': function()
                {
-                       if (this.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(\/(\S+))?$/))
-                       {
-                               if ((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.$6.indexOf('.') < 0)
-                                     ? ((RegExp.$6 >= 0) && (RegExp.$6 <= 32))
-                                     : (validation.types['ip4addr'].apply(RegExp.$6))))
-                                       return true;
-                       }
+                       if (L.parseIPv4(this))
+                               return true;
 
                        validation.i18n('Must be a valid IPv4 address');
                        return false;
@@ -4639,62 +4629,74 @@ function LuCI2()
 
                'ip6addr': function()
                {
-                       if (this.match(/^([a-fA-F0-9:.]+)(\/(\d+))?$/))
-                       {
-                               if (!RegExp.$2 || ((RegExp.$3 >= 0) && (RegExp.$3 <= 128)))
-                               {
-                                       var addr = RegExp.$1;
+                       if (L.parseIPv6(this))
+                               return true;
 
-                                       if (addr == '::')
-                                       {
-                                               return true;
-                                       }
+                       validation.i18n('Must be a valid IPv6 address');
+                       return false;
+               },
 
-                                       if (addr.indexOf('.') > 0)
-                                       {
-                                               var off = addr.lastIndexOf(':');
+               'netmask4': function()
+               {
+                       if (L.isNetmask(L.parseIPv4(this)))
+                               return true;
 
-                                               if (!(off && validation.types['ip4addr'].apply(addr.substr(off+1))))
-                                               {
-                                                       validation.i18n('Must be a valid IPv6 address');
-                                                       return false;
-                                               }
+                       validation.i18n('Must be a valid IPv4 netmask');
+                       return false;
+               },
 
-                                               addr = addr.substr(0, off) + ':0:0';
-                                       }
+               'netmask6': function()
+               {
+                       if (L.isNetmask(L.parseIPv6(this)))
+                               return true;
 
-                                       if (addr.indexOf('::') >= 0)
-                                       {
-                                               var colons = 0;
-                                               var fill = '0';
+                       validation.i18n('Must be a valid IPv6 netmask6');
+                       return false;
+               },
 
-                                               for (var i = 1; i < (addr.length-1); i++)
-                                                       if (addr.charAt(i) == ':')
-                                                               colons++;
+               'cidr4': function()
+               {
+                       if (this.match(/^([0-9.]+)\/(\d{1,2})$/))
+                               if (RegExp.$2 <= 32 && L.parseIPv4(RegExp.$1))
+                                       return true;
 
-                                               if (colons > 7)
-                                               {
-                                                       validation.i18n('Must be a valid IPv6 address');
-                                                       return false;
-                                               }
+                       validation.i18n('Must be a valid IPv4 prefix');
+                       return false;
+               },
 
-                                               for (var i = 0; i < (7 - colons); i++)
-                                                       fill += ':0';
+               'cidr6': function()
+               {
+                       if (this.match(/^([a-fA-F0-9:.]+)\/(\d{1,3})$/))
+                               if (RegExp.$2 <= 128 && L.parseIPv6(RegExp.$1))
+                                       return true;
 
-                                               if (addr.match(/^(.*?)::(.*?)$/))
-                                                       addr = (RegExp.$1 ? RegExp.$1 + ':' : '') + fill +
-                                                                  (RegExp.$2 ? ':' + RegExp.$2 : '');
-                                       }
+                       validation.i18n('Must be a valid IPv6 prefix');
+                       return false;
+               },
 
-                                       if (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null)
-                                               return true;
+               'ipmask4': function()
+               {
+                       if (this.match(/^([0-9.]+)\/([0-9.]+)$/))
+                       {
+                               var addr = RegExp.$1, mask = RegExp.$2;
+                               if (L.parseIPv4(addr) && L.isNetmask(L.parseIPv4(mask)))
+                                       return true;
+                       }
 
-                                       validation.i18n('Must be a valid IPv6 address');
-                                       return false;
-                               }
+                       validation.i18n('Must be a valid IPv4 address/netmask pair');
+                       return false;
+               },
+
+               'ipmask6': function()
+               {
+                       if (this.match(/^([a-fA-F0-9:.]+)\/([a-fA-F0-9:.]+)$/))
+                       {
+                               var addr = RegExp.$1, mask = RegExp.$2;
+                               if (L.parseIPv6(addr) && L.isNetmask(L.parseIPv6(mask)))
+                                       return true;
                        }
 
-                       validation.i18n('Must be a valid IPv6 address');
+                       validation.i18n('Must be a valid IPv6 address/netmask pair');
                        return false;
                },
 
@@ -5097,7 +5099,7 @@ function LuCI2()
                        if (typeof(a) != typeof(b))
                                return true;
 
-                       if (typeof(a) == 'object')
+                       if ($.isArray(a))
                        {
                                if (a.length != b.length)
                                        return true;
@@ -5108,6 +5110,18 @@ function LuCI2()
 
                                return false;
                        }
+                       else if ($.isPlainObject(a))
+                       {
+                               for (var k in a)
+                                       if (!(k in b))
+                                               return true;
+
+                               for (var k in b)
+                                       if (!(k in a) || a[k] !== b[k])
+                                               return true;
+
+                               return false;
+                       }
 
                        return (a != b);
                },
@@ -5975,7 +5989,7 @@ function LuCI2()
                        return $('<div />')
                                .addClass('form-control-static')
                                .attr('id', this.id(sid))
-                               .html(this.ucivalue(sid));
+                               .html(this.ucivalue(sid) || this.label('placeholder'));
                },
 
                formvalue: function(sid)
@@ -6468,6 +6482,11 @@ function LuCI2()
                        return true;
                },
 
+               sort: function(section1, section2)
+               {
+                       return 0;
+               },
+
                sections: function(cb)
                {
                        var s1 = L.uci.sections(this.map.uci_package);
@@ -6478,6 +6497,8 @@ function LuCI2()
                                        if (this.filter(s1[i]))
                                                s2.push(s1[i]);
 
+                       s2.sort(this.sort);
+
                        if (typeof(cb) == 'function')
                                for (var i = 0; i < s2.length; i++)
                                        cb.call(this, s2[i]);