luci-mod-network: steering flow - permit only integer value
[project/luci.git] / modules / luci-base / htdocs / luci-static / resources / cbi.js
index d4d61eb381119b18dc5761fe50776497a74e11a6..d7b462c367e54106c58a4f48af5e016095210ea7 100644 (file)
@@ -94,8 +94,25 @@ function sfh(s) {
        return (0x100000000 + hash).toString(16).substr(1);
 }
 
-function _(s) {
-       return (window.TR && TR[sfh(s)]) || s;
+var plural_function = null;
+
+function trimws(s) {
+       return String(s).trim().replace(/[ \t\n]+/g, ' ');
+}
+
+function _(s, c) {
+       var k = (c != null ? trimws(c) + '\u0001' : '') + trimws(s);
+       return (window.TR && TR[sfh(k)]) || s;
+}
+
+function N_(n, s, p, c) {
+       if (plural_function == null && window.TR)
+               plural_function = new Function('n', (TR['00000000'] || 'plural=(n != 1);') + 'return +plural');
+
+       var i = plural_function ? plural_function(n) : (n != 1),
+           k = (c != null ? trimws(c) + '\u0001' : '') + trimws(s) + '\u0002' + i.toString();
+
+       return (window.TR && TR[sfh(k)]) || (i ? p : s);
 }
 
 
@@ -298,8 +315,6 @@ function cbi_init() {
                                   node.getAttribute('data-type'));
        }
 
-       document.querySelectorAll('[data-browser]').forEach(cbi_browser_init);
-
        document.querySelectorAll('.cbi-tooltip:not(:empty)').forEach(function(s) {
                s.parentNode.classList.add('cbi-tooltip-container');
        });
@@ -316,39 +331,20 @@ function cbi_init() {
                i.addEventListener('mouseout', handler);
        });
 
+       var tasks = [];
+
        document.querySelectorAll('[data-ui-widget]').forEach(function(node) {
                var args = JSON.parse(node.getAttribute('data-ui-widget') || '[]'),
                    widget = new (Function.prototype.bind.apply(L.ui[args[0]], args)),
                    markup = widget.render();
 
-               markup.addEventListener('widget-change', cbi_d_update);
-               node.parentNode.replaceChild(markup, node);
+               tasks.push(Promise.resolve(markup).then(function(markup) {
+                       markup.addEventListener('widget-change', cbi_d_update);
+                       node.parentNode.replaceChild(markup, node);
+               }));
        });
 
-       cbi_d_update();
-}
-
-function cbi_filebrowser(id, defpath) {
-       var field   = L.dom.elem(id) ? id : document.getElementById(id);
-       var browser = window.open(
-               cbi_strings.path.browser + (field.value || defpath || '') + '?field=' + field.id,
-               "luci_filebrowser", "width=300,height=400,left=100,top=200,scrollbars=yes"
-       );
-
-       browser.focus();
-}
-
-function cbi_browser_init(field)
-{
-       field.parentNode.insertBefore(
-               E('img', {
-                       'src': L.resource('cbi/folder.gif'),
-                       'class': 'cbi-image-button',
-                       'click': function(ev) {
-                               cbi_filebrowser(field, field.getAttribute('data-browser'));
-                               ev.preventDefault();
-                       }
-               }), field.nextSibling);
+       Promise.all(tasks).then(cbi_d_update);
 }
 
 function cbi_validate_form(form, errmsg)
@@ -371,6 +367,12 @@ function cbi_validate_form(form, errmsg)
        return true;
 }
 
+function cbi_validate_named_section_add(input)
+{
+       var button = input.parentNode.parentNode.querySelector('.cbi-button-add');
+       button.disabled = input.value === '';
+}
+
 function cbi_validate_reset(form)
 {
        window.setTimeout(
@@ -514,9 +516,14 @@ String.prototype.format = function()
        var quot_esc = [/"/g, '"', /'/g, '''];
 
        function esc(s, r) {
-               if (typeof(s) !== 'string' && !(s instanceof String))
+               var t = typeof(s);
+
+               if (s == null || t === 'object' || t === 'function')
                        return '';
 
+               if (t !== 'string')
+                       s = String(s);
+
                for (var i = 0; i < r.length; i += 2)
                        s = s.replace(r[i], r[i+1]);
 
@@ -566,7 +573,7 @@ String.prototype.format = function()
 
                                switch(pType) {
                                        case 'b':
-                                               subst = (~~param || 0).toString(2);
+                                               subst = Math.floor(+param || 0).toString(2);
                                                break;
 
                                        case 'c':
@@ -574,11 +581,12 @@ String.prototype.format = function()
                                                break;
 
                                        case 'd':
-                                               subst = (~~param || 0);
+                                               subst = Math.floor(+param || 0).toFixed(0);
                                                break;
 
                                        case 'u':
-                                               subst = ~~Math.abs(+param || 0);
+                                               var n = +param || 0;
+                                               subst = Math.floor((n < 0) ? 0x100000000 + n : n).toFixed(0);
                                                break;
 
                                        case 'f':
@@ -588,7 +596,7 @@ String.prototype.format = function()
                                                break;
 
                                        case 'o':
-                                               subst = (~~param || 0).toString(8);
+                                               subst = Math.floor(+param || 0).toString(8);
                                                break;
 
                                        case 's':
@@ -596,11 +604,11 @@ String.prototype.format = function()
                                                break;
 
                                        case 'x':
-                                               subst = ('' + (~~param || 0).toString(16)).toLowerCase();
+                                               subst = Math.floor(+param || 0).toString(16).toLowerCase();
                                                break;
 
                                        case 'X':
-                                               subst = ('' + (~~param || 0).toString(16)).toUpperCase();
+                                               subst = Math.floor(+param || 0).toString(16).toUpperCase();
                                                break;
 
                                        case 'h':
@@ -617,17 +625,17 @@ String.prototype.format = function()
                                                var tm = 0;
                                                var ts = (param || 0);
 
-                                               if (ts > 60) {
+                                               if (ts > 59) {
                                                        tm = Math.floor(ts / 60);
                                                        ts = (ts % 60);
                                                }
 
-                                               if (tm > 60) {
+                                               if (tm > 59) {
                                                        th = Math.floor(tm / 60);
                                                        tm = (tm % 60);
                                                }
 
-                                               if (th > 24) {
+                                               if (th > 23) {
                                                        td = Math.floor(th / 24);
                                                        th = (th % 24);
                                                }
@@ -649,7 +657,11 @@ String.prototype.format = function()
                                                for (i = 0; (i < units.length) && (val > mf); i++)
                                                        val /= mf;
 
-                                               subst = (i ? val.toFixed(pr) : val) + units[i];
+                                               if (i)
+                                                       subst = val.toFixed(pr) + units[i] + (mf == 1024 ? 'i' : '');
+                                               else
+                                                       subst = val + ' ';
+
                                                pMinLength = null;
                                                break;
                                }
@@ -721,19 +733,10 @@ function matchesElem(node, selector) { return L.dom.matches(node, selector) }
 function findParent(node, selector) { return L.dom.parent(node, selector) }
 function E() { return L.dom.create.apply(L.dom, arguments) }
 
-if (typeof(window.CustomEvent) !== 'function') {
-       function CustomEvent(event, params) {
-               params = params || { bubbles: false, cancelable: false, detail: undefined };
-               var evt = document.createEvent('CustomEvent');
-                   evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
-               return evt;
-       }
-
-       CustomEvent.prototype = window.Event.prototype;
-       window.CustomEvent = CustomEvent;
-}
-
 function cbi_dropdown_init(sb) {
+       if (sb && L.dom.findClassInstance(sb) instanceof L.ui.Dropdown)
+               return;
+
        var dl = new L.ui.Dropdown(sb, null, { name: sb.getAttribute('name') });
        return dl.bind(sb);
 }
@@ -744,68 +747,14 @@ function cbi_update_table(table, data, placeholder) {
        if (!isElem(target))
                return;
 
-       target.querySelectorAll('.tr.table-titles, .cbi-section-table-titles').forEach(function(thead) {
-               var titles = [];
-
-               thead.querySelectorAll('.th').forEach(function(th) {
-                       titles.push(th);
-               });
-
-               if (Array.isArray(data)) {
-                       var n = 0, rows = target.querySelectorAll('.tr');
+       var t = L.dom.findClassInstance(target);
 
-                       data.forEach(function(row) {
-                               var trow = E('div', { 'class': 'tr' });
-
-                               for (var i = 0; i < titles.length; i++) {
-                                       var text = (titles[i].innerText || '').trim();
-                                       var td = trow.appendChild(E('div', {
-                                               'class': titles[i].className,
-                                               'data-title': (text !== '') ? text : null
-                                       }, row[i] || ''));
-
-                                       td.classList.remove('th');
-                                       td.classList.add('td');
-                               }
-
-                               trow.classList.add('cbi-rowstyle-%d'.format((n++ % 2) ? 2 : 1));
-
-                               if (rows[n])
-                                       target.replaceChild(trow, rows[n]);
-                               else
-                                       target.appendChild(trow);
-                       });
-
-                       while (rows[++n])
-                               target.removeChild(rows[n]);
-
-                       if (placeholder && target.firstElementChild === target.lastElementChild) {
-                               var trow = target.appendChild(E('div', { 'class': 'tr placeholder' }));
-                               var td = trow.appendChild(E('div', { 'class': titles[0].className }, placeholder));
-
-                               td.classList.remove('th');
-                               td.classList.add('td');
-                       }
-               }
-               else {
-                       thead.parentNode.style.display = 'none';
-
-                       thead.parentNode.querySelectorAll('.tr, .cbi-section-table-row').forEach(function(trow) {
-                               if (trow !== thead) {
-                                       var n = 0;
-                                       trow.querySelectorAll('.th, .td').forEach(function(td) {
-                                               if (n < titles.length) {
-                                                       var text = (titles[n++].innerText || '').trim();
-                                                       if (text !== '')
-                                                               td.setAttribute('data-title', text);
-                                               }
-                                       });
-                               }
-                       });
+       if (!(t instanceof L.ui.Table)) {
+               t = new L.ui.Table(target);
+               L.dom.bindClassInstance(target, t);
+       }
 
-                       thead.parentNode.style.display = '';
-               }
-       });
+       t.update(data, placeholder);
 }
 
 function showModal(title, children)
@@ -830,5 +779,7 @@ document.addEventListener('DOMContentLoaded', function() {
                        L.hideTooltip(ev);
        });
 
-       document.querySelectorAll('.table').forEach(cbi_update_table);
+       L.require('ui').then(function(ui) {
+               document.querySelectorAll('.table').forEach(cbi_update_table);
+       });
 });