From cdce600aaec66f762f18d608c74cbf3abcafe1c7 Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Tue, 1 Apr 2025 16:43:05 +0200 Subject: [PATCH] luci-mod-network: give wireless.js ES2016 treatment and refactor Signed-off-by: Paul Donald --- .../resources/view/network/wireless.js | 798 +++++++++--------- 1 file changed, 381 insertions(+), 417 deletions(-) diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js index e76b2b7111..8bdb62a46e 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js @@ -11,19 +11,13 @@ 'require firewall'; 'require tools.widgets as widgets'; -var isReadonlyView = !L.hasViewPermission(); +const isReadonlyView = !L.hasViewPermission(); function count_changes(section_id) { - var changes = ui.changes.changes, n = 0; + const changes = ui.changes.changes?.wireless; + if (!Array.isArray(changes)) return 0; - if (!L.isObject(changes)) - return n; - - if (Array.isArray(changes.wireless)) - for (var i = 0; i < changes.wireless.length; i++) - n += (changes.wireless[i][1] == section_id); - - return n; + return changes.reduce((count, [, id]) => count + (id === section_id), 0); } function render_radio_badge(radioDev) { @@ -35,32 +29,28 @@ function render_radio_badge(radioDev) { } function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode) { - var icon, title, value; - - if (signalPercent < 0) - icon = L.resource('icons/signal-none.png'); - else if (signalPercent == 0) - icon = L.resource('icons/signal-0.png'); - else if (signalPercent < 25) - icon = L.resource('icons/signal-0-25.png'); - else if (signalPercent < 50) - icon = L.resource('icons/signal-25-50.png'); - else if (signalPercent < 75) - icon = L.resource('icons/signal-50-75.png'); - else - icon = L.resource('icons/signal-75-100.png'); - - if (signalValue != null && signalValue != 0) { - if (noiseValue != null && noiseValue != 0) { - value = '%d/%d\xa0%s'.format(signalValue, noiseValue, _('dBm')); - title = '%s: %d %s / %s: %d %s / %s %d'.format( - _('Signal'), signalValue, _('dBm'), - _('Noise'), noiseValue, _('dBm'), - _('SNR'), signalValue - noiseValue); + let icon = L.resource('icons/signal-75-100.png'), title, value; + + switch(true) { + case(signalPercent < 0): icon = L.resource('icons/signal-none.png'); break; + case(signalPercent == 0): icon = L.resource('icons/signal-0.png'); break; + case(signalPercent < 25): icon = L.resource('icons/signal-0-25.png'); break; + case(signalPercent < 50): icon = L.resource('icons/signal-25-50.png'); break; + case(signalPercent < 75): icon = L.resource('icons/signal-50-75.png'); break; + } + + if (signalValue) { + if (noiseValue) { + value = `${signalValue}/${noiseValue}\xa0${_('dBm')}`; + title = [ + `${_('Signal')}: ${signalValue} ${_('dBm')}`, + `${_('Noise')}: ${noiseValue} ${_('dBm')}`, + `${_('SNR')}: ${signalValue - noiseValue} ${_('dBm')}` + ].filter(Boolean).join(' / '); } else { - value = '%d\xa0%s'.format(signalValue, _('dBm')); - title = '%s: %d %s'.format(_('Signal'), signalValue, _('dBm')); + value = `${signalValue}\xa0${_('dBm')}`; + title = `${_('Signal')} ${signalValue} ${_('dBm')}`; } } else if (signalPercent > -1) { @@ -79,12 +69,12 @@ function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode) title = _('No RX signal'); } - if (noiseValue != null && noiseValue != 0) { - value = '---/%d\xa0%s'.format(noiseValue, _('dBm')); - title = '%s / %s: %d %s'.format(title, _('Noise'), noiseValue, _('dBm')); + if (noiseValue) { + value = `---/${noiseValue}\xa0${_('dBm')}`; + title = `${title} / ${_('Noise')}: ${noiseValue} ${_('dBm')}`; } else { - value = '---\xa0%s'.format(_('dBm')); + value = `---\xa0${_('dBm')}`; } } else { @@ -113,20 +103,20 @@ function render_network_badge(radioNet) { } function render_radio_status(radioDev, wifiNets) { - var name = radioDev.getI18n().replace(/ Wireless Controller .+$/, ''), - node = E('div', [ E('big', {}, E('strong', {}, name)), E('div') ]), - channel, frequency, bitrate; - - for (var i = 0; i < wifiNets.length; i++) { - channel = channel || wifiNets[i].getChannel(); - frequency = frequency || wifiNets[i].getFrequency(); - bitrate = bitrate || wifiNets[i].getBitRate(); - } + const name = radioDev.getI18n().replace(/ Wireless Controller .+$/, ''); + const node = E('div', [ E('big', {}, E('strong', {}, name)), E('div') ]); + let channel, frequency, bitrate; + + wifiNets.forEach(wifiNet => { + channel = channel ?? wifiNet.getChannel(); + frequency = frequency ?? wifiNet.getFrequency(); + bitrate = bitrate ?? wifiNet.getBitRate(); + }) if (radioDev.isUp()) L.itemlist(node.lastElementChild, [ - _('Channel'), '%s (%s %s)'.format(channel || '?', frequency || '?', _('GHz')), - _('Bitrate'), '%s %s'.format(bitrate || '?', _('Mbit/s')) + _('Channel'), `${channel || '?'} (${frequency || '?'} ${_('GHz')})`, + _('Bitrate'), `${bitrate || '?'} ${_('Mbit/s')}` ], ' | '); else node.lastElementChild.appendChild(E('em', _('Device is not active'))); @@ -135,14 +125,14 @@ function render_radio_status(radioDev, wifiNets) { } function render_network_status(radioNet) { - var mode = radioNet.getActiveMode(), - bssid = radioNet.getActiveBSSID(), - channel = radioNet.getChannel(), - disabled = (radioNet.get('disabled') == '1' || uci.get('wireless', radioNet.getWifiDeviceName(), 'disabled') == '1'), - is_assoc = (bssid && bssid != '00:00:00:00:00:00' && channel && mode != 'Unknown' && !disabled), - is_mesh = (radioNet.getMode() == 'mesh'), - changecount = count_changes(radioNet.getName()), - status_text = null; + const mode = radioNet.getActiveMode(); + const bssid = radioNet.getActiveBSSID(); + const channel = radioNet.getChannel(); + const disabled = (radioNet.get('disabled') == '1' ?? uci.get('wireless', radioNet.getWifiDeviceName(), 'disabled') == '1'); + const is_assoc = (bssid && bssid != '00:00:00:00:00:00' && channel && mode != 'Unknown' && !disabled); + const is_mesh = (radioNet.getMode() == 'mesh'); + const changecount = count_changes(radioNet.getName()); + let status_text = null; if (changecount) status_text = E('a', { @@ -153,21 +143,21 @@ function render_network_status(radioNet) { status_text = E('em', disabled ? _('Wireless is disabled') : _('Wireless is not associated')); return L.itemlist(E('div'), [ - is_mesh ? _('Mesh ID') : _('SSID'), (is_mesh ? radioNet.getMeshID() : radioNet.getSSID()) || '?', + is_mesh ? _('Mesh ID') : _('SSID'), (is_mesh ? radioNet.getMeshID() : radioNet.getSSID()) ?? '?', _('Mode'), mode, _('BSSID'), (!changecount && is_assoc) ? bssid : null, - _('Encryption'), (!changecount && is_assoc) ? radioNet.getActiveEncryption() || _('None') : null, + _('Encryption'), (!changecount && is_assoc) ? radioNet.getActiveEncryption() ?? _('None') : null, null, status_text ], [ ' | ', E('br') ]); } function render_modal_status(node, radioNet) { - var mode = radioNet.getActiveMode(), - noise = radioNet.getNoise(), - bssid = radioNet.getActiveBSSID(), - channel = radioNet.getChannel(), - disabled = (radioNet.get('disabled') == '1'), - is_assoc = (bssid && bssid != '00:00:00:00:00:00' && channel && mode != 'Unknown' && !disabled); + const mode = radioNet.getActiveMode(); + const noise = radioNet.getNoise(); + const bssid = radioNet.getActiveBSSID(); + const channel = radioNet.getChannel(); + const disabled = (radioNet.get('disabled') == '1'); + const is_assoc = (bssid && bssid != '00:00:00:00:00:00' && channel && mode != 'Unknown' && !disabled); if (node == null) node = E('span', { 'class': 'ifacebadge large', 'data-network': radioNet.getName() }, [ E('small'), E('span') ]); @@ -178,14 +168,14 @@ function render_modal_status(node, radioNet) { L.itemlist(node.lastElementChild, [ _('Mode'), mode, - _('SSID'), radioNet.getSSID() || '?', + _('SSID'), radioNet.getSSID() ?? '?', _('BSSID'), is_assoc ? bssid : null, - _('Encryption'), is_assoc ? radioNet.getActiveEncryption() || _('None') : null, - _('Channel'), is_assoc ? '%d (%.3f %s)'.format(radioNet.getChannel(), radioNet.getFrequency() || 0, _('GHz')) : null, - _('Tx-Power'), is_assoc ? '%d %s'.format(radioNet.getTXPower(), _('dBm')) : null, - _('Signal'), is_assoc ? '%d %s'.format(radioNet.getSignal(), _('dBm')) : null, - _('Noise'), (is_assoc && noise != null) ? '%d %s'.format(noise, _('dBm')) : null, - _('Bitrate'), is_assoc ? '%.1f %s'.format(radioNet.getBitRate() || 0, _('Mbit/s')) : null, + _('Encryption'), is_assoc ? radioNet.getActiveEncryption() ?? _('None') : null, + _('Channel'), is_assoc ? `${radioNet.getChannel()} (${radioNet.getFrequency() ?? 0} ${_('GHz')})` : null, + _('Tx-Power'), is_assoc ? `${radioNet.getTXPower()} ${_('dBm')}` : null, + _('Signal'), is_assoc ? `${radioNet.getSignal()} ${_('dBm')}` : null, + _('Noise'), (is_assoc && noise != null) ? `${noise} ${_('dBm')}` : null, + _('Bitrate'), is_assoc ? `${radioNet.getBitRate() ?? 0} ${_('Mbit/s')}` : null, _('Country'), is_assoc ? radioNet.getCountryCode() : null ], [ ' | ', E('br'), E('br'), E('br'), E('br'), E('br'), ' | ', E('br'), ' | ' ]); @@ -196,43 +186,48 @@ function render_modal_status(node, radioNet) { } function format_wifirate(rate) { - var s = '%.1f\xa0%s, %d\xa0%s'.format(rate.rate / 1000, _('Mbit/s'), rate.mhz, _('MHz')), - ht = rate.ht, vht = rate.vht, - mhz = rate.mhz, nss = rate.nss, - mcs = rate.mcs, sgi = rate.short_gi, - he = rate.he, he_gi = rate.he_gi, - he_dcm = rate.he_dcm, - eht = rate?.eht ?? false, eht_gi = rate?.eht_gi ?? 0, - eht_dcm = rate?.eht_dcm ?? 0; - - if (ht || vht) { - if (vht) s += ', VHT-MCS\xa0%d'.format(mcs); - if (nss) s += ', VHT-NSS\xa0%d'.format(nss); - if (ht) s += ', MCS\xa0%s'.format(mcs); - if (sgi) s += ', ' + _('Short GI').replace(/ /g, '\xa0'); - } - - if (he) { - s += ', HE-MCS\xa0%d'.format(mcs); - if (nss) s += ', HE-NSS\xa0%d'.format(nss); - if (he_gi) s += ', HE-GI\xa0%d'.format(he_gi); - if (he_dcm) s += ', HE-DCM\xa0%d'.format(he_dcm); - } - - if (eht) { - s += ', EHT-MCS\xa0%d'.format(mcs); - if (nss) s += ', EHT-NSS\xa0%d'.format(nss); - if (eht_gi) s += ', EHT-GI\xa0%d'.format(eht_gi); - if (eht_dcm) s += ', EHT-DCM\xa0%d'.format(eht_dcm); - } + let s = `${rate.rate / 1000}\xa0${_('Mbit/s')}, ${rate.mhz}\xa0${_('MHz')}`; + const ht = rate.ht; + const vht = rate.vht; + const mhz = rate.mhz; + const nss = rate.nss; + const mcs = rate.mcs; + const sgi = rate.short_gi; + const he = rate.he; + const he_gi = rate.he_gi; + const he_dcm = rate.he_dcm; + const eht = rate?.eht ?? false; + const eht_gi = rate?.eht_gi ?? 0; + const eht_dcm = rate?.eht_dcm ?? 0; + + if (ht ?? vht) s += [ + vht && `, VHT-MCS\xa0${$mcs}`, + nss && `VHT-NSS\xa0${nss}`, + ht && `MCS\xa0${mcs}`, + sgi && _('Short GI').replace(/ /g, '\xa0') + ].filter(Boolean).join(', '); + + if (he) s += [ + `, HE-MCS\xa0${mcs}`, + nss && `HE-NSS\xa0${nss}`, + he_gi && `HE-GI\xa0${he_gi}`, + he_dcm && `HE-DCM\xa0${he_dcm}` + ].filter(Boolean).join(', '); + + if (eht) s += [ + `, EHT-MCS\xa0${mcs}`, + nss && `EHT-NSS\xa0${nss}`, + he_gi && `EHT-GI\xa0${eht_gi}`, + he_dcm && `EHT-DCM\xa0${eht_dcm}` + ].filter(Boolean).join(', '); return s; } function radio_restart(id, ev) { - var row = document.querySelector('.cbi-section-table-row[data-sid="%s"]'.format(id)), - dsc = row.querySelector('[data-name="_stat"] > div'), - btn = row.querySelector('.cbi-section-actions button'); + const row = document.querySelector('.cbi-section-table-row[data-sid="%s"]'.format(id)); + const dsc = row.querySelector('[data-name="_stat"] > div'); + const btn = row.querySelector('.cbi-section-actions button'); btn.blur(); btn.classList.add('spinning'); @@ -243,8 +238,8 @@ function radio_restart(id, ev) { } function network_updown(id, map, ev) { - var radio = uci.get('wireless', id, 'device'), - disabled = (uci.get('wireless', id, 'disabled') == '1') || + const radio = uci.get('wireless', id, 'device'); + const disabled = (uci.get('wireless', id, 'disabled') == '1') || (uci.get('wireless', radio, 'disabled') == '1'); if (disabled) { @@ -254,15 +249,13 @@ function network_updown(id, map, ev) { else { uci.set('wireless', id, 'disabled', '1'); - var all_networks_disabled = true, - wifi_ifaces = uci.sections('wireless', 'wifi-iface'); + let all_networks_disabled = true; + const wifi_ifaces = uci.sections('wireless', 'wifi-iface'); - for (var i = 0; i < wifi_ifaces.length; i++) { - if (wifi_ifaces[i].device == radio && wifi_ifaces[i].disabled != '1') { + wifi_ifaces.forEach(wifi_iface => { + if (wifi_iface.device == radio && wifi_iface.disabled != '1') all_networks_disabled = false; - break; - } - } + }) if (all_networks_disabled) uci.set('wireless', radio, 'disabled', '1'); @@ -274,7 +267,7 @@ function network_updown(id, map, ev) { } function next_free_sid(offset) { - var sid = 'wifinet' + offset; + let sid = 'wifinet' + offset; while (uci.get('wireless', sid)) sid = 'wifinet' + (++offset); @@ -283,28 +276,15 @@ function next_free_sid(offset) { } function add_dependency_permutations(o, deps) { - var res = null; - - for (var key in deps) { - if (!deps.hasOwnProperty(key) || !Array.isArray(deps[key])) - continue; + let res = [{}]; - var list = deps[key], - tmp = []; + Object.entries(deps).forEach(([key, list]) => { + if (!Array.isArray(list)) return; - for (var j = 0; j < list.length; j++) { - for (var k = 0; k < (res ? res.length : 1); k++) { - var item = (res ? Object.assign({}, res[k]) : {}); - item[key] = list[j]; - tmp.push(item); - } - } - - res = tmp; - } + res = list.flatMap(value => res.map(item => ({ ...item, [key]: value }))); + }); - for (var i = 0; i < (res ? res.length : 0); i++) - o.depends(res[i]); + res.forEach(dep => o.depends(dep)); } // Define a class CBIWifiFrequencyValue that extends form.Value @@ -329,30 +309,28 @@ var CBIWifiFrequencyValue = form.Value.extend({ '6g': L.hasSystemFeature('hostapd', 'acs') ? [ 'auto', 'auto', { available: true } ] : [], '60g': [] }; + const wifidevs = data[0]; + const freqlist = data[1]; - for (var i = 0; i < data[1].length; i++) { - if (!data[1][i].band) - continue; + freqlist.forEach(freq => { + if (!freq.band) + return; - var band = '%dg'.format(data[1][i].band), - available = true; - - - if (data[1][i].restricted && data[1][i].no_ir) - available = false; + const band = '%dg'.format(freq.band); + const available = (freq.restricted && freq.no_ir) ? false: true; this.channels[band].push( - data[1][i].channel, - '%d (%d Mhz)'.format(data[1][i].channel, data[1][i].mhz), + freq.channel, + '%d (%d Mhz)'.format(freq.channel, freq.mhz), { available: available, - no_outdoor: data[1][i].no_outdoor + no_outdoor: freq.no_outdoor } ); - } + }); - var hwmodelist = L.toArray(data[0] ? data[0].getHWModes() : null) + const hwmodelist = L.toArray(wifidevs ? wifidevs.getHWModes() : null) .reduce(function(o, v) { o[v] = true; return o }, {}); // Define supported modes @@ -365,7 +343,7 @@ var CBIWifiFrequencyValue = form.Value.extend({ ]; // Create a list of HT modes based on device capabilities - var htmodelist = L.toArray(data[0] ? data[0].getHTModes() : null) + const htmodelist = L.toArray(wifidevs ? wifidevs.getHTModes() : null) .reduce(function(o, v) { o[v] = true; return o }, {}); this.htmodes = { @@ -429,15 +407,13 @@ var CBIWifiFrequencyValue = form.Value.extend({ if (sel.vals) sel.vals.selected = sel.selectedIndex; - while (sel.options[0]) - sel.remove(0); + sel.options.length = 0; - for (var i = 0; vals && i < vals.length; i += 3) - if (vals[i+2] && vals[i+2].available) - sel.add(E('option', { value: vals[i+0] }, [ vals[i+1] ])); + for (let i = 0; vals && i < vals.length; i += 3) + if (vals[i+2]?.available) + sel.add(E('option', { value: vals[i] }, [ vals[i+1] ])); - if (vals && !isNaN(vals.selected)) - sel.selectedIndex = vals.selected; + if (Number.isInteger(vals?.selected)) sel.selectedIndex = vals.selected; sel.parentNode.style.display = (sel.options.length <= 1) ? 'none' : ''; sel.vals = vals; @@ -449,15 +425,15 @@ var CBIWifiFrequencyValue = form.Value.extend({ }, toggleWifiHTMode: function(elem) { - var mode = elem.querySelector('.mode'); - var bwdt = elem.querySelector('.htmode'); + const mode = elem.querySelector('.mode'); + const bwdt = elem.querySelector('.htmode'); this.setValues(bwdt, this.htmodes[mode.value]); }, toggleWifiBand: function(elem) { - var mode = elem.querySelector('.mode'); - var band = elem.querySelector('.band'); + const mode = elem.querySelector('.mode'); + const band = elem.querySelector('.band'); this.setValues(band, this.bands[mode.value]); this.toggleWifiChannel(elem); @@ -466,25 +442,21 @@ var CBIWifiFrequencyValue = form.Value.extend({ }, checkWifiChannelRestriction: function(elem) { - var band = elem.querySelector('.band'), - chan = elem.querySelector('.channel'), - restricted_chan = elem.querySelector('.restricted_channel'), - channels = this.channels[band.value], - no_outdoor; + const band = elem.querySelector('.band'); + const chan = elem.querySelector('.channel'); + const restricted_chan = elem.querySelector('.restricted_channel'); + const channels = this.channels[band.value]; if (chan.selectedIndex < 0) return; - no_outdoor = channels[(chan.selectedIndex*3)+2].no_outdoor; - if (no_outdoor) - restricted_chan.style.display = ''; - else - restricted_chan.style.display = 'none'; + const no_outdoor = channels[(chan.selectedIndex*3)+2].no_outdoor; + restricted_chan.style.display = no_outdoor ? '': 'none'; }, toggleWifiChannel: function(elem) { - var band = elem.querySelector('.band'); - var chan = elem.querySelector('.channel'); + const band = elem.querySelector('.band'); + const chan = elem.querySelector('.channel'); this.setValues(chan, this.channels[band.value]); @@ -493,14 +465,14 @@ var CBIWifiFrequencyValue = form.Value.extend({ }, setInitialValues: function(section_id, elem) { - var mode = elem.querySelector('.mode'), - band = elem.querySelector('.band'), - chan = elem.querySelector('.channel'), - bwdt = elem.querySelector('.htmode'), - htval = uci.get('wireless', section_id, 'htmode'), - hwval = uci.get('wireless', section_id, 'hwmode'), - chval = uci.get('wireless', section_id, 'channel'), - bandval = uci.get('wireless', section_id, 'band'); + const mode = elem.querySelector('.mode'); + const band = elem.querySelector('.band'); + const chan = elem.querySelector('.channel'); + const bwdt = elem.querySelector('.htmode'); + const htval = uci.get('wireless', section_id, 'htmode'); + const hwval = uci.get('wireless', section_id, 'hwmode'); + const chval = uci.get('wireless', section_id, 'channel'); + const bandval = uci.get('wireless', section_id, 'band'); this.setValues(mode, this.modes); @@ -521,10 +493,7 @@ var CBIWifiFrequencyValue = form.Value.extend({ if (hwval != null) { this.useBandOption = false; - if (/a/.test(hwval)) - band.value = '5g'; - else - band.value = '2g'; + band.value = /a/.test(hwval) ? '5g': '2g'; } else { this.useBandOption = true; @@ -535,7 +504,7 @@ var CBIWifiFrequencyValue = form.Value.extend({ this.toggleWifiBand(elem); bwdt.value = htval; - chan.value = chval || (chan.options[0] ? chan.options[0].value : 'auto'); + chan.value = chval ?? (chan.options[0] ? chan.options[0].value : 'auto'); this.checkWifiChannelRestriction(elem); @@ -543,7 +512,7 @@ var CBIWifiFrequencyValue = form.Value.extend({ }, renderWidget: function(section_id, option_index, cfgvalue) { - var elem = E('div'); + const elem = E('div'); dom.content(elem, [ E('div', { 'class' : 'restricted_channel', 'style': 'display:none'}, [ @@ -600,7 +569,7 @@ var CBIWifiFrequencyValue = form.Value.extend({ }, formvalue: function(section_id) { - var node = this.map.findElement('data-field', this.cbid(section_id)); + const node = this.map.findElement('data-field', this.cbid(section_id)); return [ node.querySelector('.htmode').value, @@ -612,9 +581,8 @@ var CBIWifiFrequencyValue = form.Value.extend({ write: function(section_id, value) { uci.set('wireless', section_id, 'htmode', value[0] || null); - if (this.useBandOption) - uci.set('wireless', section_id, 'band', value[1]); - else + this.useBandOption ? + uci.set('wireless', section_id, 'band', value[1]) : uci.set('wireless', section_id, 'hwmode', (value[1] == '2g') ? '11g' : '11a'); uci.set('wireless', section_id, 'channel', value[2]); @@ -636,21 +604,22 @@ var CBIWifiTxPowerValue = form.ListValue.extend({ this.value('', _('driver default')); - for (var i = 0; i < pwrlist.length; i++) - this.value(pwrlist[i].dbm, '%d dBm (%d mW)'.format(pwrlist[i].dbm, pwrlist[i].mw)); + for (let p of pwrlist) + this.value(p.dbm, `${p.dbm} dBm (${p.mw} mW)`); return form.ListValue.prototype.load.apply(this, [section_id]); }, this)); }, renderWidget: function(section_id, option_index, cfgvalue) { - var widget = form.ListValue.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]); - widget.firstElementChild.style.width = 'auto'; + const widget = form.ListValue.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]); + + widget.firstElementChild.style.width = 'auto'; dom.append(widget, E('span', [ ' - ', _('Current power'), ': ', - E('span', [ this.powerval != null ? '%d dBm'.format(this.powerval) : E('em', _('unknown')) ]), - this.poweroff ? ' + %d dB offset = %s dBm'.format(this.poweroff, this.powerval != null ? this.powerval + this.poweroff : '?') : '' + E('span', [ this.powerval != null ? `${this.powerval} dBm` : E('em', _('unknown')) ]), + this.poweroff ? ` + ${this.poweroff} dB offset = ${this.powerval != null ? this.powerval + this.poweroff : '?'} dBm` : '' ])); return widget; @@ -670,8 +639,8 @@ var CBIWifiCountryValue = form.Value.extend({ if (Array.isArray(countrylist) && countrylist.length > 0) { this.value('', _('driver default')); - for (var i = 0; i < countrylist.length; i++) - this.value(countrylist[i].iso3166, '%s - %s'.format(countrylist[i].iso3166, countrylist[i].country)); + for (let c of countrylist) + this.value(c.iso3166, `${c.iso3166} - ${c.country}`); } return form.Value.prototype.load.apply(this, [section_id]); @@ -686,23 +655,24 @@ var CBIWifiCountryValue = form.Value.extend({ }, renderWidget: function(section_id, option_index, cfgvalue) { - var typeClass = (this.keylist && this.keylist.length) ? form.ListValue : form.Value; + const typeClass = (this.keylist && this.keylist.length) ? form.ListValue : form.Value; return typeClass.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]); } }); return view.extend({ poll_status: function(map, data) { - var rows = map.querySelectorAll('.cbi-section-table-row[data-sid]'); - - for (var i = 0; i < rows.length; i++) { - var section_id = rows[i].getAttribute('data-sid'), - radioDev = data[1].filter(function(d) { return d.getName() == section_id })[0], - radioNet = data[2].filter(function(n) { return n.getName() == section_id })[0], - badge = rows[i].querySelector('[data-name="_badge"] > div'), - stat = rows[i].querySelector('[data-name="_stat"]'), - btns = rows[i].querySelectorAll('.cbi-section-actions button'), - busy = btns[0].classList.contains('spinning') || btns[1].classList.contains('spinning') || btns[2].classList.contains('spinning'); + const rows = map.querySelectorAll('.cbi-section-table-row[data-sid]'); + let stat; + + rows.forEach(row => { + const section_id = row.getAttribute('data-sid'); + const radioDev = data[1].filter(function(d) { return d.getName() == section_id })[0]; + const radioNet = data[2].filter(function(n) { return n.getName() == section_id })[0]; + const badge = row.querySelector('[data-name="_badge"] > div'); + const stat = row.querySelector('[data-name="_stat"]'); + const btns = row.querySelectorAll('.cbi-section-actions button'); + const busy = btns[0].classList.contains('spinning') || btns[1].classList.contains('spinning') || btns[2].classList.contains('spinning'); if (radioDev) { dom.content(badge, render_radio_badge(radioDev)); @@ -719,28 +689,30 @@ return view.extend({ btns[0].disabled = isReadonlyView || busy; btns[1].disabled = (isReadonlyView && radioDev) || busy; btns[2].disabled = isReadonlyView || busy; - } + }); - var table = document.querySelector('#wifi_assoclist_table'), - hosts = data[0], - trows = []; + const table = document.querySelector('#wifi_assoclist_table'); + const hosts = data[0]; + let trows = []; + const radios = data[3]; + const zones = data[4] - for (var i = 0; i < data[3].length; i++) { - var bss = data[3][i], - name = hosts.getHostnameByMACAddr(bss.mac), - ipv4 = hosts.getIPAddrByMACAddr(bss.mac), - ipv6 = hosts.getIP6AddrByMACAddr(bss.mac); + radios.forEach(zone => { + const bss = zone; + const name = hosts.getHostnameByMACAddr(bss.mac); + const ipv4 = hosts.getIPAddrByMACAddr(bss.mac); + const ipv6 = hosts.getIP6AddrByMACAddr(bss.mac); - var hint; + let hint; if (name && ipv4 && ipv6) - hint = '%s (%s, %s)'.format(name, ipv4, ipv6); - else if (name && (ipv4 || ipv6)) - hint = '%s (%s)'.format(name, ipv4 || ipv6); + hint = `${name} (${ipv4}, ${ipv6})`; + else if (name && (ipv4 ?? ipv6)) + hint = `${name} (${ipv4 || ipv6})`; else hint = name || ipv4 || ipv6 || '?'; - var row = [ + let row = [ E('span', { 'class': 'ifacebadge', 'data-ifname': bss.network.getIfname(), @@ -751,8 +723,8 @@ return view.extend({ 'title': bss.radio.getI18n() }), E('span', [ - ' %s '.format(bss.network.getShortName()), - E('small', '(%s)'.format(bss.network.getIfname())) + ` ${bss.network.getShortName()} `, + E('small', `(${bss.network.getIfname()})`) ]) ]), bss.mac, @@ -765,11 +737,10 @@ return view.extend({ ]) ]; - var zones = data[4]; if (bss.vlan) { - var desc = bss.vlan.getI18n(); - var vlan_network = bss.vlan.getNetwork(); - var vlan_zone; + const desc = bss.vlan.getI18n(); + const vlan_network = bss.vlan.getNetwork(); + let vlan_zone; if (vlan_network && zones) for (let zone of zones) @@ -806,14 +777,14 @@ return view.extend({ } trows.push(row); - } + }) cbi_update_table(table, trows, E('em', _('No information available'))); - var stat = document.querySelector('.cbi-modal [data-name="_wifistat_modal"] .ifacebadge.large'); + const status = document.querySelector('.cbi-modal [data-name="_wifistat_modal"] .ifacebadge.large'); - if (stat) - render_modal_status(stat, data[2].filter(function(n) { return n.getName() == stat.getAttribute('data-network') })[0]); + if (status) + render_modal_status(status, data[2].filter(function(n) { return n.getName() == status.getAttribute('data-network') })[0]); return network.flushCache(); }, @@ -828,13 +799,7 @@ return view.extend({ }, checkAnonymousSections: function() { - var wifiIfaces = uci.sections('wireless', 'wifi-iface'); - - for (var i = 0; i < wifiIfaces.length; i++) - if (wifiIfaces[i]['.anonymous']) - return true; - - return false; + return uci.sections('wireless', 'wifi-iface').some(iface => iface['.anonymous']); }, callUciRename: rpc.declare({ @@ -851,19 +816,17 @@ return view.extend({ }, handleMigration: function(ev) { - var wifiIfaces = uci.sections('wireless', 'wifi-iface'), - id_offset = 0, - tasks = []; - - for (var i = 0; i < wifiIfaces.length; i++) { - if (!wifiIfaces[i]['.anonymous']) - continue; - - var new_name = next_free_sid(id_offset); - - tasks.push(this.callUciRename('wireless', wifiIfaces[i]['.name'], new_name)); - id_offset = +new_name.substring(7) + 1; - } + const wifiIfaces = uci.sections('wireless', 'wifi-iface'); + let id_offset = 0; + const tasks = []; + + wifiIfaces.forEach((iface) => { + if (iface['.anonymous']) { + const new_name = next_free_sid(id_offset); + tasks.push(this.callUciRename('wireless', iface['.name'], new_name)); + id_offset = parseInt(new_name.substring(7), 10) + 1; + } + }); return Promise.all(tasks) .then(L.bind(ui.changes.init, ui.changes)) @@ -883,7 +846,7 @@ return view.extend({ }, renderOverview: function(zones) { - var m, s, o; + let m, s, o; m = new form.Map('wireless'); m.chain('network'); @@ -899,45 +862,48 @@ return view.extend({ return a.getName() > b.getName(); }); - var tasks = []; + const tasks = []; - for (var i = 0; i < radios.length; i++) - tasks.push(radios[i].getWifiNetworks()); + radios.forEach(radio => { + tasks.push(radio.getWifiNetworks()); + }) return Promise.all(tasks); }, this)).then(L.bind(function(data) { this.wifis = []; - for (var i = 0; i < data.length; i++) - this.wifis.push.apply(this.wifis, data[i]); + data.forEach(d => { + this.wifis.push.apply(this.wifis, d); + }) }, this)); }; s.cfgsections = function() { - var rv = []; + const rv = []; - for (var i = 0; i < this.radios.length; i++) { - rv.push(this.radios[i].getName()); + this.radios.forEach(radio => { + rv.push(radio.getName()); - for (var j = 0; j < this.wifis.length; j++) - if (this.wifis[j].getWifiDeviceName() == this.radios[i].getName()) - rv.push(this.wifis[j].getName()); - } + this.wifis.forEach(wifi => { + if (wifi.getWifiDeviceName() == radio.getName()) + rv.push(wifi.getName()); + }); + }); return rv; }; s.modaltitle = function(section_id) { - var radioNet = this.wifis.filter(function(w) { return w.getName() == section_id})[0]; + const radioNet = this.wifis.filter(function(w) { return w.getName() == section_id})[0]; return radioNet ? radioNet.getI18n() : _('Edit wireless network'); }; s.lookupRadioOrNetwork = function(section_id) { - var radioDev = this.radios.filter(function(r) { return r.getName() == section_id })[0]; + const radioDev = this.radios.filter(function(r) { return r.getName() == section_id })[0]; if (radioDev) return radioDev; - var radioNet = this.wifis.filter(function(w) { return w.getName() == section_id })[0]; + const radioNet = this.wifis.filter(function(w) { return w.getName() == section_id })[0]; if (radioNet) return radioNet; @@ -945,7 +911,8 @@ return view.extend({ }; s.renderRowActions = function(section_id) { - var inst = this.lookupRadioOrNetwork(section_id), btns; + const inst = this.lookupRadioOrNetwork(section_id); + let btns; if (inst.getWifiNetworks) { btns = [ @@ -967,7 +934,7 @@ return view.extend({ ]; } else { - var isDisabled = (inst.get('disabled') == '1' || + const isDisabled = (inst.get('disabled') == '1' || uci.get('wireless', inst.getWifiDeviceName(), 'disabled') == '1'); btns = [ @@ -994,8 +961,8 @@ return view.extend({ s.addModalOptions = function(s) { return network.getWifiNetwork(s.section).then(function(radioNet) { - var hwtype = uci.get('wireless', radioNet.getWifiDeviceName(), 'type'); - var o, ss; + const hwtype = uci.get('wireless', radioNet.getWifiDeviceName(), 'type'); + let o, ss; o = s.option(form.SectionValue, '_device', form.NamedSection, radioNet.getWifiDeviceName(), 'wifi-device', _('Device Configuration')); o.modalonly = true; @@ -1004,7 +971,7 @@ return view.extend({ ss.tab('general', _('General Setup')); ss.tab('advanced', _('Advanced Settings')); - var isDisabled = (radioNet.get('disabled') == '1' || + const isDisabled = (radioNet.get('disabled') == '1' || uci.get('wireless', radioNet.getWifiDeviceName(), 'disabled') == 1); o = ss.taboption('general', form.DummyValue, '_wifistat_modal', _('Status')); @@ -1108,23 +1075,24 @@ return view.extend({ o.novirtual = true; o.write = function(section_id, value) { return network.getDevice(section_id).then(L.bind(function(dev) { - var old_networks = dev.getNetworks().reduce(function(o, v) { o[v.getName()] = v; return o }, {}), - new_networks = {}, - values = L.toArray(value), - tasks = []; + const old_networks = dev.getNetworks().reduce(function(o, v) { o[v.getName()] = v; return o }, {}); + const new_networks = {}; + const values = L.toArray(value); + const tasks = []; - for (var i = 0; i < values.length; i++) { - new_networks[values[i]] = true; + values.forEach(value => { - if (old_networks[values[i]]) - continue; + new_networks[value] = true; - tasks.push(network.getNetwork(values[i]).then(L.bind(function(name, net) { + if (old_networks[value]) + return; + + tasks.push(network.getNetwork(value).then(L.bind(function(name, net) { return net || network.addNetwork(name, { proto: 'none' }); - }, this, values[i])).then(L.bind(function(dev, net) { + }, this, value)).then(L.bind(function(dev, net) { if (net) { if (!net.isEmpty()) { - var target_dev = net.getDevice(); + const target_dev = net.getDevice(); /* Resolve parent interface of vlan */ while (target_dev && target_dev.getType() == 'vlan') @@ -1137,9 +1105,9 @@ return view.extend({ net.addDevice(dev); } }, this, dev))); - } + }); - for (var name in old_networks) + for (let name in old_networks) if (!new_networks[name]) tasks.push(network.getNetwork(name).then(L.bind(function(dev, net) { if (net) @@ -1150,10 +1118,10 @@ return view.extend({ }, this)); }; + let encr; if (hwtype == 'mac80211') { - var mode = ss.children[0], - bssid = ss.children[5], - encr; + const mode = ss.children[0]; + const bssid = ss.children[5]; mode.value('mesh', '802.11s'); mode.value('ahdemo', _('Pseudo Ad-Hoc (ahdemo)')); @@ -1208,8 +1176,8 @@ return view.extend({ }; mode.cfgvalue = function(section_id) { - var mode = uci.get('wireless', section_id, 'mode'), - wds = uci.get('wireless', section_id, 'wds'); + const mode = uci.get('wireless', section_id, 'mode'); + const wds = uci.get('wireless', section_id, 'wds'); if (mode == 'ap' && wds) return 'ap-wds'; @@ -1246,7 +1214,7 @@ return view.extend({ if (/^radio\d+\.network/.test(o.placeholder)) o.placeholder = ''; - var macaddr = uci.get('wireless', radioNet.getName(), 'macaddr'); + const macaddr = uci.get('wireless', radioNet.getName(), 'macaddr'); o = ss.taboption('advanced', form.Value, 'macaddr', _('MAC address'), _('Override default MAC address - the range of usable addresses might be limited by the driver')); o.value('', _('driver default (%s)').format(!macaddr ? radioNet.getActiveBSSID() : _('no override'))); o.value('random', _('randomly generated')); @@ -1294,7 +1262,7 @@ return view.extend({ o.depends('mode', 'mesh'); o.cfgvalue = function(section_id) { - var v = String(uci.get('wireless', section_id, 'encryption')); + const v = String(uci.get('wireless', section_id, 'encryption')); if (v == 'wep') return 'wep-open'; else if (v.match(/\+/)) @@ -1303,8 +1271,8 @@ return view.extend({ }; o.write = function(section_id, value) { - var e = this.section.children.filter(function(o) { return o.option == 'encryption' })[0].formvalue(section_id), - co = this.section.children.filter(function(o) { return o.option == 'cipher' })[0], c = co.formvalue(section_id); + let e = this.section.children.filter(function(o) { return o.option == 'encryption' })[0].formvalue(section_id); + const co = this.section.children.filter(function(o) { return o.option == 'cipher' })[0], c = co.formvalue(section_id); if (value == 'wpa' || value == 'wpa2' || value == 'wpa3' || value == 'wpa3-mixed' || value == 'wpa3-192') uci.unset('wireless', section_id, 'key'); @@ -1335,7 +1303,7 @@ return view.extend({ o.write = ss.children.filter(function(o) { return o.option == 'encryption' })[0].write; o.cfgvalue = function(section_id) { - var v = String(uci.get('wireless', section_id, 'encryption')); + let v = String(uci.get('wireless', section_id, 'encryption')); if (v.match(/\+/)) { v = v.replace(/^[^+]+\+/, ''); if (v == 'aes') @@ -1347,31 +1315,31 @@ return view.extend({ }; - var crypto_modes = []; + const crypto_modes = []; if (hwtype == 'mac80211') { - var has_supplicant = L.hasSystemFeature('wpasupplicant'), - has_hostapd = L.hasSystemFeature('hostapd'); + const has_supplicant = L.hasSystemFeature('wpasupplicant'); + const has_hostapd = L.hasSystemFeature('hostapd'); // Probe EAP support - var has_ap_eap = L.hasSystemFeature('hostapd', 'eap'), - has_sta_eap = L.hasSystemFeature('wpasupplicant', 'eap'); + const has_ap_eap = L.hasSystemFeature('hostapd', 'eap'); + const has_sta_eap = L.hasSystemFeature('wpasupplicant', 'eap'); // Probe SAE support - var has_ap_sae = L.hasSystemFeature('hostapd', 'sae'), - has_sta_sae = L.hasSystemFeature('wpasupplicant', 'sae'); + const has_ap_sae = L.hasSystemFeature('hostapd', 'sae'); + const has_sta_sae = L.hasSystemFeature('wpasupplicant', 'sae'); // Probe OWE support - var has_ap_owe = L.hasSystemFeature('hostapd', 'owe'), - has_sta_owe = L.hasSystemFeature('wpasupplicant', 'owe'); + const has_ap_owe = L.hasSystemFeature('hostapd', 'owe'); + const has_sta_owe = L.hasSystemFeature('wpasupplicant', 'owe'); // Probe Suite-B support - var has_ap_eap192 = L.hasSystemFeature('hostapd', 'suiteb192'), - has_sta_eap192 = L.hasSystemFeature('wpasupplicant', 'suiteb192'); + const has_ap_eap192 = L.hasSystemFeature('hostapd', 'suiteb192'); + const has_sta_eap192 = L.hasSystemFeature('wpasupplicant', 'suiteb192'); // Probe WEP support - var has_ap_wep = L.hasSystemFeature('hostapd', 'wep'), - has_sta_wep = L.hasSystemFeature('wpasupplicant', 'wep'); + const has_ap_wep = L.hasSystemFeature('hostapd', 'wep'); + const has_sta_wep = L.hasSystemFeature('wpasupplicant', 'wep'); if (has_hostapd || has_supplicant) { crypto_modes.push(['psk2', 'WPA2-PSK', 35]); @@ -1462,10 +1430,10 @@ return view.extend({ encr.crypto_support['sta-wds'] = encr.crypto_support['sta']; encr.validate = function(section_id, value) { - var modeopt = this.section.children.filter(function(o) { return o.option == 'mode' })[0], - modeval = modeopt.formvalue(section_id), - modetitle = modeopt.vallist[modeopt.keylist.indexOf(modeval)], - enctitle = this.vallist[this.keylist.indexOf(value)]; + const modeopt = this.section.children.filter(function(o) { return o.option == 'mode' })[0]; + const modeval = modeopt.formvalue(section_id); + const modetitle = modeopt.vallist[modeopt.keylist.indexOf(modeval)]; + const enctitle = this.vallist[this.keylist.indexOf(value)]; if (value == 'none') return true; @@ -1488,13 +1456,13 @@ return view.extend({ crypto_modes.sort(function(a, b) { return b[2] - a[2] }); - for (var i = 0; i < crypto_modes.length; i++) { - var security_level = (crypto_modes[i][2] >= 30) ? _('strong security') - : (crypto_modes[i][2] >= 20) ? _('medium security') - : (crypto_modes[i][2] >= 10) ? _('weak security') : _('open network'); + crypto_modes.forEach(crypto_mode => { + const security_level = (crypto_mode[2] >= 30) ? _('strong security') + : (crypto_mode[2] >= 20) ? _('medium security') + : (crypto_mode[2] >= 10) ? _('weak security') : _('open network'); - encr.value(crypto_modes[i][0], '%s (%s)'.format(crypto_modes[i][1], security_level)); - } + encr.value(crypto_mode[0], '%s (%s)'.format(crypto_mode[1], security_level)); + }); o = ss.taboption('encryption', form.Flag, 'ppsk', _('Enable Private PSK (PPSK)'), _('Private Pre-Shared Key (PPSK) allows the use of different Pre-Shared Key for each STA MAC address. Private MAC PSKs are stored on the RADIUS server.')); @@ -1536,7 +1504,7 @@ return view.extend({ o.password = true; /* extra RADIUS settings start */ - var attr_validate = function(section_id, value) { + const attr_validate = function(section_id, value) { if (!value) return true; @@ -1546,7 +1514,7 @@ return view.extend({ return true; }; - var req_attr_syntax = _('Format:') + '<attr_id>[:<syntax:value>]' + '
' + + const req_attr_syntax = _('Format:') + '<attr_id>[:<syntax:value>]' + '
' + 'syntax: s = %s; '.format(_('string (UTF-8)')) + 'd = %s; '.format(_('integer')) + 'x = %s'.format(_('octet string')) /* https://w1.fi/cgit/hostap/commit/?id=af35e7af7f8bb1ca9f0905b4074fb56a264aa12b */ @@ -1631,7 +1599,7 @@ return view.extend({ o.password = true; o.cfgvalue = function(section_id) { - var key = uci.get('wireless', section_id, 'key'); + const key = uci.get('wireless', section_id, 'key'); return /^[1234]$/.test(key) ? null : key; }; @@ -1653,7 +1621,7 @@ return view.extend({ o.value('4', _('Key #%d').format(4)); o.cfgvalue = function(section_id) { - var slot = +uci.get('wireless', section_id, 'key'); + const slot = +uci.get('wireless', section_id, 'key'); return (slot >= 1 && slot <= 4) ? String(slot) : ''; }; @@ -1661,7 +1629,7 @@ return view.extend({ uci.set('wireless', section_id, 'key', value); }; - for (var slot = 1; slot <= 4; slot++) { + for (let slot = 1; slot <= 4; slot++) { o = ss.taboption('encryption', form.Value, 'key%d'.format(slot), _('Key #%d').format(slot)); o.depends('encryption', 'wep-open'); o.depends('encryption', 'wep-shared'); @@ -1679,7 +1647,7 @@ return view.extend({ if (hwtype == 'mac80211') { // Probe 802.11r support (and EAP support as a proxy for Openwrt) - var has_80211r = L.hasSystemFeature('hostapd', '11r') || L.hasSystemFeature('hostapd', 'eap'); + const has_80211r = L.hasSystemFeature('hostapd', '11r') || L.hasSystemFeature('hostapd', 'eap'); o = ss.taboption('roaming', form.Flag, 'ieee80211r', _('802.11r Fast Transition'), _('Enables fast roaming among access points that belong to the same Mobility Domain')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa2', 'wpa3', 'wpa3-mixed', , 'wpa3-192'] }); @@ -1767,7 +1735,7 @@ return view.extend({ } //Pull current System TZ setting - var tz = uci.get('system', '@system[0]', 'timezone'); + const tz = uci.get('system', '@system[0]', 'timezone'); o = ss.taboption('roaming', form.Value, 'time_zone', _('Time zone'), _('802.11v: Local Time Zone Advertisement in management frames.')); o.value(tz); o.rmempty = true; @@ -1848,8 +1816,8 @@ return view.extend({ add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed', 'wpa3-192'], eap_type: ['fast', 'peap', 'ttls'] }); o.validate = function(section_id, value) { - var eo = this.section.children.filter(function(o) { return o.option == 'eap_type' })[0], - ev = eo.formvalue(section_id); + const eo = this.section.children.filter(function(o) { return o.option == 'eap_type' })[0]; + const ev = eo.formvalue(section_id); if (ev != 'ttls' && (value == 'PAP' || value == 'CHAP' || value == 'MSCHAP' || value == 'MSCHAPV2')) return _('This authentication type is not applicable to the selected EAP method.'); @@ -1950,8 +1918,8 @@ return view.extend({ o.depends('ieee80211w', '2'); o.validate = function(section_id, value) { - var modeopt = this.section.children.filter(function(o) { return o.option == 'mode' })[0], - modeval = modeopt.formvalue(section_id); + const modeopt = this.section.children.filter(function(o) { return o.option == 'mode' })[0]; + const modeval = modeopt.formvalue(section_id); if ((value == '2') && ((modeval == 'sta') || (modeval == 'sta-wds'))) { return _('Workaround mode can only be used when acting as an access point.'); @@ -1986,7 +1954,7 @@ return view.extend({ }; s.handleScan = function(radioDev, ev) { - var table = E('table', { 'class': 'table' }, [ + const table = E('table', { 'class': 'table' }, [ E('tr', { 'class': 'tr table-titles' }, [ E('th', { 'class': 'th col-2 middle center' }, _('Signal')), E('th', { 'class': 'th col-4 middle left' }, _('SSID')), @@ -1998,7 +1966,7 @@ return view.extend({ ]) ]); - var stop = E('button', { + const stop = E('button', { 'class': 'btn', 'click': L.bind(this.handleScanStartStop, this), 'style': 'display:none', @@ -2007,7 +1975,7 @@ return view.extend({ cbi_update_table(table, [], E('em', { class: 'spinning' }, _('Starting wireless scan...'))); - var md = ui.showModal(_('Join Network: Wireless Scan'), [ + const md = ui.showModal(_('Join Network: Wireless Scan'), [ table, E('div', { 'class': 'right' }, [ stop, @@ -2030,17 +1998,17 @@ return view.extend({ s.handleScanRefresh = function(radioDev, scanCache, table, stop) { return radioDev.getScanList().then(L.bind(function(results) { - var rows = []; + const rows = []; - for (var i = 0; i < results.length; i++) - scanCache[results[i].bssid] = results[i]; + for (let r of results) + scanCache[r.bssid] = r; - for (var k in scanCache) + for (let k in scanCache) if (scanCache[k].stale) results.push(scanCache[k]); results.sort(function(a, b) { - var diff = (b.quality - a.quality) || (a.channel - b.channel); + const diff = (b.quality - a.quality) || (a.channel - b.channel); if (diff) return diff; @@ -2056,20 +2024,19 @@ return view.extend({ return 1; }); - for (var i = 0; i < results.length; i++) { - var res = results[i], - qv = res.quality || 0, - qm = res.quality_max || 0, - q = (qv > 0 && qm > 0) ? Math.floor((100 / qm) * qv) : 0, - s = res.stale ? 'opacity:0.5' : ''; + results.forEach(res => { + const qv = res?.quality ?? 0; + const qm = res?.quality_max ?? 0; + const q = (qv > 0 && qm > 0) ? Math.floor((100 / qm) * qv) : 0; + const s = res.stale ? 'opacity:0.5' : ''; rows.push([ - E('span', { 'style': s }, render_signal_badge(q, res.signal, res.noise)), - E('span', { 'style': s }, (res.ssid != null) ? '%h'.format(res.ssid) : E('em', _('hidden'))), - E('span', { 'style': s }, '%d'.format(res.channel)), - E('span', { 'style': s }, '%h'.format(res.mode)), - E('span', { 'style': s }, '%h'.format(res.bssid)), - E('span', { 'style': s }, '%h'.format(network.formatWifiEncryption(res.encryption))), + E('span', { 'style': s }, render_signal_badge(q, res?.signal, res?.noise)), + E('span', { 'style': s }, (res?.ssid != null) ? `${res?.ssid}` : E('em', _('hidden'))), + E('span', { 'style': s }, `${res?.channel}`), + E('span', { 'style': s }, `${res?.mode}`), + E('span', { 'style': s }, `${res?.bssid}`), + E('span', { 'style': s }, `${network.formatWifiEncryption(res?.encryption)}`), E('div', { 'class': 'right' }, E('button', { 'class': 'cbi-button cbi-button-action important', 'click': ui.createHandlerFn(this, 'handleJoin', radioDev, res) @@ -2077,7 +2044,7 @@ return view.extend({ ]); res.stale = true; - } + }); cbi_update_table(table, rows); @@ -2088,7 +2055,7 @@ return view.extend({ }; s.handleScanStartStop = function(ev) { - var btn = ev.currentTarget; + const btn = ev.currentTarget; if (btn.getAttribute('data-state') == 'stop') { poll.remove(this.pollFn); @@ -2105,7 +2072,7 @@ return view.extend({ }; s.handleScanAbort = function(ev) { - var md = dom.parent(ev.target, 'div[aria-modal="true"]'); + const md = dom.parent(ev.target, 'div[aria-modal="true"]'); if (md) { md.style.maxWidth = ''; md.style.maxHeight = ''; @@ -2118,48 +2085,48 @@ return view.extend({ }; s.handleJoinConfirm = function(radioDev, bss, form, ev) { - var nameopt = L.toArray(form.lookupOption('name', '_new_'))[0], - passopt = L.toArray(form.lookupOption('password', '_new_'))[0], - ssidopt = L.toArray(form.lookupOption('ssid', '_new_'))[0], - bssidopt = L.toArray(form.lookupOption('bssid', '_new_'))[0], - zoneopt = L.toArray(form.lookupOption('zone', '_new_'))[0], - replopt = L.toArray(form.lookupOption('replace', '_new_'))[0], - nameval = (nameopt && nameopt.isValid('_new_')) ? nameopt.formvalue('_new_') : null, - passval = (passopt && passopt.isValid('_new_')) ? passopt.formvalue('_new_') : null, - ssidval = (ssidopt && ssidopt.isValid('_new_')) ? ssidopt.formvalue('_new_') : null, - bssidval = (bssidopt && bssidopt.isValid('_new_')) ? bssidopt.formvalue('_new_') : null, - zoneval = zoneopt ? zoneopt.formvalue('_new_') : null, - enc = L.isObject(bss.encryption) ? bss.encryption : null, - is_wep = (enc && Array.isArray(enc.wep)), - is_psk = (enc && Array.isArray(enc.wpa) && L.toArray(enc.authentication).filter(function(a) { return a == 'psk' }).length > 0), - is_sae = (enc && Array.isArray(enc.wpa) && L.toArray(enc.authentication).filter(function(a) { return a == 'sae' }).length > 0); + const nameopt = L.toArray(form.lookupOption('name', '_new_'))[0]; + const passopt = L.toArray(form.lookupOption('password', '_new_'))[0]; + const ssidopt = L.toArray(form.lookupOption('ssid', '_new_'))[0]; + const bssidopt = L.toArray(form.lookupOption('bssid', '_new_'))[0]; + const zoneopt = L.toArray(form.lookupOption('zone', '_new_'))[0]; + const replopt = L.toArray(form.lookupOption('replace', '_new_'))[0]; + const nameval = (nameopt && nameopt.isValid('_new_')) ? nameopt.formvalue('_new_') : null; + const passval = (passopt && passopt.isValid('_new_')) ? passopt.formvalue('_new_') : null; + const ssidval = (ssidopt && ssidopt.isValid('_new_')) ? ssidopt.formvalue('_new_') : null; + const bssidval = (bssidopt && bssidopt.isValid('_new_')) ? bssidopt.formvalue('_new_') : null; + const zoneval = zoneopt ? zoneopt.formvalue('_new_') : null; + const enc = L.isObject(bss.encryption) ? bss.encryption : null; + const is_wep = (enc && Array.isArray(enc.wep)); + const is_psk = (enc && Array.isArray(enc.wpa) && L.toArray(enc.authentication).filter(function(a) { return a == 'psk' }).length > 0); + const is_sae = (enc && Array.isArray(enc.wpa) && L.toArray(enc.authentication).filter(function(a) { return a == 'sae' }).length > 0); if (nameval == null || (passopt && passval == null)) return; - var section_id = null; + let section_id = null; return this.map.save(function() { - var wifi_sections = uci.sections('wireless', 'wifi-iface'); + const wifi_sections = uci.sections('wireless', 'wifi-iface'); if (replopt.formvalue('_new_') == '1') { - for (var i = 0; i < wifi_sections.length; i++) - if (wifi_sections[i].device == radioDev.getName()) - uci.remove('wireless', wifi_sections[i]['.name']); + for (let ws of wifi_sections) + if (ws.device == radioDev.getName()) + uci.remove('wireless', ws['.name']); } if (uci.get('wireless', radioDev.getName(), 'disabled') == '1') { - for (var i = 0; i < wifi_sections.length; i++) - if (wifi_sections[i].device == radioDev.getName()) - uci.set('wireless', wifi_sections[i]['.name'], 'disabled', '1'); + for (let ws of wifi_sections) + if (ws.device == radioDev.getName()) + uci.set('wireless', ws['.name'], 'disabled', '1'); uci.unset('wireless', radioDev.getName(), 'disabled'); } - var htmodes = radioDev.getHTModes(); + const htmodes = radioDev.getHTModes(); if (bss.vht_operation && htmodes && htmodes.indexOf('VHT20') !== -1) { - for (var w = bss.vht_operation.channel_width; w >= 20; w /= 2) { + for (let w = bss.vht_operation.channel_width; w >= 20; w /= 2) { if (htmodes.indexOf('VHT'+w) !== -1) { uci.set('wireless', radioDev.getName(), 'htmode', 'VHT'+w); break; @@ -2167,7 +2134,7 @@ return view.extend({ } } else if (bss.ht_operation && htmodes && htmodes.indexOf('HT20') !== -1) { - var w = (bss.ht_operation.secondary_channel_offset == 'no secondary') ? 20 : 40; + const w = (bss.ht_operation.secondary_channel_offset == 'no secondary') ? 20 : 40; uci.set('wireless', radioDev.getName(), 'htmode', 'HT'+w); } else { @@ -2201,7 +2168,7 @@ return view.extend({ uci.set('wireless', section_id, 'key', passval); } else if (is_psk) { - for (var i = enc.wpa.length - 1; i >= 0; i--) { + for (let i = enc.wpa.length - 1; i >= 0; i--) { if (enc.wpa[i] == 2) { uci.set('wireless', section_id, 'encryption', 'psk2'); break; @@ -2226,7 +2193,7 @@ return view.extend({ return network.addNetwork(nameval, { proto: 'dhcp' }).then(function(net) { firewall.deleteNetwork(net.getName()); - var zonePromise = zoneval + const zonePromise = zoneval ? firewall.getZone(zoneval).then(function(zone) { return zone || firewall.addZone(zoneval) }) : Promise.resolve(); @@ -2245,19 +2212,19 @@ return view.extend({ s.handleJoin = function(radioDev, bss, ev) { poll.remove(this.pollFn); - var m2 = new form.Map('wireless'), - s2 = m2.section(form.NamedSection, '_new_'), - enc = L.isObject(bss.encryption) ? bss.encryption : null, - is_wep = (enc && Array.isArray(enc.wep)), - is_psk = (enc && Array.isArray(enc.wpa) && L.toArray(enc.authentication).filter(function(a) { return a == 'psk' || a == 'sae' })), - replace, passphrase, name, bssid, zone; + const m2 = new form.Map('wireless'); + const s2 = m2.section(form.NamedSection, '_new_'); + const enc = L.isObject(bss.encryption) ? bss.encryption : null; + const is_wep = (enc && Array.isArray(enc.wep)); + const is_psk = (enc && Array.isArray(enc.wpa) && L.toArray(enc.authentication).filter(function(a) { return a == 'psk' || a == 'sae' })); + let replace, passphrase, name, bssid, zone; - var nameUsed = function(name) { - var s = uci.get('network', name); + function nameUsed(name) { + const s = uci.get('network', name); if (s != null && s['.type'] != 'interface') return true; - var net = (s != null) ? network.instantiateNetwork(name) : null; + const net = (s != null) ? network.instantiateNetwork(name) : null; return (net != null && !net.isEmpty()); }; @@ -2288,7 +2255,7 @@ return view.extend({ return true; }; - for (var i = 2; nameUsed(name.default); i++) + for (let i = 2; nameUsed(name.default); i++) name.default = 'wwan%d'.format(i); if (is_wep || is_psk) { @@ -2324,7 +2291,7 @@ return view.extend({ }; s.handleAdd = function(radioDev, ev) { - var section_id = next_free_sid(uci.sections('wireless', 'wifi-iface').length); + const section_id = next_free_sid(uci.sections('wireless', 'wifi-iface').length); uci.unset('wireless', radioDev.getName(), 'disabled'); @@ -2341,8 +2308,8 @@ return view.extend({ o = s.option(form.DummyValue, '_badge'); o.modalonly = false; o.textvalue = function(section_id) { - var inst = this.section.lookupRadioOrNetwork(section_id), - node = E('div', { 'class': 'center' }); + const inst = this.section.lookupRadioOrNetwork(section_id); + const node = E('div', { 'class': 'center' }); if (inst.getWifiNetworks) node.appendChild(render_radio_badge(inst)); @@ -2355,7 +2322,7 @@ return view.extend({ o = s.option(form.DummyValue, '_stat'); o.modalonly = false; o.textvalue = function(section_id) { - var inst = this.section.lookupRadioOrNetwork(section_id); + const inst = this.section.lookupRadioOrNetwork(section_id); if (inst.getWifiNetworks) return render_radio_status(inst, this.section.wifis.filter(function(e) { @@ -2367,17 +2334,16 @@ return view.extend({ return m.render().then(L.bind(function(m, nodes) { poll.add(L.bind(function() { - var section_ids = m.children[0].cfgsections(), - tasks = [ network.getHostHints(), network.getWifiDevices() ]; + const tasks = [ network.getHostHints(), network.getWifiDevices() ]; - for (var i = 0; i < section_ids.length; i++) { - var row = nodes.querySelector('.cbi-section-table-row[data-sid="%s"]'.format(section_ids[i])), - dsc = row.querySelector('[data-name="_stat"] > div'), - btns = row.querySelectorAll('.cbi-section-actions button'); + m?.children[0]?.cfgsections?.().forEach(s => { + const row = nodes.querySelector('.cbi-section-table-row[data-sid="%s"]'.format(s)); + const dsc = row.querySelector('[data-name="_stat"] > div'); + const btns = row.querySelectorAll('.cbi-section-actions button'); if (dsc.getAttribute('restart') == '') { dsc.setAttribute('restart', '1'); - tasks.push(fs.exec('/sbin/wifi', ['up', section_ids[i]]).catch(function(e) { + tasks.push(fs.exec('/sbin/wifi', ['up', s]).catch(function(e) { ui.addNotification(null, E('p', e.message)); })); } @@ -2386,39 +2352,37 @@ return view.extend({ btns[0].classList.remove('spinning'); btns[0].disabled = false; } - } + }); return Promise.all(tasks) .then(L.bind(function(hosts_radios) { - var tasks = []; + const tasks = []; - for (var i = 0; i < hosts_radios[1].length; i++) - tasks.push(hosts_radios[1][i].getWifiNetworks()); + hosts_radios[1].forEach(r => tasks.push(r.getWifiNetworks()) ); return Promise.all(tasks).then(function(data) { hosts_radios[2] = []; - for (var i = 0; i < data.length; i++) - hosts_radios[2].push.apply(hosts_radios[2], data[i]); + for (let d of data) + hosts_radios[2].push.apply(hosts_radios[2], d); return hosts_radios; }); }, network)) .then(L.bind(function(hosts_radios_wifis) { - var tasks = []; + const tasks = []; - for (var i = 0; i < hosts_radios_wifis[2].length; i++) - tasks.push(hosts_radios_wifis[2][i].getAssocList()); + hosts_radios_wifis[2].forEach(hrw => tasks.push(hrw.getAssocList()) ); return Promise.all(tasks).then(function(data) { hosts_radios_wifis[3] = []; - for (var i = 0; i < data.length; i++) { - var wifiNetwork = hosts_radios_wifis[2][i], - radioDev = hosts_radios_wifis[1].filter(function(d) { return d.getName() == wifiNetwork.getWifiDeviceName() })[0]; + for (let i = 0; i < data.length; i++) { + const wifiNetwork = hosts_radios_wifis[2][i]; + const radioDev = hosts_radios_wifis[1].filter(function(d) { return d.getName() == wifiNetwork.getWifiDeviceName() })[0]; - for (var j = 0; j < data[i].length; j++) - hosts_radios_wifis[3].push(Object.assign({ radio: radioDev, network: wifiNetwork }, data[i][j])); + for (let dy of data[i]) + hosts_radios_wifis[3].push(Object.assign({ radio: radioDev, network: wifiNetwork }, dy)); } return hosts_radios_wifis; @@ -2431,7 +2395,7 @@ return view.extend({ .then(L.bind(this.poll_status, this, nodes)); }, this), 5); - var table = E('table', { 'class': 'table assoclist', 'id': 'wifi_assoclist_table' }, [ + const table = E('table', { 'class': 'table assoclist', 'id': 'wifi_assoclist_table' }, [ E('tr', { 'class': 'tr table-titles' }, [ E('th', { 'class': 'th nowrap' }, _('Network')), E('th', { 'class': 'th hide-xs' }, _('MAC address')), -- 2.30.2