luci2: fix various cross browser issues
authorJo-Philipp Wich <jow@openwrt.org>
Mon, 4 Nov 2013 21:59:28 +0000 (21:59 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Mon, 4 Nov 2013 22:03:15 +0000 (22:03 +0000)
- add respond.js to fix page rendering in IE 8
- fix datatype validation compiler in IE 8
- fix RPC response type checking in IE 8
- show/hide badges and labels since IE 8 does not support :empty CSS selector
- fix wrong classes for radio and checkbox items, leading to broken rendering in Chrome
- stop using deprecated arguments.callee

luci2/htdocs/luci2.html
luci2/htdocs/luci2/luci2.js
luci2/htdocs/luci2/respond.min.js [new file with mode: 0644]

index b390ec1c7bbdea7f6c37f16730025e591d643a18..de5e037dadcf90e21a6044126534f5a18fbfe52a 100644 (file)
@@ -6,7 +6,10 @@
         <link rel="stylesheet" href="/luci2/css/bootstrap.css">
         <link rel="stylesheet" href="/luci2/css/luci2.css">
 
-        <!--[if lt IE 9]><script src="/luci2/html5.js"></script><![endif]-->
+        <!--[if lt IE 9]>
+            <script src="/luci2/html5.js"></script>
+            <script src="/luci2/respond.min.js"></script>
+        <![endif]-->
 
         <script type="text/javascript" src="/luci2/jquery-1.9.1.js"></script>
         <script type="text/javascript" src="/luci2/jquery.peity.js"></script>
index 6481c0bd90416c989d2f6e092e8c482527bc53da..ab7faa87a5611ff61bd3d715e24f1c29ae79056e 100644 (file)
@@ -214,7 +214,7 @@ function LuCI2()
                _class.prototype = prototype;
                _class.prototype.constructor = _class;
 
-               _class.extend = arguments.callee;
+               _class.extend = Class.extend;
 
                return _class;
        };
@@ -451,7 +451,7 @@ function LuCI2()
                                                if (typeof(ret) != 'undefined' && key != '')
                                                        ret = ret[key];
 
-                                               if (type.call(ret) != type.call(req.expect[key]))
+                                               if (typeof(ret) == 'undefined' || type.call(ret) != type.call(req.expect[key]))
                                                        ret = req.expect[key];
 
                                                break;
@@ -2920,7 +2920,7 @@ function LuCI2()
                                                                else if (typeof types[label] == 'function')
                                                                {
                                                                        stack.push(types[label]);
-                                                                       stack.push(null);
+                                                                       stack.push([ ]);
                                                                }
                                                                else
                                                                {
@@ -2939,7 +2939,7 @@ function LuCI2()
                                                                throw "Syntax error, argument list follows non-function";
 
                                                        stack[stack.length-1] =
-                                                               arguments.callee(code.substring(pos, i));
+                                                               _luci2.cbi.validation.compile(code.substring(pos, i));
 
                                                        pos = i+1;
                                                }
@@ -3389,6 +3389,7 @@ function LuCI2()
                        }
 
                        i.error = $('<div />')
+                               .hide()
                                .addClass('label label-danger');
 
                        i.widget = $('<div />')
@@ -3525,7 +3526,7 @@ function LuCI2()
                                        d.elem.parents('div.form-group, td').first().addClass('luci2-form-error');
                                        d.elem.parents('div.input-group, div.form-group, td').first().addClass('has-error');
 
-                                       d.inst.error.text(_luci2.tr('Field must not be empty'));
+                                       d.inst.error.text(_luci2.tr('Field must not be empty')).show();
                                        rv = false;
                                }
                                else if (val.length > 0 && !vstack[0].apply(val, vstack[1]))
@@ -3533,7 +3534,7 @@ function LuCI2()
                                        d.elem.parents('div.form-group, td').first().addClass('luci2-form-error');
                                        d.elem.parents('div.input-group, div.form-group, td').first().addClass('has-error');
 
-                                       d.inst.error.text(validation.message.format.apply(validation.message, vstack[1]));
+                                       d.inst.error.text(validation.message.format.apply(validation.message, vstack[1])).show();
                                        rv = false;
                                }
                                else
@@ -3544,7 +3545,7 @@ function LuCI2()
                                        if (d.multi && d.inst.widget && d.inst.widget.find('input.error, select.error').length > 0)
                                                rv = false;
                                        else
-                                               d.inst.error.text('');
+                                               d.inst.error.text('').hide();
                                }
                        }
 
@@ -3749,7 +3750,6 @@ function LuCI2()
                        if (typeof(o.disabled) == 'undefined') o.disabled = '0';
 
                        var i = $('<input />')
-                               .addClass('form-control')
                                .attr('id', this.id(sid))
                                .attr('type', 'checkbox')
                                .prop('checked', this.ucivalue(sid));
@@ -4424,13 +4424,12 @@ function LuCI2()
 
                                        $('<li />')
                                                .append($('<label />')
-                                                       .addClass('radio inline')
+                                                       .addClass(itype + ' inline')
                                                        .append($('<input />')
                                                                .attr('name', itype + id)
                                                                .attr('type', itype)
                                                                .attr('value', iface['interface'])
-                                                               .prop('checked', !!check[iface['interface']])
-                                                               .addClass('form-control'))
+                                                               .prop('checked', !!check[iface['interface']]))
                                                        .append(badge))
                                                .appendTo(ul);
                                }
@@ -4440,13 +4439,12 @@ function LuCI2()
                        {
                                $('<li />')
                                        .append($('<label />')
-                                               .addClass('radio inline text-muted')
+                                               .addClass(itype + ' inline text-muted')
                                                .append($('<input />')
                                                        .attr('name', itype + id)
                                                        .attr('type', itype)
                                                        .attr('value', '')
-                                                       .prop('checked', !value)
-                                                       .addClass('form-control'))
+                                                       .prop('checked', !value))
                                                .append(_luci2.tr('unspecified')))
                                        .appendTo(ul);
                        }
@@ -4611,19 +4609,21 @@ function LuCI2()
                                                inval++;
 
                                if (inval > 0)
-                                       stbadge.text(inval)
+                                       stbadge.show()
+                                               .text(inval)
                                                .attr('title', _luci2.trp('1 Error', '%d Errors', inval).format(inval));
                                else
-                                       stbadge.text('');
+                                       stbadge.hide();
 
                                invals += inval;
                        }
 
                        if (invals > 0)
-                               badge.text(invals)
+                               badge.show()
+                                       .text(invals)
                                        .attr('title', _luci2.trp('1 Error', '%d Errors', invals).format(invals));
                        else
-                               badge.text('');
+                               badge.hide();
 
                        return invals;
                },
@@ -4645,10 +4645,11 @@ function LuCI2()
                        var badge = $('#' + this.id('sectiontab')).children('span:first');
 
                        if (this.error_count > 0)
-                               badge.text(this.error_count)
+                               badge.show()
+                                       .text(this.error_count)
                                        .attr('title', _luci2.trp('1 Error', '%d Errors', this.error_count).format(this.error_count));
                        else
-                               badge.text('');
+                               badge.hide();
 
                        return (this.error_count == 0);
                }
diff --git a/luci2/htdocs/luci2/respond.min.js b/luci2/htdocs/luci2/respond.min.js
new file mode 100644 (file)
index 0000000..e3dc2c0
--- /dev/null
@@ -0,0 +1,6 @@
+/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
+/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
+window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document);
+
+/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs  */
+(function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this);