diff options
Diffstat (limited to 'modules/luci-base/htdocs')
5 files changed, 106 insertions, 46 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index 7dc63ceb5a..46f1ff4825 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -393,6 +393,39 @@ var CBIMap = CBINode.extend({ this.checkDepends(ev, (n || 10) + 1); ui.tabs.updateTabs(ev, this.root); + }, + + isDependencySatisfied: function(depends, config_name, section_id) { + var def = false; + + if (!Array.isArray(depends) || !depends.length) + return true; + + for (var i = 0; i < depends.length; i++) { + var istat = true, + reverse = false; + + for (var dep in depends[i]) { + if (dep == '!reverse') { + reverse = true; + } + else if (dep == '!default') { + def = true; + istat = false; + } + else { + var res = this.lookupOption(dep, section_id, config_name), + val = (res && res[0].isActive(res[1])) ? res[0].formvalue(res[1]) : null; + + istat = (istat && isEqual(val, depends[i][dep])); + } + } + + if (istat ^ reverse) + return true; + } + + return def; } }); @@ -675,37 +708,42 @@ var CBIAbstractValue = CBINode.extend({ }, checkDepends: function(section_id) { - var def = false; + var config_name = this.uciconfig || this.section.uciconfig || this.map.config, + active = this.map.isDependencySatisfied(this.deps, config_name, section_id); - if (!Array.isArray(this.deps) || !this.deps.length) - return true; + if (active) + this.updateDefaultValue(section_id); - for (var i = 0; i < this.deps.length; i++) { - var istat = true, - reverse = false; + return active; + }, - for (var dep in this.deps[i]) { - if (dep == '!reverse') { - reverse = true; - } - else if (dep == '!default') { - def = true; - istat = false; - } - else { - var conf = this.uciconfig || this.section.uciconfig || this.map.config, - res = this.map.lookupOption(dep, section_id, conf), - val = (res && res[0].isActive(res[1])) ? res[0].formvalue(res[1]) : null; + updateDefaultValue: function(section_id) { + if (!L.isObject(this.defaults)) + return; - istat = (istat && isEqual(val, this.deps[i][dep])); - } - } + var config_name = this.uciconfig || this.section.uciconfig || this.map.config, + cfgvalue = L.toArray(this.cfgvalue(section_id))[0], + default_defval = null, satisified_defval = null; - if (istat ^ reverse) - return true; + for (var value in this.defaults) { + if (!this.defaults[value] || this.defaults[value].length == 0) { + default_defval = value; + continue; + } + else if (this.map.isDependencySatisfied(this.defaults[value], config_name, section_id)) { + satisified_defval = value; + break; + } } - return def; + if (satisified_defval == null) + satisified_defval = default_defval; + + var node = this.map.findElement('id', this.cbid(section_id)); + if (node && node.getAttribute('data-changed') != 'true' && satisified_defval != null && cfgvalue == null) + L.dom.callClassMethod(node, 'setValue', satisified_defval); + + this.default = satisified_defval; }, cbid: function(section_id) { @@ -906,8 +944,8 @@ var CBITypedSection = CBIAbstractSection.extend({ sectionEl = E('div', { 'id': 'cbi-%s-%s'.format(config_name, this.sectiontype), 'class': 'cbi-section', - 'data-tab': this.map.tabbed ? this.sectiontype : null, - 'data-tab-title': this.map.tabbed ? this.title || this.sectiontype : null + 'data-tab': (this.map.tabbed && !this.parentoption) ? this.sectiontype : null, + 'data-tab-title': (this.map.tabbed && !this.parentoption) ? this.title || this.sectiontype : null }); if (this.title != null && this.title != '') @@ -975,8 +1013,8 @@ var CBITableSection = CBITypedSection.extend({ sectionEl = E('div', { 'id': 'cbi-%s-%s'.format(config_name, this.sectiontype), 'class': 'cbi-section cbi-tblsection', - 'data-tab': this.map.tabbed ? this.sectiontype : null, - 'data-tab-title': this.map.tabbed ? this.title || this.sectiontype : null + 'data-tab': (this.map.tabbed && !this.parentoption) ? this.sectiontype : null, + 'data-tab-title': (this.map.tabbed && !this.parentoption) ? this.title || this.sectiontype : null }), tableEl = E('div', { 'class': 'table cbi-section-table' @@ -1037,6 +1075,8 @@ var CBITableSection = CBITypedSection.extend({ renderHeaderRows: function(max_cols) { var has_titles = false, has_descriptions = false, + max_cols = isNaN(this.max_cols) ? this.children.length : this.max_cols, + has_more = max_cols < this.children.length, anon_class = (!this.anonymous || this.sectiontitle) ? 'named' : 'anonymous', trEls = E([]); @@ -1171,10 +1211,7 @@ var CBITableSection = CBITypedSection.extend({ E('button', { 'title': btn_title || _('Delete'), 'class': 'cbi-button cbi-button-remove', - 'click': L.ui.createHandlerFn(this, function(sid, ev) { - this.map.data.remove(config_name, sid); - return this.map.save(null, true); - }, section_id) + 'click': L.ui.createHandlerFn(this, 'handleRemove', section_id) }, [ btn_title || _('Delete') ]) ); } @@ -1401,7 +1438,7 @@ var CBIGridSection = CBITableSection.extend({ return E('div', { 'class': 'td cbi-value-field', - 'data-title': (title != '') ? title : opt.option, + 'data-title': (title != '') ? title : null, 'data-description': (descr != '') ? descr : null, 'data-name': opt.option, 'data-type': opt.typename || opt.__name__ @@ -1466,8 +1503,8 @@ var CBINamedSection = CBIAbstractSection.extend({ sectionEl = E('div', { 'id': ucidata ? null : 'cbi-%s-%s'.format(config_name, section_id), 'class': 'cbi-section', - 'data-tab': this.map.tabbed ? this.sectiontype : null, - 'data-tab-title': this.map.tabbed ? this.title || this.sectiontype : null + 'data-tab': (this.map.tabbed && !this.parentoption) ? this.sectiontype : null, + 'data-tab-title': (this.map.tabbed && !this.parentoption) ? this.title || this.sectiontype : null }); if (typeof(this.title) === 'string' && this.title !== '') @@ -1540,9 +1577,10 @@ var CBIValue = CBIAbstractValue.extend({ optionEl; if (in_table) { + var title = this.stripTags(this.title).trim(); optionEl = E('div', { 'class': 'td cbi-value-field', - 'data-title': this.stripTags(this.title).trim(), + 'data-title': (title != '') ? title : null, 'data-description': this.stripTags(this.description).trim(), 'data-name': this.option, 'data-type': this.typename || (this.template ? this.template.replace(/^.+\//, '') : null) || this.__name__ @@ -1822,7 +1860,7 @@ var CBIButtonValue = CBIValue.extend({ E('button', { 'class': 'cbi-button cbi-button-%s'.format(this.inputstyle || 'button'), 'click': L.ui.createHandlerFn(this, this.onclick || function(ev) { - ev.target.previousElementSibling.value = ev.target.value; + ev.currentTarget.parentNode.nextElementSibling.value = value; return this.map.save(); }) }, [ btn_title ]) @@ -1884,6 +1922,7 @@ var CBISectionValue = CBIValue.extend({ throw 'Sub section must be a descendent of CBIAbstractSection'; this.subsection = cbiClass.instantiate(this.varargs(arguments, 4, this.map)); + this.subsection.parentoption = this; }, load: function(section_id) { diff --git a/modules/luci-base/htdocs/luci-static/resources/luci.js b/modules/luci-base/htdocs/luci-static/resources/luci.js index af2b179ce3..4e3c8445a9 100644 --- a/modules/luci-base/htdocs/luci-static/resources/luci.js +++ b/modules/luci-base/htdocs/luci-static/resources/luci.js @@ -399,17 +399,21 @@ }, handleReadyStateChange: function(resolveFn, rejectFn, ev) { - var xhr = this.xhr; + var xhr = this.xhr, + duration = Date.now() - this.start; if (xhr.readyState !== 4) return; if (xhr.status === 0 && xhr.statusText === '') { - rejectFn.call(this, new Error('XHR request aborted by browser')); + if (duration >= this.timeout) + rejectFn.call(this, new Error('XHR request timed out')); + else + rejectFn.call(this, new Error('XHR request aborted by browser')); } else { var response = new Response( - xhr, xhr.responseURL || this.url, Date.now() - this.start); + xhr, xhr.responseURL || this.url, duration); Promise.all(Request.interceptors.map(function(fn) { return fn(response) })) .then(resolveFn.bind(this, response)) @@ -819,9 +823,14 @@ }, probeSystemFeatures: function() { + var sessionid = classes.rpc.getSessionID(); + if (sysFeatures == null) { try { - sysFeatures = JSON.parse(window.sessionStorage.getItem('sysFeatures')); + var data = JSON.parse(window.sessionStorage.getItem('sysFeatures')); + + if (this.isObject(data) && this.isObject(data[sessionid])) + sysFeatures = data[sessionid]; } catch (e) {} } @@ -833,7 +842,10 @@ expect: { '': {} } })().then(function(features) { try { - window.sessionStorage.setItem('sysFeatures', JSON.stringify(features)); + var data = {}; + data[sessionid] = features; + + window.sessionStorage.setItem('sysFeatures', JSON.stringify(data)); } catch (e) {} diff --git a/modules/luci-base/htdocs/luci-static/resources/network.js b/modules/luci-base/htdocs/luci-static/resources/network.js index d0282ad01f..a85e2414b6 100644 --- a/modules/luci-base/htdocs/luci-static/resources/network.js +++ b/modules/luci-base/htdocs/luci-static/resources/network.js @@ -78,6 +78,7 @@ var callIwinfoScan = rpc.declare({ object: 'iwinfo', method: 'scan', params: [ 'device' ], + nobatch: true, expect: { results: [] } }); @@ -821,7 +822,9 @@ Network = L.Class.extend({ }, deleteNetwork: function(name) { - return Promise.all([ L.require('firewall').catch(function() { return null }), initNetworkState() ]).then(function() { + var requireFirewall = Promise.resolve(L.require('firewall')).catch(function() {}); + + return Promise.all([ requireFirewall, initNetworkState() ]).then(function() { var uciInterface = uci.get('network', name); if (uciInterface != null && uciInterface['.type'] == 'interface') { diff --git a/modules/luci-base/htdocs/luci-static/resources/rpc.js b/modules/luci-base/htdocs/luci-static/resources/rpc.js index 87850b8564..9c74bfdaf0 100644 --- a/modules/luci-base/htdocs/luci-static/resources/rpc.js +++ b/modules/luci-base/htdocs/luci-static/resources/rpc.js @@ -6,7 +6,7 @@ var rpcRequestID = 1, rpcInterceptorFns = []; return L.Class.extend({ - call: function(req, cb) { + call: function(req, cb, nobatch) { var q = ''; if (Array.isArray(req)) { @@ -26,7 +26,8 @@ return L.Class.extend({ } return L.Request.post(rpcBaseURL + q, req, { - timeout: (L.env.rpctimeout || 5) * 1000, + timeout: (L.env.rpctimeout || 20) * 1000, + nobatch: nobatch, credentials: true }).then(cb, cb); }, @@ -167,7 +168,7 @@ return L.Class.extend({ }; /* call rpc */ - rpc.call(msg, rpc.parseCallReply.bind(rpc, req)); + rpc.call(msg, rpc.parseCallReply.bind(rpc, req), options.nobatch); }); }, this, this, options); }, diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index c0b57528fb..99e1548a43 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -70,6 +70,11 @@ var UIElement = L.Class.extend({ }, setChangeEvents: function(targetNode /*, ... */) { + var tag_changed = L.bind(function(ev) { this.setAttribute('data-changed', true) }, this.node); + + for (var i = 1; i < arguments.length; i++) + targetNode.addEventListener(arguments[i], tag_changed); + this.registerEvents(targetNode, 'widget-change', this.varargs(arguments, 1)); } }); |