diff options
Diffstat (limited to 'modules/luci-base/htdocs/luci-static')
7 files changed, 127 insertions, 49 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/firewall.js b/modules/luci-base/htdocs/luci-static/resources/firewall.js index b1c7de4358..4fa4954ba6 100644 --- a/modules/luci-base/htdocs/luci-static/resources/firewall.js +++ b/modules/luci-base/htdocs/luci-static/resources/firewall.js @@ -57,21 +57,7 @@ function getColorForName(forName) { else if (forName == 'wan') return '#f09090'; - random.seed(parseInt(sfh(forName), 16)); - - var r = random.get(128), - g = random.get(128), - min = 0, - max = 128; - - if ((r + g) < 128) - min = 128 - r - g; - else - max = 255 - r - g; - - var b = min + Math.floor(random.get() * (max - min)); - - return '#%02x%02x%02x'.format(0xff - r, 0xff - g, 0xff - b); + return random.derive_color(forName); } @@ -106,7 +92,6 @@ Firewall = L.Class.extend({ z = uci.add('firewall', 'zone'); uci.set('firewall', z, 'name', name); - uci.set('firewall', z, 'network', ' '); uci.set('firewall', z, 'input', d.getInput() || 'DROP'); uci.set('firewall', z, 'output', d.getOutput() || 'DROP'); uci.set('firewall', z, 'forward', d.getForward() || 'DROP'); @@ -347,17 +332,17 @@ Zone = AbstractFirewallItem.extend({ return false; newNetworks.push(network); - this.set('network', newNetworks.join(' ')); + this.set('network', newNetworks); return true; }, deleteNetwork: function(network) { var oldNetworks = this.getNetworks(), - newNetworks = oldNetworks.filter(function(net) { return net != network }); + newNetworks = oldNetworks.filter(function(net) { return net != network }); if (newNetworks.length > 0) - this.set('network', newNetworks.join(' ')); + this.set('network', newNetworks); else this.set('network', null); @@ -369,7 +354,7 @@ Zone = AbstractFirewallItem.extend({ }, clearNetworks: function() { - this.set('network', ' '); + this.set('network', null); }, getDevices: function() { diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index 1588bc7bfb..58a31dddb2 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -3602,13 +3602,47 @@ var CBIFlagValue = CBIValue.extend(/** @lends LuCI.form.FlagValue.prototype */ { * @default 0 */ + /** + * Set a tooltip for the flag option. + * + * If set to a string, it will be used as-is as a tooltip. + * + * If set to a function, the function will be invoked and the return + * value will be shown as a tooltip. If the return value of the function + * is `null` no tooltip will be set. + * + * @name LuCI.form.TypedSection.prototype#tooltip + * @type string|function + * @default null + */ + + /** + * Set a tooltip icon. + * + * If set, this icon will be shown for the default one. + * This could also be a png icon from the resources directory. + * + * @name LuCI.form.TypedSection.prototype#tooltipicon + * @type string + * @default 'ℹ️'; + */ + /** @private */ renderWidget: function(section_id, option_index, cfgvalue) { + var tooltip = null; + + if (typeof(this.tooltip) == 'function') + tooltip = this.tooltip.apply(this, [section_id]); + else if (typeof(this.tooltip) == 'string') + tooltip = (arguments.length > 1) ? ''.format.apply(this.tooltip, this.varargs(arguments, 1)) : this.tooltip; + var widget = new ui.Checkbox((cfgvalue != null) ? cfgvalue : this.default, { id: this.cbid(section_id), value_enabled: this.enabled, value_disabled: this.disabled, validate: L.bind(this.validate, this, section_id), + tooltip: tooltip, + tooltipicon: this.tooltipicon, disabled: (this.readonly != null) ? this.readonly : this.map.readonly }); diff --git a/modules/luci-base/htdocs/luci-static/resources/luci.js b/modules/luci-base/htdocs/luci-static/resources/luci.js index faed3aa6d2..23853e2cc8 100644 --- a/modules/luci-base/htdocs/luci-static/resources/luci.js +++ b/modules/luci-base/htdocs/luci-static/resources/luci.js @@ -672,12 +672,12 @@ * if it is an object, it will be converted to JSON, in all other * cases it is converted to a string. * - * @property {Object<string, string>} [header] - * Specifies HTTP headers to set for the request. - * - * @property {function} [progress] - * An optional request callback function which receives ProgressEvent - * instances as sole argument during the HTTP request transfer. + * @property {Object<string, string>} [header] + * Specifies HTTP headers to set for the request. + * + * @property {function} [progress] + * An optional request callback function which receives ProgressEvent + * instances as sole argument during the HTTP request transfer. */ /** @@ -982,12 +982,13 @@ if (!Poll.active()) return; + var res_json = null; try { - callback(res, res.json(), res.duration); - } - catch (err) { - callback(res, null, res.duration); + res_json = res.json(); } + catch (err) {} + + callback(res, res_json, res.duration); }); }; @@ -2971,7 +2972,12 @@ }).filter(function(e) { return (e[1] != null); }).sort(function(a, b) { - return (a[1] > b[1]); + if (a[1] < b[1]) + return -1; + else if (a[1] > b[1]) + return 1; + else + return 0; }).map(function(e) { return e[0]; }); diff --git a/modules/luci-base/htdocs/luci-static/resources/network.js b/modules/luci-base/htdocs/luci-static/resources/network.js index 1f749c593c..1e24915f97 100644 --- a/modules/luci-base/htdocs/luci-static/resources/network.js +++ b/modules/luci-base/htdocs/luci-static/resources/network.js @@ -1453,6 +1453,18 @@ Network = baseclass.extend(/** @lends LuCI.network.prototype */ { } } + rv.sort(function(a, b) { + if (a.metric != b.metric) + return (a.metric - b.metric); + + if (a.interface < b.interface) + return -1; + else if (a.interface > b.interface) + return 1; + + return 0; + }); + return rv; }, this)); }, diff --git a/modules/luci-base/htdocs/luci-static/resources/tools/prng.js b/modules/luci-base/htdocs/luci-static/resources/tools/prng.js index 752dc75ce8..b916cc7792 100644 --- a/modules/luci-base/htdocs/luci-static/resources/tools/prng.js +++ b/modules/luci-base/htdocs/luci-static/resources/tools/prng.js @@ -89,5 +89,23 @@ return L.Class.extend({ } return Math.floor(r * (u - l + 1)) + l; + }, + + derive_color: function(string) { + this.seed(parseInt(sfh(string), 16)); + + var r = this.get(128), + g = this.get(128), + min = 0, + max = 128; + + if ((r + g) < 128) + min = 128 - r - g; + else + max = 255 - r - g; + + var b = min + Math.floor(this.get() * (max - min)); + + return '#%02x%02x%02x'.format(0xff - r, 0xff - g, 0xff - b); } }); diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index 77074d5075..c8ebef6691 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -610,6 +610,22 @@ var UICheckbox = UIElement.extend(/** @lends LuCI.ui.Checkbox.prototype */ { frameEl.appendChild(E('label', { 'for': id })); + if (this.options.tooltip != null) { + var icon = "⚠️"; + + if (this.options.tooltipicon != null) + icon = this.options.tooltipicon; + + frameEl.appendChild( + E('label', { 'class': 'cbi-tooltip-container' },[ + icon, + E('div', { 'class': 'cbi-tooltip' }, + this.options.tooltip + ) + ]) + ); + } + return this.bind(frameEl); }, @@ -1344,6 +1360,8 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { /** @private */ toggleItem: function(sb, li, force_state) { + var ul = li.parentNode; + if (li.hasAttribute('unselectable')) return; @@ -1420,7 +1438,7 @@ var UIDropdown = UIElement.extend(/** @lends LuCI.ui.Dropdown.prototype */ { this.closeDropdown(sb, true); } - this.saveValues(sb, li.parentNode); + this.saveValues(sb, ul); }, /** @private */ @@ -3597,9 +3615,11 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ { this.setActiveTabId(panes[selected], selected); } - panes[selected].dispatchEvent(new CustomEvent('cbi-tab-active', { - detail: { tab: panes[selected].getAttribute('data-tab') } - })); + requestAnimationFrame(L.bind(function(pane) { + pane.dispatchEvent(new CustomEvent('cbi-tab-active', { + detail: { tab: pane.getAttribute('data-tab') } + })); + }, this, panes[selected])); this.updateTabs(group); }, diff --git a/modules/luci-base/htdocs/luci-static/resources/validation.js b/modules/luci-base/htdocs/luci-static/resources/validation.js index d47392c239..0d2157bee0 100644 --- a/modules/luci-base/htdocs/luci-static/resources/validation.js +++ b/modules/luci-base/htdocs/luci-static/resources/validation.js @@ -272,18 +272,21 @@ var ValidatorFactory = baseclass.extend({ _('valid IPv6 prefix value (0-128)')); }, - cidr: function() { - return this.assert(this.apply('cidr4') || this.apply('cidr6'), _('valid IPv4 or IPv6 CIDR')); + cidr: function(negative) { + return this.assert(this.apply('cidr4', null, [negative]) || this.apply('cidr6', null, [negative]), + _('valid IPv4 or IPv6 CIDR')); }, - cidr4: function() { - var m = this.value.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d{1,2})$/); - return this.assert(m && this.factory.parseIPv4(m[1]) && this.apply('ip4prefix', m[2]), _('valid IPv4 CIDR')); + cidr4: function(negative) { + var m = this.value.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(-)?(\d{1,2})$/); + return this.assert(m && this.factory.parseIPv4(m[1]) && (negative || !m[2]) && this.apply('ip4prefix', m[3]), + _('valid IPv4 CIDR')); }, - cidr6: function() { - var m = this.value.match(/^([0-9a-fA-F:.]+)\/(\d{1,3})$/); - return this.assert(m && this.factory.parseIPv6(m[1]) && this.apply('ip6prefix', m[2]), _('valid IPv6 CIDR')); + cidr6: function(negative) { + var m = this.value.match(/^([0-9a-fA-F:.]+)\/(-)?(\d{1,3})$/); + return this.assert(m && this.factory.parseIPv6(m[1]) && (negative || !m[2]) && this.apply('ip6prefix', m[3]), + _('valid IPv6 CIDR')); }, ipnet4: function() { @@ -304,18 +307,18 @@ var ValidatorFactory = baseclass.extend({ return this.assert(!(!v6 || v6[0] || v6[1] || v6[2] || v6[3]), _('valid IPv6 host id')); }, - ipmask: function() { - return this.assert(this.apply('ipmask4') || this.apply('ipmask6'), + ipmask: function(negative) { + return this.assert(this.apply('ipmask4', null, [negative]) || this.apply('ipmask6', null, [negative]), _('valid network in address/netmask notation')); }, - ipmask4: function() { - return this.assert(this.apply('cidr4') || this.apply('ipnet4') || this.apply('ip4addr'), + ipmask4: function(negative) { + return this.assert(this.apply('cidr4', null, [negative]) || this.apply('ipnet4') || this.apply('ip4addr'), _('valid IPv4 network')); }, - ipmask6: function() { - return this.assert(this.apply('cidr6') || this.apply('ipnet6') || this.apply('ip6addr'), + ipmask6: function(negative) { + return this.assert(this.apply('cidr6', null, [negative]) || this.apply('ipnet6') || this.apply('ip6addr'), _('valid IPv6 network')); }, |