summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--applications/luci-app-aria2/luasrc/view/aria2/overview_status.htm2
-rw-r--r--applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.css173
-rw-r--r--applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.js684
-rw-r--r--applications/luci-app-nlbwmon/luasrc/view/nlbw/display.htm1116
-rw-r--r--applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm25
-rw-r--r--applications/luci-app-olsr/luasrc/controller/olsr.lua9
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/hna.htm25
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/interfaces.htm16
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/mid.htm4
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/neighbors.htm58
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/routes.htm44
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm69
-rw-r--r--applications/luci-app-olsr/luasrc/view/status-olsr/topology.htm16
-rw-r--r--applications/luci-app-olsr/po/de/olsr.po4
-rw-r--r--applications/luci-app-olsr/po/en/olsr.po4
-rw-r--r--applications/luci-app-olsr/po/templates/olsr.pot5
-rw-r--r--applications/luci-app-opkg/po/zh-cn/opkg.po101
-rw-r--r--applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm35
-rw-r--r--collections/luci-ssl-nginx/Makefile2
-rw-r--r--libs/luci-lib-httpclient/luasrc/httpclient.lua195
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/cbi.js78
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/luci.js186
-rw-r--r--modules/luci-base/luasrc/view/cbi/map.htm34
-rw-r--r--modules/luci-base/luasrc/view/cbi/nsection.htm1
-rw-r--r--modules/luci-base/luasrc/view/cbi/tabcontainer.htm15
-rw-r--r--modules/luci-base/luasrc/view/cbi/tabmenu.htm12
-rw-r--r--modules/luci-base/luasrc/view/cbi/tsection.htm2
-rw-r--r--modules/luci-mod-status/luasrc/controller/admin/status.lua22
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index.htm122
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index/10-system.htm29
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index/20-memory.htm31
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index/30-network.htm17
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index/40-dhcp-leases.htm14
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index/50-dsl.htm20
-rw-r--r--modules/luci-mod-status/luasrc/view/admin_status/index/60-wifi.htm26
-rw-r--r--themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css27
-rw-r--r--themes/luci-theme-freifunk-generic/htdocs/luci-static/freifunk-generic/cascade.css12
-rw-r--r--themes/luci-theme-material/htdocs/luci-static/material/cascade.css3511
-rw-r--r--themes/luci-theme-material/htdocs/luci-static/material/custom.css17
-rwxr-xr-xthemes/luci-theme-material/htdocs/luci-static/material/js/script.js4
-rw-r--r--themes/luci-theme-material/luasrc/view/themes/material/header.htm2
-rw-r--r--themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css48
-rw-r--r--themes/luci-theme-rosy/htdocs/luci-static/rosy/cascade.css980
-rwxr-xr-xthemes/luci-theme-rosy/htdocs/luci-static/rosy/js/script.js27
44 files changed, 4314 insertions, 3510 deletions
diff --git a/applications/luci-app-aria2/luasrc/view/aria2/overview_status.htm b/applications/luci-app-aria2/luasrc/view/aria2/overview_status.htm
index 34b7b3c641..a06d2015ff 100644
--- a/applications/luci-app-aria2/luasrc/view/aria2/overview_status.htm
+++ b/applications/luci-app-aria2/luasrc/view/aria2/overview_status.htm
@@ -67,7 +67,7 @@ function openWebUI(path) {
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
var localhostPath = curWwwPath.substring(0, pos);
- var url = "http:" + localhostPath.substring(window.location.protocol.length) + "/" + path;
+ var url = localhostPath + "/" + path;
window.open(url)
};
//]]>
diff --git a/applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.css b/applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.css
new file mode 100644
index 0000000000..dd24e5dffc
--- /dev/null
+++ b/applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.css
@@ -0,0 +1,173 @@
+#chartjs-tooltip {
+ opacity: 0;
+ position: absolute;
+ background: rgba(0, 0, 0, .7);
+ color: white;
+ padding: 3px;
+ border-radius: 3px;
+ transition: all .1s ease;
+ pointer-events: none;
+ transform: translate(-50%, 0);
+ z-index: 20000;
+}
+
+#chartjs-tooltip.above {
+ transform: translate(-50%, -100%);
+}
+
+#chartjs-tooltip.above:before {
+ border: solid;
+ border-color: #111 transparent;
+ border-color: rgba(0, 0, 0, .8) transparent;
+ border-width: 8px 8px 0 8px;
+ bottom: 1em;
+ content: "";
+ display: block;
+ left: 50%;
+ top: 100%;
+ position: absolute;
+ z-index: 99;
+ transform: translate(-50%, 0);
+}
+
+.pie label {
+ font-weight: bold;
+ font-size: 14px;
+ display: block;
+ margin-bottom: 10px;
+ text-align: center;
+}
+
+.kpi ul {
+ list-style: none;
+}
+
+.kpi li {
+ margin: 10px;
+ display: none;
+}
+
+.kpi big {
+ font-weight: bold;
+}
+
+.head {
+ text-align: center;
+ position: relative;
+ display: flex;
+ flex-wrap: wrap;
+ white-space: normal;
+}
+
+.head .pie {
+ min-width: 200px;
+ padding: 5px;
+ flex: 1 1 30%;
+}
+
+.cbi-tooltip .head .pie {
+ min-width: 100px;
+}
+
+.head .kpi {
+ padding: 5px;
+ font-size: smaller;
+ text-align: left;
+ align-self: center;
+ flex: 1 0 33%;
+ min-width: 150px;
+ display: flex;
+ justify-content: center;
+}
+
+.head .kpi ul {
+ margin: 0;
+}
+
+.table .th,
+.table .td {
+ padding: 1px 3px !important;
+ border: 1px solid #ddd;
+}
+
+.table .td > a {
+ display: block;
+}
+
+.table .placeholder .td {
+ border: none;
+}
+
+.table .td.double {
+ padding: 0 !important;
+}
+
+.table .td.double > span {
+ display: block;
+ padding: 1px 3px;
+}
+
+.table .td.double > span:first-child {
+ border-bottom: 1px solid #ddd;
+}
+
+.cbi-tooltip {
+ box-shadow: 0 0 5px #000;
+}
+
+@media screen and (max-width: 992px) {
+ .table .tr {
+ margin-bottom: 10px;
+ }
+
+ .table .th,
+ .table .td, .table .td.double {
+ padding: 1px 3px !important;
+ flex-basis: 50%;
+ }
+
+ .table .td, .table .td::before,
+ .table .th, .table .th::before {
+ text-align: left !important;
+ font-size: 14px;
+ border: none;
+ }
+
+ #host-data .td.hostname {
+ flex-basis: 100%;
+ }
+
+ #ipv6-data .td.double > span {
+ padding: 0;
+ border-bottom: none;
+ }
+
+ #ipv6-data .td.double > span:first-child::before {
+ content: "IPv4: ";
+ font-style: italic;
+ font-size: 13px;
+ }
+
+ #ipv6-data .td.double > span:last-child::before {
+ content: "IPv6: ";
+ font-style: italic;
+ font-size: 13px;
+ }
+
+ .cbi-tooltip {
+ width: 100%;
+ pointer-events: auto;
+ box-shadow: 0 0 10px 5px #000;
+ border-radius: 0;
+ }
+
+ .cbi-tooltip .table .th,
+ .cbi-tooltip .table .td {
+ flex-basis: 16%;
+ min-width: 100px;
+ }
+
+ .head .kpi {
+ font-size: 14px;
+ }
+}
diff --git a/applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.js b/applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.js
new file mode 100644
index 0000000000..e5ae69b3a7
--- /dev/null
+++ b/applications/luci-app-nlbwmon/htdocs/luci-static/resources/view/nlbw.js
@@ -0,0 +1,684 @@
+var chartRegistry = {},
+ trafficPeriods = [],
+ trafficData = { columns: [], data: [] },
+ hostNames = {},
+ ouiData = [];
+
+
+function off(elem)
+{
+ var val = [0, 0];
+ do {
+ if (!isNaN(elem.offsetLeft) && !isNaN(elem.offsetTop)) {
+ val[0] += elem.offsetLeft;
+ val[1] += elem.offsetTop;
+ }
+ }
+ while ((elem = elem.offsetParent) != null);
+ return val;
+}
+
+Chart.defaults.global.customTooltips = function(tooltip) {
+ var tooltipEl = document.getElementById('chartjs-tooltip');
+
+ if (!tooltipEl) {
+ tooltipEl = document.createElement('div');
+ tooltipEl.setAttribute('id', 'chartjs-tooltip');
+ document.body.appendChild(tooltipEl);
+ }
+
+ if (!tooltip) {
+ if (tooltipEl.row)
+ tooltipEl.row.style.backgroundColor = '';
+
+ tooltipEl.style.opacity = 0;
+ return;
+ }
+
+ var pos = off(tooltip.chart.canvas);
+
+ tooltipEl.className = tooltip.yAlign;
+ tooltipEl.innerHTML = tooltip.text[0];
+
+ tooltipEl.style.opacity = 1;
+ tooltipEl.style.left = pos[0] + tooltip.x + 'px';
+ tooltipEl.style.top = pos[1] + tooltip.y - tooltip.caretHeight - tooltip.caretPadding + 'px';
+
+ console.debug(tooltip.text);
+
+ var row = findParent(tooltip.text[1], '.tr'),
+ hue = tooltip.text[2];
+
+ if (row && !isNaN(hue)) {
+ row.style.backgroundColor = 'hsl(%u, 100%%, 80%%)'.format(hue);
+ tooltipEl.row = row;
+ }
+};
+
+Chart.defaults.global.tooltipFontSize = 10;
+Chart.defaults.global.tooltipTemplate = function(tip) {
+ tip.label[0] = tip.label[0].format(tip.value);
+ return tip.label;
+};
+
+function kpi(id, val1, val2, val3)
+{
+ var e = L.dom.elem(id) ? id : document.getElementById(id);
+
+ if (val1 && val2 && val3)
+ e.innerHTML = _('%s, %s and %s').format(val1, val2, val3);
+ else if (val1 && val2)
+ e.innerHTML = _('%s and %s').format(val1, val2);
+ else if (val1)
+ e.innerHTML = val1;
+
+ e.parentNode.style.display = val1 ? 'list-item' : '';
+}
+
+function pie(id, data)
+{
+ var total = data.reduce(function(n, d) { return n + d.value }, 0);
+
+ data.sort(function(a, b) { return b.value - a.value });
+
+ if (total === 0)
+ data = [{
+ value: 1,
+ color: '#cccccc',
+ label: [ _('no traffic') ]
+ }];
+
+ for (var i = 0; i < data.length; i++) {
+ if (!data[i].color) {
+ var hue = 120 / (data.length-1) * i;
+ data[i].color = 'hsl(%u, 80%%, 50%%)'.format(hue);
+ data[i].label.push(hue);
+ }
+ }
+
+ var node = L.dom.elem(id) ? id : document.getElementById(id),
+ key = L.dom.elem(id) ? id.id : id,
+ ctx = node.getContext('2d');
+
+ if (chartRegistry.hasOwnProperty(key))
+ chartRegistry[key].destroy();
+
+ chartRegistry[key] = new Chart(ctx).Doughnut(data, {
+ segmentStrokeWidth: 1,
+ percentageInnerCutout: 30
+ });
+
+ return chartRegistry[key];
+}
+
+function query(filter, group, order)
+{
+ var keys = [], columns = {}, records = {}, result = [];
+
+ if (typeof(group) !== 'function' && typeof(group) !== 'object')
+ group = ['mac'];
+
+ for (var i = 0; i < trafficData.columns.length; i++)
+ columns[trafficData.columns[i]] = i;
+
+ for (var i = 0; i < trafficData.data.length; i++) {
+ var record = trafficData.data[i];
+
+ if (typeof(filter) === 'function' && filter(columns, record) !== true)
+ continue;
+
+ var key;
+
+ if (typeof(group) === 'function') {
+ key = group(columns, record);
+ }
+ else {
+ key = [];
+
+ for (var j = 0; j < group.length; j++)
+ if (columns.hasOwnProperty(group[j]))
+ key.push(record[columns[group[j]]]);
+
+ key = key.join(',');
+ }
+
+ if (!records.hasOwnProperty(key)) {
+ var rec = {};
+
+ for (var col in columns)
+ rec[col] = record[columns[col]];
+
+ records[key] = rec;
+ result.push(rec);
+ }
+ else {
+ records[key].conns += record[columns.conns];
+ records[key].rx_bytes += record[columns.rx_bytes];
+ records[key].rx_pkts += record[columns.rx_pkts];
+ records[key].tx_bytes += record[columns.tx_bytes];
+ records[key].tx_pkts += record[columns.tx_pkts];
+ }
+ }
+
+ if (typeof(order) === 'function')
+ result.sort(order);
+
+ return result;
+}
+
+function oui(mac) {
+ var m, l = 0, r = ouiData.length / 3 - 1;
+ var mac1 = parseInt(mac.replace(/[^a-fA-F0-9]/g, ''), 16);
+
+ while (l <= r) {
+ m = l + Math.floor((r - l) / 2);
+
+ var mask = (0xffffffffffff -
+ (Math.pow(2, 48 - ouiData[m * 3 + 1]) - 1));
+
+ var mac1_hi = ((mac1 / 0x10000) & (mask / 0x10000)) >>> 0;
+ var mac1_lo = ((mac1 & 0xffff) & (mask & 0xffff)) >>> 0;
+
+ var mac2 = parseInt(ouiData[m * 3], 16);
+ var mac2_hi = (mac2 / 0x10000) >>> 0;
+ var mac2_lo = (mac2 & 0xffff) >>> 0;
+
+ if (mac1_hi === mac2_hi && mac1_lo === mac2_lo)
+ return ouiData[m * 3 + 2];
+
+ if (mac2_hi > mac1_hi ||
+ (mac2_hi === mac1_hi && mac2_lo > mac1_lo))
+ r = m - 1;
+ else
+ l = m + 1;
+ }
+
+ return null;
+}
+
+
+function fetchData(period)
+{
+ XHR.get(L.url('admin/nlbw/data'), { period: period, group_by: 'family,mac,ip,layer7', order_by: '-rx_bytes,-tx_bytes' }, function(xhr, res) {
+ if (res !== null && typeof(res) === 'object' && typeof(res.columns) === 'object' && typeof(res.data) === 'object')
+ trafficData = res;
+
+ var addrs = query(null, ['ip'], null);
+ var ipAddrs = [];
+
+ for (var i = 0; i < addrs.length; i++)
+ if (ipAddrs.indexOf(addrs[i].ip) < 0)
+ ipAddrs.push(addrs[i].ip);
+
+ renderHostData();
+ renderLayer7Data();
+ renderIPv6Data();
+
+ XHR.get(L.url('admin/nlbw/ptr', ipAddrs.join('/')), null, function(xhr, res) {
+ if (res !== null && typeof(res) === 'object')
+ hostNames = res;
+ });
+ });
+}
+
+function renderPeriods()
+{
+ var sel = document.getElementById('nlbw.period');
+
+ for (var e, i = trafficPeriods.length - 1; e = trafficPeriods[i]; i--) {
+ var d1 = new Date(e);
+ var d2, pd;
+
+ if (i) {
+ d2 = new Date(trafficPeriods[i - 1]);
+ d2.setDate(d2.getDate() - 1);
+ pd = '%04d-%02d-%02d'.format(d1.getFullYear(), d1.getMonth() + 1, d1.getDate());
+ }
+ else {
+ d2 = new Date();
+ pd = '';
+ }
+
+ var opt = document.createElement('option');
+ opt.setAttribute('data-duration', (d2.getTime() - d1.getTime()) / 1000);
+ opt.value = pd;
+ opt.text = '%04d-%02d-%02d - %04d-%02d-%02d'.format(
+ d1.getFullYear(), d1.getMonth() + 1, d1.getDate(),
+ d2.getFullYear(), d2.getMonth() + 1, d2.getDate());
+
+ sel.appendChild(opt);
+ }
+
+ sel.selectedIndex = sel.childNodes.length - 1;
+ sel.style.display = '';
+
+ sel.onchange = function(ev) {
+ L.hideTooltip(ev);
+ fetchData(sel.options[sel.selectedIndex].value);
+ }
+}
+
+function renderHostDetail(tooltip)
+{
+ var key = this.getAttribute('href').substr(1),
+ col = this.getAttribute('data-col'),
+ label = this.getAttribute('data-tooltip');
+
+ var detailData = query(
+ function(c, r) {
+ return ((r[c.mac] === key || r[c.ip] === key) &&
+ (r[c.rx_bytes] > 0 || r[c.tx_bytes] > 0));
+ },
+ [col],
+ function(r1, r2) {
+ return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
+ }
+ );
+
+ var rxData = [], txData = [];
+
+ L.dom.content(tooltip, [
+ E('div', { 'class': 'head' }, [
+ E('div', { 'class': 'pie' }, [
+ E('label', _('Download')),
+ E('canvas', { 'id': 'bubble-pie1', 'width': 100, 'height': 100 })
+ ]),
+ E('div', { 'class': 'pie' }, [
+ E('label', _('Upload')),
+ E('canvas', { 'id': 'bubble-pie2', 'width': 100, 'height': 100 })
+ ]),
+ E('div', { 'class': 'kpi' }, [
+ E('ul', [
+ E('li', _('Hostname: <big id="bubble-hostname">example.org</big>')),
+ E('li', _('Vendor: <big id="bubble-vendor">Example Corp.</big>'))
+ ])
+ ])
+ ]),
+ E('div', { 'class': 'table' }, [
+ E('div', { 'class': 'tr table-titles' }, [
+ E('div', { 'class': 'th' }, label || col),
+ E('div', { 'class': 'th' }, _('Conn.')),
+ E('div', { 'class': 'th' }, _('Down. (Bytes)')),
+ E('div', { 'class': 'th' }, _('Down. (Pkts.)')),
+ E('div', { 'class': 'th' }, _('Up. (Bytes)')),
+ E('div', { 'class': 'th' }, _('Up. (Pkts.)')),
+ ])
+ ])
+ ]);
+
+ var rows = [];
+
+ for (var i = 0; i < detailData.length; i++) {
+ var rec = detailData[i],
+ cell = E('div', rec[col] || _('other'));
+
+ rows.push([
+ cell,
+ '%1000.2m'.format(rec.conns),
+ '%1024.2mB'.format(rec.rx_bytes),
+ '%1000.2mP'.format(rec.rx_pkts),
+ '%1024.2mB'.format(rec.tx_bytes),
+ '%1000.2mP'.format(rec.tx_pkts)
+ ]);
+
+ rxData.push({
+ label: ['%s: %%1024.2mB'.format(rec[col] || _('other')), cell],
+ value: rec.rx_bytes
+ });
+
+ txData.push({
+ label: ['%s: %%1024.2mB'.format(rec[col] || _('other')), cell],
+ value: rec.tx_bytes
+ });
+ }
+
+ cbi_update_table(tooltip.lastElementChild, rows);
+
+ pie(tooltip.querySelector('#bubble-pie1'), rxData);
+ pie(tooltip.querySelector('#bubble-pie2'), txData);
+
+ var mac = key.toUpperCase();
+ var name = hostInfo.hasOwnProperty(mac) ? hostInfo[mac].name : null;
+
+ if (!name)
+ for (var i = 0; i < detailData.length; i++)
+ if ((name = hostNames[detailData[i].ip]) !== undefined)
+ break;
+
+ if (mac !== '00:00:00:00:00:00') {
+ kpi(tooltip.querySelector('#bubble-hostname'), name);
+ kpi(tooltip.querySelector('#bubble-vendor'), oui(mac));
+ }
+ else {
+ kpi(tooltip.querySelector('#bubble-hostname'));
+ kpi(tooltip.querySelector('#bubble-vendor'));
+ }
+
+ var rect = this.getBoundingClientRect(), x, y;
+
+ if ('ontouchstart' in window || window.innerWidth <= 992) {
+ var vpHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
+ scrollFrom = window.pageYOffset,
+ scrollTo = scrollFrom + rect.top - vpHeight * 0.5,
+ start = null;
+
+ tooltip.style.top = (rect.top + rect.height + window.pageYOffset) + 'px';
+ tooltip.style.left = 0;
+
+ var scrollStep = function(timestamp) {
+ if (!start)
+ start = timestamp;
+
+ var duration = Math.max(timestamp - start, 1);
+ if (duration < 100) {
+ document.body.scrollTop = scrollFrom + (scrollTo - scrollFrom) * (duration / 100);
+ window.requestAnimationFrame(scrollStep);
+ }
+ else {
+ document.body.scrollTop = scrollTo;
+ }
+ };
+
+ window.requestAnimationFrame(scrollStep);
+ }
+ else {
+ x = rect.left + rect.width + window.pageXOffset,
+ y = rect.top + window.pageYOffset;
+
+ if ((y + tooltip.offsetHeight) > (window.innerHeight + window.pageYOffset))
+ y -= ((y + tooltip.offsetHeight) - (window.innerHeight + window.pageYOffset));
+
+ tooltip.style.top = y + 'px';
+ tooltip.style.left = x + 'px';
+ }
+
+ return false;
+}
+
+function formatHostname(dns)
+{
+ if (dns === undefined || dns === null || dns === '')
+ return '-';
+
+ dns = dns.split('.')[0];
+
+ if (dns.length > 12)
+ return '<span title="%q">%h…</span>'.format(dns, dns.substr(0, 12));
+
+ return '%h'.format(dns);
+}
+
+function renderHostData()
+{
+ var trafData = [], connData = [];
+ var rx_total = 0, tx_total = 0, conn_total = 0;
+
+ var hostData = query(
+ function(c, r) {
+ return (r[c.rx_bytes] > 0 || r[c.tx_bytes] > 0);
+ },
+ ['mac'],
+ //function(c, r) {
+ // return (r[c.mac] !== '00:00:00:00:00:00') ? r[c.mac] : r[c.ip];
+ //},
+ function(r1, r2) {
+ return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
+ }
+ );
+
+ var rows = [];
+
+ for (var i = 0; i < hostData.length; i++) {
+ var rec = hostData[i],
+ mac = rec.mac.toUpperCase(),
+ key = (mac !== '00:00:00:00:00:00') ? mac : rec.ip,
+ dns = hostInfo[mac] ? hostInfo[mac].name : null;
+
+ var cell = E('div', formatHostname(dns));
+
+ rows.push([
+ cell,
+ E('a', {
+ 'href': '#' + rec.mac,
+ 'data-col': 'ip',
+ 'data-tooltip': _('Source IP')
+ }, (mac !== '00:00:00:00:00:00') ? mac : _('other')),
+ E('a', {
+ 'href': '#' + rec.mac,
+ 'data-col': 'layer7',
+ 'data-tooltip': _('Protocol')
+ }, '%1000.2m'.format(rec.conns)),
+ '%1024.2mB'.format(rec.rx_bytes),
+ '%1000.2mP'.format(rec.rx_pkts),
+ '%1024.2mB'.format(rec.tx_bytes),
+ '%1000.2mP'.format(rec.tx_pkts)
+ ]);
+
+ trafData.push({
+ value: rec.rx_bytes + rec.tx_bytes,
+ label: ["%s: %%.2mB".format(key), cell]
+ });
+
+ connData.push({
+ value: rec.conns,
+ label: ["%s: %%.2m".format(key), cell]
+ });
+
+ rx_total += rec.rx_bytes;
+ tx_total += rec.tx_bytes;
+ conn_total += rec.conns;
+ }
+
+ cbi_update_table('#host-data', rows, E('em', [
+ _('No data recorded yet.'), ' ',
+ E('a', { 'href': L.url('admin/nlbw/commit') }, _('Force reload…'))
+ ]));
+
+ pie('traf-pie', trafData);
+ pie('conn-pie', connData);
+
+ kpi('rx-total', '%1024.2mB'.format(rx_total));
+ kpi('tx-total', '%1024.2mB'.format(tx_total));
+ kpi('conn-total', '%1000m'.format(conn_total));
+ kpi('host-total', '%u'.format(hostData.length));
+}
+
+function renderLayer7Data()
+{
+ var rxData = [], txData = [];
+ var topConn = [[0],[0],[0]], topRx = [[0],[0],[0]], topTx = [[0],[0],[0]];
+
+ var layer7Data = query(
+ null, ['layer7'],
+ function(r1, r2) {
+ return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
+ }
+ );
+
+ var rows = [];
+
+ for (var i = 0, c = 0; i < layer7Data.length; i++) {
+ var rec = layer7Data[i],
+ cell = E('div', rec.layer7 || _('other'));
+
+ rows.push([
+ cell,
+ '%1000m'.format(rec.conns),
+ '%1024.2mB'.format(rec.rx_bytes),
+ '%1000.2mP'.format(rec.rx_pkts),
+ '%1024.2mB'.format(rec.tx_bytes),
+ '%1000.2mP'.format(rec.tx_pkts)
+ ]);
+
+ rxData.push({
+ value: rec.rx_bytes,
+ label: ["%s: %%.2mB".format(rec.layer7 || _('other')), cell]
+ });
+
+ txData.push({
+ value: rec.tx_bytes,
+ label: ["%s: %%.2mB".format(rec.layer7 || _('other')), cell]
+ });
+
+ if (rec.layer7) {
+ topRx.push([rec.rx_bytes, rec.layer7]);
+ topTx.push([rec.tx_bytes, rec.layer7]);
+ topConn.push([rec.conns, rec.layer7]);
+ }
+ }
+
+ cbi_update_table('#layer7-data', rows, E('em', [
+ _('No data recorded yet.'), ' ',
+ E('a', { 'href': L.url('admin/nlbw/commit') }, _('Force reload…'))
+ ]));
+
+ pie('layer7-rx-pie', rxData);
+ pie('layer7-tx-pie', txData);
+
+ topRx.sort(function(a, b) { return b[0] - a[0] });
+ topTx.sort(function(a, b) { return b[0] - a[0] });
+ topConn.sort(function(a, b) { return b[0] - a[0] });
+
+ kpi('layer7-total', layer7Data.length);
+ kpi('layer7-most-rx', topRx[0][1], topRx[1][1], topRx[2][1]);
+ kpi('layer7-most-tx', topTx[0][1], topTx[1][1], topTx[2][1]);
+ kpi('layer7-most-conn', topConn[0][1], topConn[1][1], topConn[2][1]);
+}
+
+function renderIPv6Data()
+{
+ var col = { },
+ rx4_total = 0,
+ tx4_total = 0,
+ rx6_total = 0,
+ tx6_total = 0,
+ v4_total = 0,
+ v6_total = 0,
+ ds_total = 0,
+ families = { },
+ records = { };
+
+ ipv6Data = query(
+ null, ['family', 'mac'],
+ function(r1, r2) {
+ return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
+ }
+ );
+
+ for (var i = 0, c = 0; i < ipv6Data.length; i++) {
+ var rec = ipv6Data[i],
+ mac = rec.mac.toUpperCase(),
+ ip = rec.ip,
+ fam = families[mac] || 0,
+ recs = records[mac] || {};
+
+ if (rec.family == 4) {
+ rx4_total += rec.rx_bytes;
+ tx4_total += rec.tx_bytes;
+ fam |= 1;
+ }
+ else {
+ rx6_total += rec.rx_bytes;
+ tx6_total += rec.tx_bytes;
+ fam |= 2;
+ }
+
+ recs[rec.family] = rec;
+ records[mac] = recs;
+
+ families[mac] = fam;
+ }
+
+ for (var mac in families) {
+ switch (families[mac])
+ {
+ case 3:
+ ds_total++;
+ break;
+
+ case 2:
+ v6_total++;
+ break;
+
+ case 1:
+ v4_total++;
+ break;
+ }
+ }
+
+ var rows = [];
+
+ for (var mac in records) {
+ if (mac === '00:00:00:00:00:00')
+ continue;
+
+ var dns = hostInfo[mac] ? hostInfo[mac].name : null,
+ rec4 = records[mac][4],
+ rec6 = records[mac][6];
+
+ rows.push([
+ formatHostname(dns),
+ mac,
+ [ E('span', _('IPv4')),
+ E('span', _('IPv6')) ],
+ [ E('span', rec4 ? '%1024.2mB'.format(rec4.rx_bytes) : '-'),
+ E('span', rec6 ? '%1024.2mB'.format(rec6.rx_bytes) : '-') ],
+ [ E('span', rec4 ? '%1000.2mP'.format(rec4.rx_pkts) : '-'),
+ E('span', rec6 ? '%1000.2mP'.format(rec6.rx_pkts) : '-') ],
+ [ E('span', rec4 ? '%1024.2mB'.format(rec4.tx_bytes) : '-'),
+ E('span', rec6 ? '%1024.2mB'.format(rec6.tx_bytes) : '-') ],
+ [ E('span', rec4 ? '%1000.2mP'.format(rec4.tx_pkts) : '-'),
+ E('span', rec6 ? '%1000.2mP'.format(rec6.tx_pkts) : '-') ]
+ ]);
+ }
+
+ cbi_update_table('#ipv6-data', rows, E('em', [
+ _('No data recorded yet.'), ' ',
+ E('a', { 'href': L.url('admin/nlbw/commit') }, _('Force reload…'))
+ ]));
+
+ var shareData = [], hostsData = [];
+
+ if (rx4_total > 0 || tx4_total > 0)
+ shareData.push({
+ value: rx4_total + tx4_total,
+ label: ["IPv4: %.2mB"],
+ color: 'hsl(140, 100%, 50%)'
+ });
+
+ if (rx6_total > 0 || tx6_total > 0)
+ shareData.push({
+ value: rx6_total + tx6_total,
+ label: ["IPv6: %.2mB"],
+ color: 'hsl(180, 100%, 50%)'
+ });
+
+ if (v4_total > 0)
+ hostsData.push({
+ value: v4_total,
+ label: [_('%d IPv4-only hosts')],
+ color: 'hsl(140, 100%, 50%)'
+ });
+
+ if (v6_total > 0)
+ hostsData.push({
+ value: v6_total,
+ label: [_('%d IPv6-only hosts')],
+ color: 'hsl(180, 100%, 50%)'
+ });
+
+ if (ds_total > 0)
+ hostsData.push({
+ value: ds_total,
+ label: [_('%d dual-stack hosts')],
+ color: 'hsl(50, 100%, 50%)'
+ });
+
+ pie('ipv6-share-pie', shareData);
+ pie('ipv6-hosts-pie', hostsData);
+
+ kpi('ipv6-hosts', '%.2f%%'.format(100 / (ds_total + v4_total + v6_total) * (ds_total + v6_total)));
+ kpi('ipv6-share', '%.2f%%'.format(100 / (rx4_total + rx6_total + tx4_total + tx6_total) * (rx6_total + tx6_total)));
+ kpi('ipv6-rx', '%1024.2mB'.format(rx6_total));
+ kpi('ipv6-tx', '%1024.2mB'.format(tx6_total));
+}
diff --git a/applications/luci-app-nlbwmon/luasrc/view/nlbw/display.htm b/applications/luci-app-nlbwmon/luasrc/view/nlbw/display.htm
index 616bcc52a1..3c7af928ff 100644
--- a/applications/luci-app-nlbwmon/luasrc/view/nlbw/display.htm
+++ b/applications/luci-app-nlbwmon/luasrc/view/nlbw/display.htm
@@ -1,1031 +1,155 @@
<%#
- Copyright 2017 Jo-Philipp Wich <jo@mein.io>
+ Copyright 2017-2018 Jo-Philipp Wich <jo@mein.io>
Licensed to the public under the Apache License 2.0.
-%>
-<% css = [[
-
- #chartjs-tooltip {
- opacity: 0;
- position: absolute;
- background: rgba(0, 0, 0, .7);
- color: white;
- padding: 3px;
- border-radius: 3px;
- -webkit-transition: all .1s ease;
- transition: all .1s ease;
- pointer-events: none;
- -webkit-transform: translate(-50%, 0);
- transform: translate(-50%, 0);
- z-index: 200;
- }
-
- #chartjs-tooltip.above {
- -webkit-transform: translate(-50%, -100%);
- transform: translate(-50%, -100%);
- }
-
- #chartjs-tooltip.above:before {
- border: solid;
- border-color: #111 transparent;
- border-color: rgba(0, 0, 0, .8) transparent;
- border-width: 8px 8px 0 8px;
- bottom: 1em;
- content: "";
- display: block;
- left: 50%;
- top: 100%;
- position: absolute;
- z-index: 99;
- -webkit-transform: translate(-50%, 0);
- transform: translate(-50%, 0);
- }
-
- table {
- border: 1px solid #999;
- border-collapse: collapse;
- margin: 0 0 2px !important;
- }
-
- th, td, table table td {
- border: 1px solid #999;
- text-align: right;
- padding: 1px 3px !important;
- white-space: nowrap;
- }
-
- tbody td {
- border-bottom-color: #ccc;
- }
-
- tbody td[rowspan] {
- border-bottom-color: #999;
- }
-
- tbody tr:last-child td {
- border-bottom-color: #999;
- }
-
-
- .pie {
- width: 200px;
- display: inline-block;
- margin: 20px;
- }
-
- .pie label {
- font-weight: bold;
- font-size: 14px;
- display: block;
- margin-bottom: 10px;
- text-align: center;
- }
-
- .kpi {
- display: inline-block;
- margin: 80px 20px 20px;
- vertical-align: top;
- }
-
- .kpi ul {
- list-style: none;
- }
-
- .kpi li {
- margin: 10px;
- display: none;
- }
-
- .kpi big {
- font-weight: bold;
- }
-
- #detail-bubble {
- position: absolute;
- opacity: 0;
- visibility: hidden;
- }
-
- #detail-bubble.in {
- opacity: 1;
- visibility: visible;
- transition: opacity 0.5s;
- }
-
- #detail-bubble > div {
- border: 1px solid #ccc;
- border-radius: 2px;
- padding: 5px;
- background: #fcfcfc;
- }
-
- #detail-bubble .head {
- text-align: center;
- white-space: nowrap;
- position: relative;
- }
-
- #detail-bubble .head .dismiss {
- top: 0;
- right: 0;
- width: 20px;
- line-height: 20px;
- text-align: center;
- text-decoration: none;
- font-weight: bold;
- color: #000;
- position: absolute;
- font-size: 20px;
- }
-
- #detail-bubble .pie {
- width: 100px;
- margin: 5px;
- }
-
- #detail-bubble .kpi {
- margin: 40px 5px 5px;
- font-size: smaller;
- text-align: left;
- }
-
- #detail-bubble .kpi ul {
- margin: 0;
- }
-
- #bubble-arrow {
- border: 1px solid #ccc;
- border-width: 1px 0 0 1px;
- background: #fcfcfc;
- width: 15px;
- height: 15px;
- position: absolute;
- left: 0;
- top: -8px;
- transform: rotate(45deg);
- margin: 0 0 0 -8px;
- }
-
- tr.active > td {
- border-bottom: 2px solid red;
- }
-
- tr.active > td.active {
- border: 2px solid red;
- border-bottom: none;
- }
-
- td.detail {
- border: 2px solid red;
- border-top: none;
- opacity: 0;
- transition: opacity 0.5s;
- }
-
- td.detail.in {
- opacity: 1;
- }
-
- th.hostname,
- td.hostname {
- text-align: left;
- }
-
-]] -%>
-
<%+header%>
-<script type="text/javascript" src="<%=resource%>/nlbw.chart.min.js"></script>
-<script type="text/javascript">//<![CDATA[
-
-var chartRegistry = {},
- trafficPeriods = [],
- trafficData = { columns: [], data: [] },
- hostNames = {},
- hostInfo = <%=luci.util.serialize_json(luci.sys.net.host_hints())%>,
- ouiData = [];
-
-
-function off(elem)
-{
- var val = [0, 0];
- do {
- if (!isNaN(elem.offsetLeft) && !isNaN(elem.offsetTop)) {
- val[0] += elem.offsetLeft;
- val[1] += elem.offsetTop;
- }
- }
- while ((elem = elem.offsetParent) != null);
- return val;
-}
-
-Chart.defaults.global.customTooltips = function(tooltip) {
- var tooltipEl = document.getElementById('chartjs-tooltip');
-
- if (!tooltipEl) {
- tooltipEl = document.createElement('div');
- tooltipEl.setAttribute('id', 'chartjs-tooltip');
- document.body.appendChild(tooltipEl);
- }
-
- if (!tooltip) {
- if (tooltipEl.row)
- tooltipEl.row.style.backgroundColor = '';
-
- tooltipEl.style.opacity = 0;
- return;
- }
-
- var pos = off(tooltip.chart.canvas);
-
- tooltipEl.className = tooltip.yAlign;
- tooltipEl.innerHTML = tooltip.text[0];
-
- tooltipEl.style.opacity = 1;
- tooltipEl.style.left = pos[0] + tooltip.x + 'px';
- tooltipEl.style.top = pos[1] + tooltip.y - tooltip.caretHeight - tooltip.caretPadding + 'px';
-
- var row = tooltip.text[1],
- hue = tooltip.text[2];
-
- if (row && !isNaN(hue)) {
- row.style.backgroundColor = 'hsl(%u, 100%%, 80%%)'.format(hue);
- tooltipEl.row = row;
- }
-};
-
-Chart.defaults.global.tooltipFontSize = 10;
-Chart.defaults.global.tooltipTemplate = function(tip) {
- tip.label[0] = tip.label[0].format(tip.value);
- return tip.label;
-};
-
-function kpi(id, val1, val2, val3)
-{
- var e = document.getElementById(id);
-
- if (val1 && val2 && val3)
- e.innerHTML = '<%:%s, %s and %s%>'.format(val1, val2, val3);
- else if (val1 && val2)
- e.innerHTML = '<%:%s and %s%>'.format(val1, val2);
- else if (val1)
- e.innerHTML = val1;
-
- e.parentNode.style.display = val1 ? 'list-item' : '';
-}
-
-function pie(id, data)
-{
- data.sort(function(a, b) { return b.value - a.value });
-
- if (data.length === 0 || (data.length === 1 && data[0].value === 0))
- data[0] = {
- value: 1,
- color: '#cccccc',
- label: [ '<%:no traffic%>' ]
- };
-
- for (var i = 0; i < data.length; i++) {
- if (!data[i].color) {
- var hue = 120 / (data.length-1) * i;
- data[i].color = 'hsl(%u, 80%%, 50%%)'.format(hue);
- data[i].label.push(hue);
- }
- }
-
- var ctx = document.getElementById(id).getContext('2d');
-
- if (chartRegistry.hasOwnProperty(id))
- chartRegistry[id].destroy();
-
- chartRegistry[id] = new Chart(ctx).Doughnut(data, {
- segmentStrokeWidth: 1,
- percentageInnerCutout: 30
- });
-
- return chartRegistry[id];
-}
-
-function query(filter, group, order)
-{
- var keys = [], columns = {}, records = {}, result = [];
-
- if (typeof(group) !== 'function' && typeof(group) !== 'object')
- group = ['mac'];
-
- for (var i = 0; i < trafficData.columns.length; i++)
- columns[trafficData.columns[i]] = i;
-
- for (var i = 0; i < trafficData.data.length; i++) {
- var record = trafficData.data[i];
-
- if (typeof(filter) === 'function' && filter(columns, record) !== true)
- continue;
-
- var key;
-
- if (typeof(group) === 'function') {
- key = group(columns, record);
- }
- else {
- key = [];
-
- for (var j = 0; j < group.length; j++)
- if (columns.hasOwnProperty(group[j]))
- key.push(record[columns[group[j]]]);
-
- key = key.join(',');
- }
-
- if (!records.hasOwnProperty(key)) {
- var rec = {};
-
- for (var col in columns)
- rec[col] = record[columns[col]];
-
- records[key] = rec;
- result.push(rec);
- }
- else {
- records[key].conns += record[columns.conns];
- records[key].rx_bytes += record[columns.rx_bytes];
- records[key].rx_pkts += record[columns.rx_pkts];
- records[key].tx_bytes += record[columns.tx_bytes];
- records[key].tx_pkts += record[columns.tx_pkts];
- }
- }
-
- if (typeof(order) === 'function')
- result.sort(order);
-
- return result;
-}
-
-function oui(mac) {
- var m, l = 0, r = ouiData.length / 3 - 1;
- var mac1 = parseInt(mac.replace(/[^a-fA-F0-9]/g, ''), 16);
-
- while (l <= r) {
- m = l + Math.floor((r - l) / 2);
-
- var mask = (0xffffffffffff -
- (Math.pow(2, 48 - ouiData[m * 3 + 1]) - 1));
-
- var mac1_hi = ((mac1 / 0x10000) & (mask / 0x10000)) >>> 0;
- var mac1_lo = ((mac1 & 0xffff) & (mask & 0xffff)) >>> 0;
-
- var mac2 = parseInt(ouiData[m * 3], 16);
- var mac2_hi = (mac2 / 0x10000) >>> 0;
- var mac2_lo = (mac2 & 0xffff) >>> 0;
-
- if (mac1_hi === mac2_hi && mac1_lo === mac2_lo)
- return ouiData[m * 3 + 2];
-
- if (mac2_hi > mac1_hi ||
- (mac2_hi === mac1_hi && mac2_lo > mac1_lo))
- r = m - 1;
- else
- l = m + 1;
- }
-
- return null;
-}
-
-
-function fetchData(period)
-{
- XHR.get('<%=url("admin/nlbw/data")%>', { period: period, group_by: 'family,mac,ip,layer7', order_by: '-rx_bytes,-tx_bytes' }, function(xhr, res) {
- if (res !== null && typeof(res) === 'object' && typeof(res.columns) === 'object' && typeof(res.data) === 'object')
- trafficData = res;
-
- var addrs = query(null, ['ip'], null);
- var ipAddrs = [];
-
- for (var i = 0; i < addrs.length; i++)
- if (ipAddrs.indexOf(addrs[i].ip) < 0)
- ipAddrs.push(addrs[i].ip);
-
- renderHostData();
- renderLayer7Data();
- renderIPv6Data();
-
- XHR.get('<%=url("admin/nlbw/ptr")%>/' + ipAddrs.join('/'), null, function(xhr, res) {
- if (res !== null && typeof(res) === 'object')
- hostNames = res;
- });
- });
-}
-
-function switchTab(tab)
-{
- bubbleDismiss();
-
- return cbi_t_switch('nlbw', tab);
-}
-
-function renderPeriods()
-{
- var sel = document.getElementById('nlbw.period');
-
- for (var e, i = trafficPeriods.length - 1; e = trafficPeriods[i]; i--) {
- var d1 = new Date(e);
- var d2, pd;
-
- if (i) {
- d2 = new Date(trafficPeriods[i - 1]);
- d2.setDate(d2.getDate() - 1);
- pd = '%04d-%02d-%02d'.format(d1.getFullYear(), d1.getMonth() + 1, d1.getDate());
- }
- else {
- d2 = new Date();
- pd = '';
- }
-
- var opt = document.createElement('option');
- opt.setAttribute('data-duration', (d2.getTime() - d1.getTime()) / 1000);
- opt.value = pd;
- opt.text = '%04d-%02d-%02d - %04d-%02d-%02d'.format(
- d1.getFullYear(), d1.getMonth() + 1, d1.getDate(),
- d2.getFullYear(), d2.getMonth() + 1, d2.getDate());
-
- sel.appendChild(opt);
- }
-
- sel.selectedIndex = sel.childNodes.length - 1;
- sel.style.display = '';
-
- sel.onchange = function() {
- bubbleDismiss();
- fetchData(sel.options[sel.selectedIndex].value);
- }
-}
-
-function renderHostDetail()
-{
- var key = this.getAttribute('href').substr(1),
- col = this.getAttribute('data-col'),
- label = this.getAttribute('data-label'),
- bubble = document.getElementById('detail-bubble'),
- arrow = document.getElementById('bubble-arrow'),
- table = document.getElementById('bubble-table');
-
- bubbleDismiss();
-
- var detailData = query(
- function(c, r) {
- return ((r[c.mac] === key || r[c.ip] === key) &&
- (r[c.rx_bytes] > 0 || r[c.tx_bytes] > 0));
- },
- [col],
- function(r1, r2) {
- return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
- }
- );
-
- var rxData = [], txData = [];
-
- table.innerHTML = '<tr>' +
- '<th>%s</th>'.format(label || col) +
- '<th><%:Conn.%></th>' +
- '<th colspan="2"><%:Down. (Bytes / Pkts.)%></th>' +
- '<th colspan="2"><%:Up. (Bytes / Pkts.)%></th>' +
- '</tr>';
-
- for (var i = 0; i < detailData.length; i++) {
- var rec = detailData[i],
- row = table.insertRow(-1);
-
- row.insertCell(-1).innerHTML = rec[col] || '<%:other%>';
- row.insertCell(-1).innerHTML = "%1000.2m".format(rec.conns);
- row.insertCell(-1).innerHTML = "%1024.2mB".format(rec.rx_bytes);
- row.insertCell(-1).innerHTML = "%1000.2mP".format(rec.rx_pkts);
- row.insertCell(-1).innerHTML = "%1024.2mB".format(rec.tx_bytes);
- row.insertCell(-1).innerHTML = "%1000.2mP".format(rec.tx_pkts);
-
- rxData.push({
- label: ['%s: %%1024.2mB'.format(rec[col] || '<%:other%>'), row],
- value: rec.rx_bytes
- });
-
- txData.push({
- label: ['%s: %%1024.2mB'.format(rec[col] || '<%:other%>'), row],
- value: rec.tx_bytes
- });
- }
-
- pie('bubble-pie1', rxData);
- pie('bubble-pie2', txData);
-
- var mac = key.toUpperCase();
- var name = hostInfo.hasOwnProperty(mac) ? hostInfo[mac].name : null;
-
- if (!name)
- for (var i = 0; i < detailData.length; i++)
- if ((name = hostNames[detailData[i].ip]) !== undefined)
- break;
+<link rel="stylesheet" href="<%=resource%>/view/nlbw.css" />
- if (mac !== '00:00:00:00:00:00') {
- kpi('bubble-hostname', name);
- kpi('bubble-vendor', oui(mac));
- }
- else {
- kpi('bubble-hostname');
- kpi('bubble-vendor');
- }
-
- var tr = this.parentNode.parentNode,
- xy = off(tr),
- xy2 = off(this);
-
- bubble.style.width = tr.offsetWidth + 'px';
- bubble.style.left = xy[0] + 'px';
- bubble.style.top = (xy[1] + tr.offsetHeight) + 'px';
- arrow.style.left = Math.floor(xy2[0] + this.offsetWidth / 2 - xy[0]) + 'px';
-
- bubble.className = 'in';
-
- return false;
-}
-
-function formatHostname(dns)
-{
- if (dns === undefined || dns === null || dns === '')
- return '-';
-
- dns = dns.split('.')[0];
-
- if (dns.length > 12)
- return '<span title="%q">%h…</span>'.format(dns, dns.substr(0, 12));
-
- return '%h'.format(dns);
-}
-
-function renderHostData()
-{
- var trafData = [], connData = [];
- var rx_total = 0, tx_total = 0, conn_total = 0;
- var table = document.getElementById('host-data');
-
- var hostData = query(
- function(c, r) {
- return (r[c.rx_bytes] > 0 || r[c.tx_bytes] > 0);
- },
- ['mac'],
- //function(c, r) {
- // return (r[c.mac] !== '00:00:00:00:00:00') ? r[c.mac] : r[c.ip];
- //},
- function(r1, r2) {
- return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
- }
- );
-
- while (table.rows.length > 1)
- table.deleteRow(1);
-
- for (var i = 0; i < hostData.length; i++) {
- var row = table.insertRow(-1),
- cell = row.insertCell(-1),
- rec = hostData[i],
- mac = rec.mac.toUpperCase(),
- key = (mac !== '00:00:00:00:00:00') ? mac : rec.ip,
- dns = hostInfo[mac] ? hostInfo[mac].name : null;
-
- var link1 = document.createElement('a');
- link1.onclick = renderHostDetail;
- link1.href = '#' + rec.mac;
- link1.setAttribute('data-col', 'ip');
- link1.setAttribute('data-label', '<%:Source IP%>');
- link1.innerHTML = (mac !== '00:00:00:00:00:00') ? mac : '<%:other%>';
-
- var link2 = document.createElement('a');
- link2.onclick = renderHostDetail;
- link2.href = '#' + rec.mac;
- link2.setAttribute('data-col', 'layer7');
- link2.setAttribute('data-label', '<%:Protocol%>');
- link2.innerHTML = "%1000.2m".format(rec.conns);
-
- cell.innerHTML = formatHostname(dns);
- cell.className = 'hostname';
-
- row.insertCell(-1).appendChild(link1);
- row.insertCell(-1).appendChild(link2);
- row.insertCell(-1).innerHTML = "%1024.2mB".format(rec.rx_bytes);
- row.insertCell(-1).innerHTML = "%1000.2mP".format(rec.rx_pkts);
- row.insertCell(-1).innerHTML = "%1024.2mB".format(rec.tx_bytes);
- row.insertCell(-1).innerHTML = "%1000.2mP".format(rec.tx_pkts);
-
- trafData.push({
- value: rec.rx_bytes + rec.tx_bytes,
- label: ["%s: %%.2mB".format(key), row]
- });
-
- connData.push({
- value: rec.conns,
- label: ["%s: %%.2m".format(key), row]
- });
-
- rx_total += rec.rx_bytes;
- tx_total += rec.tx_bytes;
- conn_total += rec.conns;
- }
-
- if (table.rows.length === 1) {
- var cell = table.insertRow(-1).insertCell(-1);
-
- cell.setAttribute('colspan', 6);
- cell.innerHTML = '<em><%:No data recorded yet.%> <a href="<%=url("admin/nlbw/commit")%>"><%:Force reload…%></a></em>';
- }
-
- pie('traf-pie', trafData);
- pie('conn-pie', connData);
-
- kpi('rx-total', '%1024.2mB'.format(rx_total));
- kpi('tx-total', '%1024.2mB'.format(tx_total));
- kpi('conn-total', '%1000m'.format(conn_total));
- kpi('host-total', '%u'.format(hostData.length));
-}
-
-function renderLayer7Data()
-{
- var rxData = [], txData = [];
- var topConn = [[0],[0],[0]], topRx = [[0],[0],[0]], topTx = [[0],[0],[0]];
- var table = document.getElementById('layer7-data');
-
- var layer7Data = query(
- null, ['layer7'],
- function(r1, r2) {
- return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
- }
- );
-
- while (table.rows.length > 1)
- table.deleteRow(1);
-
- for (var i = 0, c = 0; i < layer7Data.length; i++) {
- var rec = layer7Data[i],
- row = table.insertRow(-1);
-
- rxData.push({
- value: rec.rx_bytes,
- label: ["%s: %%.2mB".format(rec.layer7 || '<%:other%>'), row]
- });
-
- txData.push({
- value: rec.tx_bytes,
- label: ["%s: %%.2mB".format(rec.layer7 || '<%:other%>'), row]
- });
-
- row.insertCell(-1).innerHTML = rec.layer7 || '<%:other%>';
- row.insertCell(-1).innerHTML = "%1000m".format(rec.conns);
- row.insertCell(-1).innerHTML = "%1024.2mB".format(rec.rx_bytes);
- row.insertCell(-1).innerHTML = "%1000.2mP".format(rec.rx_pkts);
- row.insertCell(-1).innerHTML = "%1024.2mB".format(rec.tx_bytes);
- row.insertCell(-1).innerHTML = "%1000.2mP".format(rec.tx_pkts);
-
- if (rec.layer7) {
- topRx.push([rec.rx_bytes, rec.layer7]);
- topTx.push([rec.tx_bytes, rec.layer7]);
- topConn.push([rec.conns, rec.layer7]);
- }
- }
-
- if (table.rows.length === 1) {
- var cell = table.insertRow(-1).insertCell(-1);
-
- cell.setAttribute('colspan', 6);
- cell.innerHTML = '<em><%:No data recorded yet.%> <a href="<%=url("admin/nlbw/commit")%>"><%:Force reload…%></a></em>';
- }
-
- pie('layer7-rx-pie', rxData);
- pie('layer7-tx-pie', txData);
-
- topRx.sort(function(a, b) { return b[0] - a[0] });
- topTx.sort(function(a, b) { return b[0] - a[0] });
- topConn.sort(function(a, b) { return b[0] - a[0] });
-
- kpi('layer7-total', layer7Data.length);
- kpi('layer7-most-rx', topRx[0][1], topRx[1][1], topRx[2][1]);
- kpi('layer7-most-tx', topTx[0][1], topTx[1][1], topTx[2][1]);
- kpi('layer7-most-conn', topConn[0][1], topConn[1][1], topConn[2][1]);
-}
-
-function renderIPv6Data()
-{
- var table = document.getElementById('ipv6-data'),
- col = { },
- rx4_total = 0,
- tx4_total = 0,
- rx6_total = 0,
- tx6_total = 0,
- v4_total = 0,
- v6_total = 0,
- ds_total = 0,
- families = { },
- records = { };
-
- ipv6Data = query(
- null, ['family', 'mac'],
- function(r1, r2) {
- return ((r2.rx_bytes + r2.tx_bytes) - (r1.rx_bytes + r1.tx_bytes));
- }
- );
-
- for (var i = 0, c = 0; i < ipv6Data.length; i++) {
- var rec = ipv6Data[i],
- mac = rec.mac.toUpperCase(),
- ip = rec.ip,
- fam = families[mac] || 0,
- recs = records[mac] || {};
-
- if (rec.family == 4) {
- rx4_total += rec.rx_bytes;
- tx4_total += rec.tx_bytes;
- fam |= 1;
- }
- else {
- rx6_total += rec.rx_bytes;
- tx6_total += rec.tx_bytes;
- fam |= 2;
- }
-
- recs[rec.family] = rec;
- records[mac] = recs;
-
- families[mac] = fam;
- }
-
- for (var mac in families) {
- switch (families[mac])
- {
- case 3:
- ds_total++;
- break;
-
- case 2:
- v6_total++;
- break;
-
- case 1:
- v4_total++;
- break;
- }
- }
-
- while (table.rows.length > 1)
- table.deleteRow(1);
-
- for (var mac in records) {
- if (mac === '00:00:00:00:00:00')
- continue;
-
- var row = table.insertRow(-1),
- cell1 = row.insertCell(-1),
- cell2 = row.insertCell(-1),
- dns = hostInfo[mac] ? hostInfo[mac].name : null,
- rec4 = records[mac][4],
- rec6 = records[mac][6];
-
- cell1.setAttribute('rowspan', 2);
- cell1.innerHTML = formatHostname(dns);
- cell1.className = 'hostname';
-
- cell2.setAttribute('rowspan', 2);
- cell2.innerHTML = mac;
-
- row.insertCell(-1).innerHTML = 'IPv4';
- row.insertCell(-1).innerHTML = rec4 ? "%1024.2mB".format(rec4.rx_bytes) : '-';
- row.insertCell(-1).innerHTML = rec4 ? "%1000.2mP".format(rec4.rx_pkts) : '-';
- row.insertCell(-1).innerHTML = rec4 ? "%1024.2mB".format(rec4.tx_bytes) : '-';
- row.insertCell(-1).innerHTML = rec4 ? "%1000.2mP".format(rec4.tx_pkts) : '-';
-
- row = table.insertRow(-1);
-
- row.insertCell(-1).innerHTML = 'IPv6';
- row.insertCell(-1).innerHTML = rec6 ? "%1024.2mB".format(rec6.rx_bytes) : '-';
- row.insertCell(-1).innerHTML = rec6 ? "%1000.2mP".format(rec6.rx_pkts) : '-';
- row.insertCell(-1).innerHTML = rec6 ? "%1024.2mB".format(rec6.tx_bytes) : '-';
- row.insertCell(-1).innerHTML = rec6 ? "%1000.2mP".format(rec6.tx_pkts) : '-';
- }
-
- if (table.rows.length === 1) {
- var cell = table.insertRow(-1).insertCell(-1);
-
- cell.setAttribute('colspan', 7);
- cell.innerHTML = '<em><%:No data recorded yet.%> <a href="<%=url("admin/nlbw/commit")%>"><%:Force reload…%></a></em>';
- }
-
- var shareData = [], hostsData = [];
-
- if (rx4_total > 0 || tx4_total > 0)
- shareData.push({
- value: rx4_total + tx4_total,
- label: ["IPv4: %.2mB"],
- color: 'hsl(140, 100%, 50%)'
- });
-
- if (rx6_total > 0 || tx6_total > 0)
- shareData.push({
- value: rx6_total + tx6_total,
- label: ["IPv6: %.2mB"],
- color: 'hsl(180, 100%, 50%)'
- });
-
- if (v4_total > 0)
- hostsData.push({
- value: v4_total,
- label: ["<%:%d IPv4-only hosts%>"],
- color: 'hsl(140, 100%, 50%)'
- });
-
- if (v6_total > 0)
- hostsData.push({
- value: v6_total,
- label: ["<%:%d IPv6-only hosts%>"],
- color: 'hsl(180, 100%, 50%)'
- });
-
- if (ds_total > 0)
- hostsData.push({
- value: ds_total,
- label: ["<%:%d dual-stack hosts%>"],
- color: 'hsl(50, 100%, 50%)'
- });
-
- pie('ipv6-share-pie', shareData);
- pie('ipv6-hosts-pie', hostsData);
-
- kpi('ipv6-hosts', '%.2f%%'.format(100 / (ds_total + v4_total + v6_total) * (ds_total + v6_total)));
- kpi('ipv6-share', '%.2f%%'.format(100 / (rx4_total + rx6_total + tx4_total + tx6_total) * (rx6_total + tx6_total)));
- kpi('ipv6-rx', '%1024.2mB'.format(rx6_total));
- kpi('ipv6-tx', '%1024.2mB'.format(tx6_total));
-}
-
-function bubbleDismiss()
-{
- var bubble = document.getElementById('detail-bubble');
-
- bubble.className = '';
- document.body.appendChild(bubble);
-
- return false;
-}
+<script type="text/javascript" src="<%=resource%>/nlbw.chart.min.js"></script>
+<script type="text/javascript" src="<%=resource%>/view/nlbw.js"></script>
+<h2 name="content"><%:Netlink Bandwidth Monitor%></h2>
-//]]></script>
+<p>
+ <%:Select accounting period:%>
+ <select id="nlbw.period" style="display:none"></select>
+</p>
-<h2 name="content"><%:Netlink Bandwidth Monitor%></h2>
+<hr />
-<div id="detail-bubble">
- <span id="bubble-arrow"></span>
- <div>
+<div>
+ <div class="cbi-section" data-tab="traffic" data-tab-title="<%:Traffic Distribution%>">
<div class="head">
- <a class="dismiss" href="#" onclick="this.blur(); return bubbleDismiss()">×</a>
<div class="pie">
- <label>Download</label>
- <canvas id="bubble-pie1" width="100" height="100"></canvas>
+ <label><%:Traffic / Host%></label>
+ <canvas id="traf-pie" width="200" height="200"></canvas>
</div>
+
<div class="pie">
- <label>Upload</label>
- <canvas id="bubble-pie2" width="100" height="100"></canvas>
+ <label><%:Connections / Host%></label>
+ <canvas id="conn-pie" width="200" height="200"></canvas>
</div>
+
<div class="kpi">
<ul>
- <li><%_Hostname: <big id="bubble-hostname">example.org</big>%></li>
- <li><%_Vendor: <big id="bubble-vendor">Example Corp.</big>%></li>
+ <li><%_<big id="host-total">0</big> hosts%></li>
+ <li><%_<big id="rx-total">0</big> download%></li>
+ <li><%_<big id="tx-total">0</big> upload%></li>
+ <li><%_<big id="conn-total">0</big> connections%></li>
</ul>
</div>
</div>
- <table id="bubble-table"></table>
+ <div class="table" id="host-data">
+ <div class="tr table-titles">
+ <div class="th left hostname"><%:Host%></div>
+ <div class="th right"><%:MAC%></div>
+ <div class="th right"><%:Connections%></div>
+ <div class="th right"><%:Download (Bytes)%></div>
+ <div class="th right"><%:Download (Packets)%></div>
+ <div class="th right"><%:Upload (Bytes)%></div>
+ <div class="th right"><%:Upload (Packets)%></div>
+ </div>
+ <div class="tr placeholder">
+ <div class="td">
+ <em class="spinning"><%:Collecting data...%></em>
+ </div>
+ </div>
+ </div>
</div>
-</div>
-<hr />
-
-<p>
- <%:Select accounting period:%>
- <select id="nlbw.period" style="display:none"></select>
-</p>
-
-<hr />
-
-<ul class="cbi-tabmenu">
- <li id="tab.nlbw.traffic" class="cbi-tab"><a href="#" onclick="return switchTab('traffic')"><%:Traffic Distribution%></a></li>
- <li id="tab.nlbw.layer7" class="cbi-tab-disabled"><a href="#" onclick="return switchTab('layer7')"><%:Application Protocols%></a></li>
- <li id="tab.nlbw.ipv6" class="cbi-tab-disabled"><a href="#" onclick="return switchTab('ipv6')"><%:IPv6%></a></li>
- <li id="tab.nlbw.export" class="cbi-tab-disabled"><a href="#" onclick="return switchTab('export')"><%:Export%></a></li>
-</ul>
+ <div class="cbi-section" data-tab="layer7" data-tab-title="<%:Application Protocols%>">
+ <div class="head">
+ <div class="pie">
+ <label><%:Download / Application%></label>
+ <canvas id="layer7-rx-pie" width="200" height="200"></canvas>
+ </div>
-<div class="cbi-section" id="container.nlbw.traffic">
- <div>
- <div class="pie">
- <label><%:Traffic / Host%></label>
- <canvas id="traf-pie" width="200" height="200"></canvas>
- </div>
+ <div class="pie">
+ <label><%:Upload / Application%></label>
+ <canvas id="layer7-tx-pie" width="200" height="200"></canvas>
+ </div>
- <div class="pie">
- <label><%:Connections / Host%></label>
- <canvas id="conn-pie" width="200" height="200"></canvas>
+ <div class="kpi">
+ <ul>
+ <li><%_<big id="layer7-total">0</big> different application protocols%></li>
+ <li><%_<big id="layer7-most-rx">0</big> cause the most download%></li>
+ <li><%_<big id="layer7-most-tx">0</big> cause the most upload%></li>
+ <li><%_<big id="layer7-most-conn">0</big> cause the most connections%></li>
+ </ul>
+ </div>
</div>
-
- <div class="kpi">
- <ul>
- <li><%_<big id="host-total">0</big> hosts%></li>
- <li><%_<big id="rx-total">0</big> download%></li>
- <li><%_<big id="tx-total">0</big> upload%></li>
- <li><%_<big id="conn-total">0</big> connections%></li>
- </ul>
+ <div class="table" id="layer7-data">
+ <div class="tr table-titles">
+ <div class="th left"><%:Application%></div>
+ <div class="th right"><%:Connections%></div>
+ <div class="th right"><%:Download (Bytes)%></div>
+ <div class="th right"><%:Download (Packets)%></div>
+ <div class="th right"><%:Upload (Bytes)%></div>
+ <div class="th right"><%:Upload (Packets)%></div>
+ </div>
+ <div class="tr placeholder">
+ <div class="td">
+ <em class="spinning"><%:Collecting data...%></em>
+ </div>
+ </div>
</div>
</div>
- <table id="host-data">
- <tr>
- <th width="10%" class="hostname"><%:Host%></th>
- <th width="5%"><%:MAC%></th>
- <th width="5%"><%:Connections%></th>
- <th width="30%" colspan="2"><%:Download (Bytes / Packets)%></th>
- <th width="30%" colspan="2"><%:Upload (Bytes / Packets)%></th>
- </tr>
- </table>
-</div>
-
-<div class="cbi-section" id="container.nlbw.layer7" style="display:none">
- <div>
- <div class="pie">
- <label><%:Download / Application%></label>
- <canvas id="layer7-rx-pie" width="200" height="200"></canvas>
- </div>
-
- <div class="pie">
- <label><%:Upload / Application%></label>
- <canvas id="layer7-tx-pie" width="200" height="200"></canvas>
- </div>
- <div class="kpi">
- <ul>
- <li><%_<big id="layer7-total">0</big> different application protocols%></li>
- <li><%_<big id="layer7-most-rx">0</big> cause the most download%></li>
- <li><%_<big id="layer7-most-tx">0</big> cause the most upload%></li>
- <li><%_<big id="layer7-most-conn">0</big> cause the most connections%></li>
- </ul>
- </div>
- </div>
- <table id="layer7-data">
- <tr>
- <th width="20%"><%:Application%></th>
- <th width="10%"><%:Connections%></th>
- <th width="30%" colspan="2"><%:Download (Bytes / Packets)%></th>
- <th width="30%" colspan="2"><%:Upload (Bytes / Packets)%></th>
- </tr>
- </table>
-</div>
+ <div class="cbi-section" data-tab="ipv6" data-tab-title="<%:IPv6%>">
+ <div class="head">
+ <div class="pie">
+ <label><%:IPv4 vs. IPv6%></label>
+ <canvas id="ipv6-share-pie" width="200" height="200"></canvas>
+ </div>
-<div class="cbi-section" id="container.nlbw.ipv6" style="display:none">
- <div>
- <div class="pie">
- <label><%:IPv4 vs. IPv6%></label>
- <canvas id="ipv6-share-pie" width="200" height="200"></canvas>
- </div>
+ <div class="pie">
+ <label><%:Dualstack enabled hosts%></label>
+ <canvas id="ipv6-hosts-pie" width="200" height="200"></canvas>
+ </div>
- <div class="pie">
- <label><%:Dualstack enabled hosts%></label>
- <canvas id="ipv6-hosts-pie" width="200" height="200"></canvas>
+ <div class="kpi">
+ <ul>
+ <li><%_<big id="ipv6-hosts">0%</big> IPv6 support rate among hosts%></li>
+ <li><%_<big id="ipv6-share">0%</big> of the total traffic is IPv6%></li>
+ <li><%_<big id="ipv6-rx">0B</big> total IPv6 download%></li>
+ <li><%_<big id="ipv6-tx">0B</big> total IPv6 upload%></li>
+ </ul>
+ </div>
</div>
-
- <div class="kpi">
- <ul>
- <li><%_<big id="ipv6-hosts">0%</big> IPv6 support rate among hosts%></li>
- <li><%_<big id="ipv6-share">0%</big> of the total traffic is IPv6%></li>
- <li><%_<big id="ipv6-rx">0B</big> total IPv6 download%></li>
- <li><%_<big id="ipv6-tx">0B</big> total IPv6 upload%></li>
- </ul>
+ <div class="table" id="ipv6-data">
+ <div class="tr table-titles">
+ <div class="th left"><%:Host%></div>
+ <div class="th right"><%:MAC%></div>
+ <div class="th double right hide-xs"><%:Family%></div>
+ <div class="th double right"><%:Download (Bytes)%></div>
+ <div class="th double right"><%:Download (Packets)%></div>
+ <div class="th double right"><%:Upload (Bytes)%></div>
+ <div class="th double right"><%:Upload (Packets)%></div>
+ </div>
+ <div class="tr placeholder">
+ <div class="td">
+ <em class="spinning"><%:Collecting data...%></em>
+ </div>
+ </div>
</div>
</div>
- <table id="ipv6-data">
- <tr>
- <th width="10%" class="hostname"><%:Host%></th>
- <th width="5%"><%:MAC%></th>
- <th width="5%"><%:Family%></th>
- <th width="40%" colspan="2"><%:Download (Bytes / Packets)%></th>
- <th width="40%" colspan="2"><%:Upload (Bytes / Packets)%></th>
- </tr>
- </table>
-</div>
-<div class="cbi-section" id="container.nlbw.export" style="display:none">
- <ul>
- <li><a href="<%=url('admin/nlbw/data')%>?type=csv&#38;group_by=mac&#38;order_by=-rx,-tx"><%:CSV, grouped by MAC%></a></li>
- <li><a href="<%=url('admin/nlbw/data')%>?type=csv&#38;group_by=ip&#38;order_by=-rx,-tx"><%:CSV, grouped by IP%></a></li>
- <li><a href="<%=url('admin/nlbw/data')%>?type=csv&#38;group_by=layer7&#38;order_by=-rx,-tx"><%:CSV, grouped by protocol%></a></li>
- <li><a href="<%=url('admin/nlbw/data')%>?type=json"><%:JSON dump%></a></li>
- </ul>
+ <div class="cbi-section" data-tab="export" data-tab-title="<%:Export%>">
+ <ul>
+ <li><a href="<%=url('admin/nlbw/data')%>?type=csv&#38;group_by=mac&#38;order_by=-rx,-tx"><%:CSV, grouped by MAC%></a></li>
+ <li><a href="<%=url('admin/nlbw/data')%>?type=csv&#38;group_by=ip&#38;order_by=-rx,-tx"><%:CSV, grouped by IP%></a></li>
+ <li><a href="<%=url('admin/nlbw/data')%>?type=csv&#38;group_by=layer7&#38;order_by=-rx,-tx"><%:CSV, grouped by protocol%></a></li>
+ <li><a href="<%=url('admin/nlbw/data')%>?type=json"><%:JSON dump%></a></li>
+ </ul>
+ </div>
</div>
<script type="text/javascript">//<![CDATA[
- cbi_t_add('nlbw', 'traffic');
- cbi_t_add('nlbw', 'layer7');
- cbi_t_add('nlbw', 'ipv6');
- cbi_t_add('nlbw', 'export');
+ var hostInfo = <%=luci.util.serialize_json(luci.sys.net.host_hints())%>;
- XHR.get('<%=url("admin/nlbw/list")%>', null, function(xhr, res) {
+ XHR.get(L.url('admin/nlbw/list'), null, function(xhr, res) {
if (res !== null && typeof(res) === 'object' && res.length > 0) {
trafficPeriods = res;
@@ -1046,6 +170,20 @@ function bubbleDismiss()
};
xhr.send(null);
});
+
+ document.addEventListener('tooltip-open', function(ev) {
+ renderHostDetail.call(ev.detail.target, ev.target);
+ });
+
+ if ('ontouchstart' in window) {
+ document.addEventListener('touchstart', function(ev) {
+ var tooltip = document.querySelector('.cbi-tooltip');
+ if (tooltip === ev.target || tooltip.contains(ev.target))
+ return;
+
+ L.hideTooltip(ev);
+ });
+ }
//]]></script>
<%+footer%>
diff --git a/applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm b/applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm
index 91624f3b30..0aac36de87 100644
--- a/applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm
+++ b/applications/luci-app-olsr-services/luasrc/view/freifunk-services/services.htm
@@ -126,15 +126,20 @@ end
var tbody = document.getElementById('olsr_services');
if (tbody)
{
- var s = '';
+ var s = '<div class="tr cbi-section-table-titles">' +
+ '<div class="th cbi-section-table-cell"><%:Url%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Protocol%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Source%></div>' +
+ '</div>';
+
for (var idx = 0; idx < info.length; idx++)
{
var service = info[idx];
s += String.format(
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' +
- '<div class="td cbi-section-table-titles"><a href="%s">%s</a></div>' +
- '<div class="td cbi-section-table-titles">%s</div>' +
- '<div class="td cbi-section-table-titles"><a href="http://%s/cgi-bin-status.html">%s</a></div>' +
+ '<div class="td cbi-section-table-cell left"><a href="%s">%s</a></div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left"><a href="http://%s/cgi-bin-status.html">%s</a></div>' +
'</div>',
service.url, service.descr, service.proto, service.origin_link, service.origin || '?'
);
@@ -152,16 +157,13 @@ end
<fieldset class="cbi-section">
<legend><%:Internal services%></legend>
- <div class="table cbi-section-table">
- <div class="thead">
+ <div class="table cbi-section-table" id="olsr_services">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Url%></div>
<div class="th cbi-section-table-cell"><%:Protocol%></div>
<div class="th cbi-section-table-cell"><%:Source%></div>
</div>
- </div>
- <div class="tbody" id="olsr_services">
<%
for k, line in ipairs(services) do
local field = {}
@@ -178,13 +180,12 @@ end
%>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%>">
- <div class="td cbi-section-table-titles"><a href="<%=url%>"><%=descr%></a></div>
- <div class="td cbi-section-table-titles"><%=proto%></div>
- <div class="td cbi-section-table-titles"><a href="http://<%=origin_link%>/cgi-bin-status.html"><%=origin%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="<%=url%>"><%=descr%></a></div>
+ <div class="td cbi-section-table-cell left"><%=proto%></div>
+ <div class="td cbi-section-table-cell left"><a href="http://<%=origin_link%>/cgi-bin-status.html"><%=origin%></a></div>
</div>
<% i = ((i % 2) + 1)
end %>
- </div>
</div>
<br />
<%=last_update%>
diff --git a/applications/luci-app-olsr/luasrc/controller/olsr.lua b/applications/luci-app-olsr/luasrc/controller/olsr.lua
index dc424c0114..11e27d7c00 100644
--- a/applications/luci-app-olsr/luasrc/controller/olsr.lua
+++ b/applications/luci-app-olsr/luasrc/controller/olsr.lua
@@ -331,6 +331,8 @@ end
function action_interfaces()
local data, has_v4, has_v6, error = fetch_jsoninfo('interfaces')
+ local ntm = require "luci.model.network".init()
+
if error then
return
end
@@ -339,6 +341,13 @@ function action_interfaces()
return a.proto < b.proto
end
+ for k, v in ipairs(data) do
+ local interface = ntm:get_status_by_address(v.olsrInterface.ipAddress)
+ if interface then
+ v.interface = interface
+ end
+ end
+
table.sort(data, compare)
luci.template.render("status-olsr/interfaces", {iface=data, has_v4=has_v4, has_v6=has_v6})
end
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/hna.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/hna.htm
index f04d926918..34cf563363 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/hna.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/hna.htm
@@ -35,7 +35,12 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
var hnadiv = document.getElementById('olsrd_hna');
if (hnadiv)
{
- var s = '';
+ var s = '<div class="tr cbi-section-table-titles">' +
+ '<div class="th cbi-section-table-cell"><%:Announced network%></div>' +
+ '<div class="th cbi-section-table-cell"><%:OLSR gateway%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Validity Time%></div>' +
+ '</div>';
+
for (var idx = 0; idx < info.length; idx++)
{
var hna = info[idx];
@@ -62,9 +67,9 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
}
s += String.format(
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>', hna.destination + '/' + hna.genmask, linkgw + hostname, validity
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>', hna.destination + '/' + hna.genmask, linkgw + hostname, validity
)
s += '</div>'
}
@@ -80,21 +85,18 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
<fieldset class="cbi-section">
<legend><%:Overview of currently active OLSR host net announcements%></legend>
- <div class="table cbi-section-table">
- <div class="thead">
+ <div class="table cbi-section-table" id="olsrd_hna">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Announced network%></div>
<div class="th cbi-section-table-cell"><%:OLSR gateway%></div>
<div class="th cbi-section-table-cell"><%:Validity Time%></div>
</div>
- </div>
- <div class="tbody" id="olsrd_hna">
<% for k, route in ipairs(hna) do %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=hna[k].proto%>">
- <div class="td cbi-section-table-cell"><%=hna[k].destination%>/<%=hna[k].genmask%> </div>
- <div class="td cbi-section-table-cell">
+ <div class="td cbi-section-table-cell left"><%=hna[k].destination%>/<%=hna[k].genmask%> </div>
+ <div class="td cbi-section-table-cell left">
<% if hna[k].proto == '6' then %>
<a href="http://[<%=hna[k].gateway%>]/cgi-bin-status.html"><%=hna[k].gateway%></a>
<% else %>
@@ -110,12 +112,11 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
validity = '-'
end %>
- <div class="td cbi-section-table-cell"><%=validity%></div>
+ <div class="td cbi-section-table-cell left"><%=validity%></div>
</div>
<% i = ((i % 2) + 1)
end %>
- </div>
</div>
</fieldset>
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/interfaces.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/interfaces.htm
index 7506f07029..12f7cba967 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/interfaces.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/interfaces.htm
@@ -21,6 +21,7 @@ local i = 1
<div class="table cbi-section-table">
<div class="tr">
<div class="th cbi-section-table-cell"><%:Interface%></div>
+ <div class="th cbi-section-table-cell"><%:Device%></div>
<div class="th cbi-section-table-cell"><%:State%></div>
<div class="th cbi-section-table-cell"><%:MTU%></div>
<div class="th cbi-section-table-cell"><%:WLAN%></div>
@@ -32,13 +33,14 @@ local i = 1
<% for k, iface in ipairs(iface) do %>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=iface.proto%>">
- <div class="td cbi-section-table-cell"><%=iface.name%></div>
- <div class="td cbi-section-table-cell"><%=iface.olsrInterface.up and luci.i18n.translate('up') or luci.i18n.translate('down')%></div>
- <div class="td cbi-section-table-cell"><%=iface.olsrInterface.mtu%></div>
- <div class="td cbi-section-table-cell"><%=iface.olsrInterface.wireless and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
- <div class="td cbi-section-table-cell"><%=iface.olsrInterface.ipAddress%></div>
- <div class="td cbi-section-table-cell"><%=iface.olsrInterface.ipv4Address ~= '0.0.0.0' and iface.olsrInterface.ipv4Netmask%></div>
- <div class="td cbi-section-table-cell"><%=iface.olsrInterface.ipv4Address ~= '0.0.0.0' and iface.olsrInterface.ipv4Broadcast or iface.olsrInterface.ipv6Multicast%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.interface%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.name%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.olsrInterface.up and luci.i18n.translate('up') or luci.i18n.translate('down')%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.olsrInterface.mtu%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.olsrInterface.wireless and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.olsrInterface.ipAddress%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.olsrInterface.ipv4Address ~= '0.0.0.0' and iface.olsrInterface.ipv4Netmask%></div>
+ <div class="td cbi-section-table-cell left"><%=iface.olsrInterface.ipv4Address ~= '0.0.0.0' and iface.olsrInterface.ipv4Broadcast or iface.olsrInterface.ipv6Multicast%></div>
</div>
<% i = ((i % 2) + 1)
end %>
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/mid.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/mid.htm
index 9babd50a80..469d89111a 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/mid.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/mid.htm
@@ -38,8 +38,8 @@ local i = 1
%>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=mid.proto%>">
- <div class="td cbi-section-table-cell"><a href="http://<%=host%>/cgi-bin-status.html"><%=mid.main.ipAddress%></a></div>
- <div class="td cbi-section-table-cell"><%=aliases%></div>
+ <div class="td cbi-section-table-cell left"><a href="http://<%=host%>/cgi-bin-status.html"><%=mid.main.ipAddress%></a></div>
+ <div class="td cbi-section-table-cell left"><%=aliases%></div>
</div>
<% i = ((i % 2) + 1)
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/neighbors.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/neighbors.htm
index 29ea95694c..8cdda14916 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/neighbors.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/neighbors.htm
@@ -56,7 +56,17 @@ end
var nt = document.getElementById('olsr_neigh_table');
if (nt)
{
- var s = '';
+ var s = '<div class="tr cbi-section-table-cell">' +
+ '<div class="th cbi-section-table-cell"><%:Neighbour IP%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Hostname%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Interface%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Local interface IP%></div>' +
+ '<div class="th cbi-section-table-cell">LQ</div>' +
+ '<div class="th cbi-section-table-cell">NLQ</div>' +
+ '<div class="th cbi-section-table-cell">ETX</div>' +
+ '<div class="th cbi-section-table-cell">SNR</div>' +
+ '</div>';
+
for (var idx = 0; idx < info.length; idx++)
{
var neigh = info[idx];
@@ -64,34 +74,34 @@ end
if (neigh.proto == '6') {
s += String.format(
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
- '<div class="td cbi-section-table-titles" style="background-color:%s"><a href="http://[%s]/cgi-bin-status.html">%s</a></div>',
+ '<div class="td cbi-section-table-cell left" style="background-color:%s"><a href="http://[%s]/cgi-bin-status.html">%s</a></div>',
neigh.proto, neigh.dfgcolor, neigh.rip, neigh.rip
);
} else {
s += String.format(
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
- '<div class="td cbi-section-table-titles" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></div>',
+ '<div class="td cbi-section-table-cell left" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></div>',
neigh.proto, neigh.dfgcolor, neigh.rip, neigh.rip
);
}
if (neigh.hn) {
s += String.format(
- '<div class="td cbi-section-table-titles" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></div>',
+ '<div class="td cbi-section-table-cell left" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></div>',
neigh.dfgcolor, neigh.hn, neigh.hn
);
} else {
s += String.format(
- '<div class="td cbi-section-table-titles" style="background-color:%s">?</div>',
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">?</div>',
neigh.dfgcolor
);
}
s += String.format(
- '<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
- '<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
- '<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
- '<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
- '<div class="td cbi-section-table-titles" style="background-color:%s">%s</div>' +
- '<div class="td cbi-section-table-titles" style="background-color:%s" title="Signal: %s Noise: %s">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s" title="Signal: %s Noise: %s">%s</div>' +
'</div>',
neigh.dfgcolor, neigh.ifn, neigh.dfgcolor, neigh.lip, neigh.dfgcolor, neigh.lq, neigh.dfgcolor, neigh.nlq, neigh.color, neigh.cost, neigh.snr_color, neigh.signal, neigh.noise, neigh.snr || '?'
);
@@ -111,9 +121,8 @@ end
<fieldset class="cbi-section">
<legend><%:Overview of currently established OLSR connections%></legend>
- <div class="table cbi-section-table">
- <div class="thead">
- <div class="tr cbi-section-table-titles">
+ <div class="table cbi-section-table" id="olsr_neigh_table">
+ <div class="tr cbi-section-table-cell">
<div class="th cbi-section-table-cell"><%:Neighbour IP%></div>
<div class="th cbi-section-table-cell"><%:Hostname%></div>
<div class="th cbi-section-table-cell"><%:Interface%></div>
@@ -123,9 +132,7 @@ end
<div class="th cbi-section-table-cell">ETX</div>
<div class="th cbi-section-table-cell">SNR</div>
</div>
- </div>
- <div class="tbody" id="olsr_neigh_table">
<% local i = 1
for k, link in ipairs(links) do
link.linkCost = tonumber(link.linkCost) or 0
@@ -148,22 +155,21 @@ end
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=link.proto%>">
<% if link.proto == "6" then %>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://[<%=link.remoteIP%>]/cgi-bin-status.html"><%=link.remoteIP%></a></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><a href="http://[<%=link.remoteIP%>]/cgi-bin-status.html"><%=link.remoteIP%></a></div>
<% else %>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.remoteIP%>/cgi-bin-status.html"><%=link.remoteIP%></a></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.remoteIP%>/cgi-bin-status.html"><%=link.remoteIP%></a></div>
<% end %>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.hostname%>/cgi-bin-status.html"><%=link.hostname%></a></div>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=link.interface%></div>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=link.localIP%></div>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.linkQuality)%></div>
- <div class="td cbi-section-table-titles" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.neighborLinkQuality)%></div>
- <div class="td cbi-section-table-titles" style="background-color:<%=color%>"><%=string.format("%.3f", link.linkCost)%></div>
- <div class="td cbi-section-table-titles" style="background-color:<%=snr_color%>" title="Signal: <%=link.signal%> Noise: <%=link.noise%>"><%=link.snr%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.hostname%>/cgi-bin-status.html"><%=link.hostname%></a></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><%=link.interface%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><%=link.localIP%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.linkQuality)%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.neighborLinkQuality)%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=color%>"><%=string.format("%.3f", link.linkCost)%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=snr_color%>" title="Signal: <%=link.signal%> Noise: <%=link.noise%>"><%=link.snr%></div>
</div>
<%
i = ((i % 2) + 1)
end %>
- </div>
</div>
<br />
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/routes.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/routes.htm
index 4b733524a5..624047f40c 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/routes.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/routes.htm
@@ -13,7 +13,7 @@ local i = 1
if luci.http.formvalue("status") == "1" then
local rv = {}
for k, route in ipairs(routes) do
- local ETX = string.format("%.3f", tonumber(route.rtpMetricCost)/1024 or 0)
+ local ETX = string.format("%.3f", tonumber(route.etx) or 0)
rv[#rv+1] = {
hostname = route.hostname,
dest = route.destination,
@@ -43,21 +43,28 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
var rt = document.getElementById('olsrd_routes');
if (rt)
{
- var s = '';
+ var s = '<div class="tr cbi-section-table-cell">' +
+ '<div class="th cbi-section-table-cell"><%:Announced network%></div>' +
+ '<div class="th cbi-section-table-cell"><%:OLSR gateway%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Interface%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Metric%></div>' +
+ '<div class="th cbi-section-table-cell">ETX</div>' +
+ '</div>';
+
for (var idx = 0; idx < info.length; idx++)
{
var route = info[idx];
s += String.format(
'<div class="tr cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' +
- '<div class="td cbi-section-table-cell">%s/%s</div>' +
- '<div class="td cbi-section-table-cell">' +
+ '<div class="td cbi-section-table-cell left">%s/%s</div>' +
+ '<div class="td cbi-section-table-cell left">' +
'<a href="http://%s/cgi-bin-status.html">%s</a>',
route.proto, route.dest, route.genmask, route.gw, route.gw
)
if (route.hostname) {
- if (hna.proto == '6') {
+ if (route.proto == '6') {
s += String.format(
' / <a href="http://[%s]/cgi-bin-status.html">%s</a>',
route.hostname, route.hostname || '?'
@@ -72,9 +79,9 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
}
s += String.format(
'</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell" style="background-color:%s">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left" style="background-color:%s">%s</div>' +
'</div>',
route.interface, route.metric, route.color, route.etx || '?'
);
@@ -95,27 +102,23 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
<fieldset class="cbi-section">
<legend><%:Overview of currently known routes to other OLSR nodes%></legend>
-<div class="table cbi-section-table">
- <div class="thead">
- <div class="tr cbi-section-table-titles">
+<div class="table cbi-section-table" id="olsrd_routes">
+ <div class="tr cbi-section-table-cell">
<div class="th cbi-section-table-cell"><%:Announced network%></div>
<div class="th cbi-section-table-cell"><%:OLSR gateway%></div>
<div class="th cbi-section-table-cell"><%:Interface%></div>
<div class="th cbi-section-table-cell"><%:Metric%></div>
<div class="th cbi-section-table-cell">ETX</div>
</div>
- </div>
-
- <div class="tbody" id="olsrd_routes">
<% for k, route in ipairs(routes) do
- ETX = tonumber(route.rtpMetricCost)/1024 or '0'
+ ETX = tonumber(route.etx) or '0'
color = olsrtools.etx_color(ETX)
%>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>">
- <div class="td cbi-section-table-cell"><%=route.destination%>/<%=route.genmask%></div>
- <div class="td cbi-section-table-cell">
+ <div class="td cbi-section-table-cell left"><%=route.destination%>/<%=route.genmask%></div>
+ <div class="td cbi-section-table-cell left">
<% if route.proto == '6' then %>
<a href="http://[<%=route.gateway%>]/cgi-bin-status.html"><%=route.gateway%></a>
<% else %>
@@ -125,14 +128,13 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 },
/ <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.hostname%></a>
<% end %>
</div>
- <div class="td cbi-section-table-cell"><%=route.networkInterface%></div>
- <div class="td cbi-section-table-cell"><%=route.metric%></div>
- <div class="td cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", ETX)%></div>
+ <div class="td cbi-section-table-cell left"><%=route.networkInterface%></div>
+ <div class="td cbi-section-table-cell left"><%=route.metric%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=color%>"><%=string.format("%.3f", ETX)%></div>
</div>
<%
i = ((i % 2) + 1)
end %>
- </div>
</div>
<%+status-olsr/legend%>
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm
index ba36ce980a..8cd2088e42 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm
@@ -19,7 +19,7 @@ if luci.http.formvalue("status") == "1" then
local rv = {}
for k, gw in ipairs(gws.ipv4, gws.ipv6) do
gw.cost = tonumber(gw.cost)/1024 or 0
- if gw.cost == 4096 then
+ if gw.cost >= 100 then
gw.cost = 0
end
@@ -27,7 +27,7 @@ if luci.http.formvalue("status") == "1" then
proto = gw.IPv4 and '4' or '6',
originator = gw.originator,
selected = gw.selected and luci.i18n.translate('yes') or luci.i18n.translate('no'),
- cost = string.format("%.3f", gw.cost),
+ cost = gw.cost > 0 and string.format("%.3f", gw.cost) or luci.i18n.translate('infinate'),
hops = gw.hops,
uplink = gw.uplink,
downlink = gw.downlink,
@@ -51,7 +51,18 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
var smartgwdiv = document.getElementById('olsrd_smartgw');
if (smartgwdiv)
{
- var s = '';
+ var s = '<div class="tr cbi-section-table-titles">' +
+ '<div class="th cbi-section-table-cell"><%:Gateway%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Selected%></div>' +
+ '<div class="th cbi-section-table-cell"><%:ETX%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Hops%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Uplink%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Downlink%></div>' +
+ '<div class="th cbi-section-table-cell"><%:IPv4%></div>' +
+ '<div class="th cbi-section-table-cell"><%:IPv6%></div>' +
+ '<div class="th cbi-section-table-cell"><%:Prefix%></div>' +
+ '</div>';
+
for (var idx = 0; idx < info.length; idx++)
{
var smartgw = info[idx];
@@ -64,15 +75,15 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
}
s += String.format(
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>' +
- '<div class="td cbi-section-table-cell">%s</div>',
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>' +
+ '<div class="td cbi-section-table-cell left">%s</div>',
linkgw, smartgw.selected, smartgw.cost, smartgw.hops, smartgw.uplink, smartgw.downlink, smartgw.v4, smartgw.v6, smartgw.prefix
)
s += '</div>'
@@ -83,9 +94,6 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
);
//]]></script>
-
-<%+header%>
-
<h2 name="content"><%:SmartGW announcements%></h2>
<div id="togglebuttons"></div>
@@ -94,8 +102,7 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
<fieldset class="cbi-section">
<legend><%:Overview of smart gateways in this network%></legend>
- <div class="table cbi-section-table">
- <div class="thead">
+ <div class="table cbi-section-table" id="olsrd_smartgw">
<div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Gateway%></div>
<div class="th cbi-section-table-cell"><%:Selected%></div>
@@ -106,39 +113,35 @@ XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 },
<div class="th cbi-section-table-cell"><%:IPv4%></div>
<div class="th cbi-section-table-cell"><%:IPv6%></div>
<div class="th cbi-section-table-cell"><%:Prefix%></div>
-
- </div>
</div>
- <div class="tbody" id="olsrd_smartgw">
- <% for k, gw in ipairs(gws) do
+ <% for k, gw in ipairs(gws.ipv4, gws.ipv6) do
gw.cost = tonumber(gw.cost)/1024 or 0
- if gw.cost == 4096 then
+ if gw.cost >= 100 then
gw.cost = 0
end
%>
<div class="tr cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=proto%>">
<% if gw.proto == '6' then %>
- <div class="td cbi-section-table-cell"><a href="http://[<%=gw.originator%>]/cgi-bin-status.html"><%=gw.originator%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="http://[<%=gw.originator%>]/cgi-bin-status.html"><%=gw.originator%></a></div>
<% else %>
- <div class="td cbi-section-table-cell"><a href="http://<%=gw.originator%>/cgi-bin-status.html"><%=gw.originator%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="http://<%=gw.originator%>/cgi-bin-status.html"><%=gw.originator%></a></div>
<% end %>
- <div class="td cbi-section-table-cell"><%=gw.selected and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
- <div class="td cbi-section-table-cell"><%=string.format("%.3f", gw.cost)%></div>
- <div class="td cbi-section-table-cell"><%=gw.hops%></div>
- <div class="td cbi-section-table-cell"><%=gw.uplink%></div>
- <div class="td cbi-section-table-cell"><%=gw.downlink%></div>
- <div class="td cbi-section-table-cell"><%=gw.IPv4 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
- <div class="td cbi-section-table-cell"><%=gw.IPv6 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
- <div class="td cbi-section-table-cell"><%=gw.prefix%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.selected and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.cost > 0 and string.format("%.3f", gw.cost) or luci.i18n.translate('infinate')%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.hops%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.uplink%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.downlink%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.IPv4 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.IPv6 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></div>
+ <div class="td cbi-section-table-cell left"><%=gw.prefix%></div>
</div>
<% i = ((i % 2) + 1)
end %>
- </div>
</div>
</fieldset>
diff --git a/applications/luci-app-olsr/luasrc/view/status-olsr/topology.htm b/applications/luci-app-olsr/luasrc/view/status-olsr/topology.htm
index 02fdfddac3..fe673c4111 100644
--- a/applications/luci-app-olsr/luasrc/view/status-olsr/topology.htm
+++ b/applications/luci-app-olsr/luasrc/view/status-olsr/topology.htm
@@ -27,7 +27,7 @@ local olsrtools = require "luci.tools.olsr"
</div>
<% for k, route in ipairs(routes) do
- local cost = string.format("%.3f", tonumber(route.tcEdgeCost/1024) or 0)
+ local cost = string.format("%.3f", tonumber(route.tcEdgeCost) or 0)
local color = olsrtools.etx_color(tonumber(cost))
local lq = string.format("%.3f", tonumber(route.linkQuality) or 0)
local nlq = string.format("%.3f", tonumber(route.neighborLinkQuality) or 0)
@@ -37,19 +37,19 @@ local olsrtools = require "luci.tools.olsr"
<% if route.proto == "6" then %>
- <div class="td cbi-section-table-cell"><a href="http://[<%=route.destinationIP%>]/cgi-bin-status.html"><%=route.destinationIP%></a></div>
- <div class="td cbi-section-table-cell"><a href="http://[<%=route.lastHopIP%>]/cgi-bin-status.html"><%=route.lastHopIP%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="http://[<%=route.destinationIP%>]/cgi-bin-status.html"><%=route.destinationIP%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="http://[<%=route.lastHopIP%>]/cgi-bin-status.html"><%=route.lastHopIP%></a></div>
<% else %>
- <div class="td cbi-section-table-cell"><a href="http://<%=route.destinationIP%>/cgi-bin-status.html"><%=route.destinationIP%></a></div>
- <div class="td cbi-section-table-cell"><a href="http://<%=route.lastHopIP%>/cgi-bin-status.html"><%=route.lastHopIP%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="http://<%=route.destinationIP%>/cgi-bin-status.html"><%=route.destinationIP%></a></div>
+ <div class="td cbi-section-table-cell left"><a href="http://<%=route.lastHopIP%>/cgi-bin-status.html"><%=route.lastHopIP%></a></div>
<%end%>
- <div class="td cbi-section-table-cell"><%=lq%></div>
- <div class="td cbi-section-table-cell"><%=nlq%></div>
- <div class="td cbi-section-table-cell" style="background-color:<%=color%>"><%=cost%></div>
+ <div class="td cbi-section-table-cell left"><%=lq%></div>
+ <div class="td cbi-section-table-cell left"><%=nlq%></div>
+ <div class="td cbi-section-table-cell left" style="background-color:<%=color%>"><%=cost%></div>
</div>
<% i = ((i % 2) + 1)
diff --git a/applications/luci-app-olsr/po/de/olsr.po b/applications/luci-app-olsr/po/de/olsr.po
index 2f387413ff..15b8412a26 100644
--- a/applications/luci-app-olsr/po/de/olsr.po
+++ b/applications/luci-app-olsr/po/de/olsr.po
@@ -1201,6 +1201,10 @@ msgstr ""
#~ msgid "Status"
#~ msgstr "Status"
+#: application/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm:97
+msgid "Selected"
+msgstr "Ausgewählt"
+
#~ msgid "Device"
#~ msgstr "Schnittstelle"
diff --git a/applications/luci-app-olsr/po/en/olsr.po b/applications/luci-app-olsr/po/en/olsr.po
index bd7ee6fcbf..a009f84854 100644
--- a/applications/luci-app-olsr/po/en/olsr.po
+++ b/applications/luci-app-olsr/po/en/olsr.po
@@ -1088,6 +1088,10 @@ msgstr ""
msgid "yes"
msgstr ""
+#: application/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm:97
+msgid "Selected"
+msgstr ""
+
#~ msgid ""
#~ "Make sure that OLSRd is running, the \"txtinfo\" plugin is loaded, "
#~ "configured on port 2006 and accepts connections from \"127.0.0.1\"."
diff --git a/applications/luci-app-olsr/po/templates/olsr.pot b/applications/luci-app-olsr/po/templates/olsr.pot
index 49f5d63501..521af613ed 100644
--- a/applications/luci-app-olsr/po/templates/olsr.pot
+++ b/applications/luci-app-olsr/po/templates/olsr.pot
@@ -1073,3 +1073,8 @@ msgstr ""
#: applications/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm:135
msgid "yes"
msgstr ""
+
+#: application/luci-app-olsr/luasrc/view/status-olsr/smartgw.htm:97
+msgid "Selected"
+msgstr ""
+
diff --git a/applications/luci-app-opkg/po/zh-cn/opkg.po b/applications/luci-app-opkg/po/zh-cn/opkg.po
index bb30fa00be..076ee49b6a 100644
--- a/applications/luci-app-opkg/po/zh-cn/opkg.po
+++ b/applications/luci-app-opkg/po/zh-cn/opkg.po
@@ -1,9 +1,10 @@
#
# Yangfl <mmyangfl@gmail.com>, 2018.
+# Zheng Qian <sotux82@gmail.com>, 2018.
#
msgid ""
msgstr ""
-"PO-Revision-Date: 2018-08-18 12:39+0800\n"
+"PO-Revision-Date: 2018-12-11 09:07+0800\n"
"Last-Translator: Yangfl <mmyangfl@gmail.com>\n"
"Language-Team: <debian-l10n-chinese@lists.debian.org>\n"
"Language: \n"
@@ -18,7 +19,7 @@ msgstr "动作"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:795
msgid "Automatically remove unused dependencies"
-msgstr ""
+msgstr "自动移除未使用的依赖"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:935
msgid "Available"
@@ -31,6 +32,9 @@ msgid ""
"custom repository entries. The configuration in the other files may be "
"changed but is usually not preserved by <em>sysupgrade</em>."
msgstr ""
+"以下列出了 <em>opkg</em> 所使用的各个配置文件。<em>opkg.conf</em> 用于全局配"
+"置,<em>customfeeds.conf</em> 用于描述自定义仓库。其他配置文件的变更在系统升"
+"级时默认不被保留。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:666
#: applications/luci-app-opkg/luasrc/view/opkg.htm:711
@@ -41,16 +45,15 @@ msgstr "取消"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:917
msgid "Clear"
-msgstr ""
+msgstr "清除"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:930
-#, fuzzy
msgid "Configure opkg…"
-msgstr "配置"
+msgstr "配置 opkg…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:643
msgid "Dependencies"
-msgstr ""
+msgstr "依赖"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:649
#: applications/luci-app-opkg/luasrc/view/opkg.htm:781
@@ -60,7 +63,7 @@ msgstr "描述"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:654
msgid "Details for package <em>%h</em>"
-msgstr ""
+msgstr "软件包 <em>%h</em> 详情"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:851
msgid "Dismiss"
@@ -68,20 +71,19 @@ msgstr "解除"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:311
msgid "Displaying %d-%d of %d"
-msgstr ""
+msgstr "正在显示 %d-%d,共 %d"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:921
msgid "Download and install package"
msgstr "下载并安装软件包"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:837
-#, fuzzy
msgid "Errors"
msgstr "错误"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:821
msgid "Executing package manager"
-msgstr ""
+msgstr "正在执行软件包管理器"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:915
msgid "Filter"
@@ -99,65 +101,58 @@ msgstr "安装"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:262
#: applications/luci-app-opkg/luasrc/view/opkg.htm:470
#: applications/luci-app-opkg/luasrc/view/opkg.htm:936
-#, fuzzy
msgid "Installed"
-msgstr "安装"
+msgstr "已安装"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:695
msgid ""
"Installing packages from untrusted sources is a potential security risk! "
"Really attempt to install <em>%h</em>?"
-msgstr ""
+msgstr "从未信任的源安装软件包有潜在的安全隐患!您确定要安装 <em>%h</em> 吗?"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:251
-#, fuzzy
msgid "Install…"
-msgstr "安装"
+msgstr "安装…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:720
-#, fuzzy
msgid "Loading configuration data…"
-msgstr "开始应用配置…"
+msgstr "载入配置数据…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:858
msgid "Loading package information…"
-msgstr ""
+msgstr "载入软件包信息…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:705
-#, fuzzy
msgid "Manually install package"
-msgstr "下载并安装软件包"
+msgstr "手动安装软件包"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:458
msgid "Needs upgrade"
-msgstr ""
+msgstr "需要升级"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:944
msgid "Next page"
-msgstr ""
+msgstr "下一页"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:324
msgid "No information available"
msgstr "无可用信息"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:312
-#, fuzzy
msgid "No packages"
-msgstr "查找软件包"
+msgstr "没有软件包"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:328
msgid "No packages matching \"<strong>%h</strong>\"."
-msgstr ""
+msgstr "没有匹配“<strong>%h</strong>”的软件包。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:490
-#, fuzzy
msgid "Not available"
-msgstr "可用数"
+msgstr "不可用"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:475
-#, fuzzy
msgid "Not installed"
-msgstr "未连接"
+msgstr "未安装"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:923
msgid "OK"
@@ -166,7 +161,6 @@ msgstr "确认"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:719
#: applications/luci-app-opkg/luasrc/view/opkg.htm:751
#: applications/luci-app-opkg/luasrc/view/opkg.htm:761
-#, fuzzy
msgid "OPKG Configuration"
msgstr "OPKG 配置"
@@ -175,17 +169,16 @@ msgid "Package name"
msgstr "软件包名称"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:922
-#, fuzzy
msgid "Package name or URL…"
-msgstr "软件包名称"
+msgstr "软件包名称或 URL…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:942
msgid "Previous page"
-msgstr ""
+msgstr "上一页"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:702
msgid "Really attempt to install <em>%h</em>?"
-msgstr ""
+msgstr "真的要安装 <em>%h</em> 吗?"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:241
#: applications/luci-app-opkg/luasrc/view/opkg.htm:808
@@ -194,11 +187,11 @@ msgstr "移除"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:786
msgid "Remove package <em>%h</em>"
-msgstr ""
+msgstr "移除软件包 <em>%h</em>"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:639
msgid "Require approx. %.1024mB size for %d package(s) to install."
-msgstr ""
+msgstr "需要大约 %.1024mB 空间来安装 %d 个软件包。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:465
#: applications/luci-app-opkg/luasrc/view/opkg.htm:483
@@ -206,15 +199,17 @@ msgid ""
"Require version %h %h,\n"
"installed %h"
msgstr ""
+"要求 %h %h 版本,\n"
+"已安装 %h"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:488
msgid ""
"Required dependency package <em>%h</em> is not available in any repository."
-msgstr ""
+msgstr "依赖的软件包 <em>%h</em> 在所有仓库都未提供。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:456
msgid "Requires update to %h %h"
-msgstr ""
+msgstr "需要更新到 %h %h"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:329
msgid "Reset"
@@ -225,9 +220,8 @@ msgid "Save"
msgstr "保存"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:752
-#, fuzzy
msgid "Saving configuration data…"
-msgstr "开始应用配置…"
+msgstr "正在保存配置数据…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:657
#: applications/luci-app-opkg/luasrc/view/opkg.htm:789
@@ -245,42 +239,40 @@ msgstr "软件包"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:842
msgid "The <em>opkg %h</em> command failed with code <code>%d</code>."
-msgstr ""
+msgstr "<em>opkg %h</em> 命令失败,代码 <code>%d</code>。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:461
msgid ""
"The installed version of package <em>%h</em> is not compatible, require %s "
"while %s is installed."
-msgstr ""
+msgstr "已安装的软件包 <em>%h</em> 版本不兼容,要求 %s 而 %s 已安装。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:698
msgid "The package <em>%h</em> is not available in any configured repository."
-msgstr ""
+msgstr "软件包 <em>%h</em> 在所有已配置的仓库中都不存在。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:478
msgid ""
"The repository version of package <em>%h</em> is not compatible, require %s "
"but only %s is available."
-msgstr ""
+msgstr "软件包 <em>%h</em> 在仓库中的版本不兼容,要求 %s 但仅可提供 %s。"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:916
msgid "Type to filter…"
-msgstr ""
+msgstr "输入以过滤…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:928
-#, fuzzy
msgid "Update lists…"
-msgstr "刷新列表"
+msgstr "更新列表…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:937
-#, fuzzy
msgid "Updates"
-msgstr "刷新列表"
+msgstr "更新"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:233
#: applications/luci-app-opkg/luasrc/view/opkg.htm:257
msgid "Upgrade…"
-msgstr ""
+msgstr "升级…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:656
#: applications/luci-app-opkg/luasrc/view/opkg.htm:788
@@ -291,12 +283,11 @@ msgstr "版本"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:467
#: applications/luci-app-opkg/luasrc/view/opkg.htm:485
msgid "Version incompatible"
-msgstr ""
+msgstr "版本不兼容"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:823
-#, fuzzy
msgid "Waiting for the <em>opkg %h</em> command to complete…"
-msgstr "等待命令执行完成…"
+msgstr "等待命令 <em>opkg %h</em> 执行完成…"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:617
#: applications/luci-app-opkg/luasrc/view/opkg.htm:777
@@ -307,9 +298,9 @@ msgstr "未知"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:615
#: applications/luci-app-opkg/luasrc/view/opkg.htm:775
msgid "~%.1024mB compressed"
-msgstr ""
+msgstr "~%.1024mB 已压缩"
#: applications/luci-app-opkg/luasrc/view/opkg.htm:613
#: applications/luci-app-opkg/luasrc/view/opkg.htm:773
msgid "~%.1024mB installed"
-msgstr ""
+msgstr "~%.1024mB 已安装"
diff --git a/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm b/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm
index 2b526a31d7..fdb3f27abc 100644
--- a/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm
+++ b/applications/luci-app-radicale/luasrc/view/radicale/tabmap_nsections.htm
@@ -3,8 +3,12 @@
<%- end end -%>
<div class="cbi-map" id="cbi-<%=self.config%>">
- <% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
- <% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
+ <% if self.title and #self.title > 0 then %>
+ <h2 name="content"><%=self.title%></h2>
+ <% end %>
+ <% if self.description and #self.description > 0 then %>
+ <div class="cbi-map-descr"><%=self.description%></div>
+ <% end %>
<%- if firstmap and (applymap or confirmmap) then -%>
<%+cbi/apply_widget%>
<% cbi_apply_widget() %>
@@ -21,23 +25,18 @@
<%- end -%>
<% if self.tabbed then %>
- <ul class="cbi-tabmenu map">
- <%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
- <% for i, section in ipairs(self.children) do %>
- <%- if not self.selected_tab then self.selected_tab = section.sectiontype end %>
- <li id="tab.m-<%=self.config%>.<%=section.section or section.sectiontype%>" class="cbi-tab<%=(section.sectiontype == self.selected_tab) and '' or '-disabled'%>">
- <a onclick="this.blur(); return cbi_t_switch('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')" href="<%=REQUEST_URI%>?tab.m-<%=self.config%>=<%=section.section or section.sectiontype%>"><%=section.title or section.section or section.sectiontype %></a>
- <% if section.sectiontype == self.selected_tab then %><input type="hidden" id="tab.m-<%=self.config%>" name="tab.m-<%=self.config%>" value="<%=section.section or section.sectiontype%>" /><% end %>
- </li>
+ <div>
+ <% for i, section in ipairs(self.children) do
+ tab = section.section or section.sectiontype %>
+ <div class="cbi-tabcontainer"<%=
+ attr("id", "container.m-%s.%s" %{ self.config, tab }) ..
+ attr("data-tab", tab) ..
+ attr("data-tab-title", section.title or tab)
+ %>>
+ <% section:render() %>
+ </div>
<% end %>
- </ul>
- <br />
- <% for i, section in ipairs(self.children) do %>
- <div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.section or section.sectiontype%>"<% if section.sectiontype ~= self.selected_tab then %> style="display:none"<% end %>>
- <% section:render() %>
- </div>
- <script type="text/javascript">cbi_t_add('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')</script>
- <% end %>
+ </div>
<% else %>
<%- self:render_children() %>
diff --git a/collections/luci-ssl-nginx/Makefile b/collections/luci-ssl-nginx/Makefile
index 549c44af11..facae6dbac 100644
--- a/collections/luci-ssl-nginx/Makefile
+++ b/collections/luci-ssl-nginx/Makefile
@@ -16,7 +16,7 @@ LUCI_DESCRIPTION:=LuCI with OpenSSL as the SSL backend (libustream-openssl). \
LUCI_DEPENDS:= \
+nginx-ssl +nginx-mod-luci-ssl +luci-mod-admin-full +luci-theme-bootstrap \
+luci-app-firewall +luci-proto-ppp +libiwinfo-lua +IPV6:luci-proto-ipv6 \
- +rpcd-mod-rrdns +libustream-openssl +openssl-util
+ +rpcd-mod-rrdns +openssl-util
PKG_LICENSE:=Apache-2.0
diff --git a/libs/luci-lib-httpclient/luasrc/httpclient.lua b/libs/luci-lib-httpclient/luasrc/httpclient.lua
index 3e8d7277d7..79ce41294c 100644
--- a/libs/luci-lib-httpclient/luasrc/httpclient.lua
+++ b/libs/luci-lib-httpclient/luasrc/httpclient.lua
@@ -9,9 +9,10 @@ local util = require "luci.util"
local table = require "table"
local http = require "luci.http"
local date = require "luci.http.date"
+local ip = require "luci.ip"
-local type, pairs, ipairs, tonumber = type, pairs, ipairs, tonumber
-local unpack = unpack
+local type, pairs, ipairs, tonumber, tostring = type, pairs, ipairs, tonumber, tostring
+local unpack, string = unpack, string
module "luci.httpclient"
@@ -25,7 +26,7 @@ function chunksource(sock, buffer)
if not newblock then
return nil, code
end
- buffer = buffer .. newblock
+ buffer = buffer .. newblock
_, endp, count = buffer:find("^([0-9a-fA-F]+);?.-\r\n")
end
count = tonumber(count, 16)
@@ -62,17 +63,17 @@ end
function request_to_buffer(uri, options)
local source, code, msg = request_to_source(uri, options)
local output = {}
-
+
if not source then
return nil, code, msg
end
-
+
source, code = ltn12.pump.all(source, (ltn12.sink.table(output)))
-
+
if not source then
return nil, code
end
-
+
return table.concat(output)
end
@@ -83,7 +84,7 @@ function request_to_source(uri, options)
elseif status ~= 200 and status ~= 206 then
return nil, status, buffer
end
-
+
if response.headers["Transfer-Encoding"] == "chunked" then
return chunksource(sock, buffer)
else
@@ -91,67 +92,115 @@ function request_to_source(uri, options)
end
end
+function parse_url(uri)
+ local url, rest, tmp = {}, nil, nil
+
+ url.scheme, rest = uri:match("^(%w+)://(.+)$")
+ if not (url.scheme and rest) then
+ return nil
+ end
+
+ url.auth, tmp = rest:match("^([^@]+)@(.+)$")
+ if url.auth and tmp then
+ rest = tmp
+ end
+
+ url.host, tmp = rest:match("^%[([0-9a-fA-F:]+)%](.*)$")
+ if url.host and tmp then
+ url.ip6addr = ip.IPv6(url.host)
+ if not url.ip6addr then
+ return nil
+ end
+ url.host = string.format("[%s]", url.ip6addr:string())
+ rest = tmp
+ else
+ url.host, tmp = rest:match("^(%d+%.%d+%.%d+%.%d+)(.*)$")
+ if url.host and tmp then
+ url.ipaddr = ip.IPv4(url.host)
+ if not url.ipaddr then
+ return nil
+ end
+ url.host = url.ipaddr:string()
+ rest = tmp
+ else
+ url.host, tmp = rest:match("^([0-9a-zA-Z%.%-]+)(.*)$")
+ if url.host and tmp then
+ rest = tmp
+ else
+ return nil
+ end
+ end
+ end
+
+ url.port, tmp = rest:match("^:(%d+)(.*)$")
+ if url.port and tmp then
+ url.port = tonumber(url.port)
+ rest = tmp
+ if url.port < 1 or url.port > 65535 then
+ return nil
+ end
+ end
+
+ if url.scheme == "http" then
+ url.port = url.port or 80
+ url.default_port = (url.port == 80)
+ elseif url.scheme == "https" then
+ url.port = url.port or 443
+ url.default_port = (url.port == 443)
+ end
+
+ if rest == "" then
+ url.path = "/"
+ else
+ url.path = rest
+ end
+
+ return url
+end
+
--
-- GET HTTP-resource
--
function request_raw(uri, options)
options = options or {}
- local pr, auth, host, port, path
if options.params then
uri = uri .. '?' .. http.urlencode_params(options.params)
end
- if uri:find("%[") then
- if uri:find("@") then
- pr, auth, host, port, path = uri:match("(%w+)://(.+)@(%b[]):?([0-9]*)(.*)")
- host = host:sub(2,-2)
- else
- pr, host, port, path = uri:match("(%w+)://(%b[]):?([0-9]*)(.*)")
- host = host:sub(2,-2)
- end
- else
- if uri:find("@") then
- pr, auth, host, port, path =
- uri:match("(%w+)://(.+)@([%w-.]+):?([0-9]*)(.*)")
- else
- pr, host, port, path = uri:match("(%w+)://([%w-.]+):?([0-9]*)(.*)")
- end
- end
+ local url = parse_url(uri)
- if not host then
+ if not url then
return nil, -1, "unable to parse URI"
end
-
- if pr ~= "http" and pr ~= "https" then
+
+ if url.scheme ~= "http" and url.scheme ~= "https" then
return nil, -2, "protocol not supported"
end
-
- port = #port > 0 and port or (pr == "https" and 443 or 80)
- path = #path > 0 and path or "/"
-
+
options.depth = options.depth or 10
local headers = options.headers or {}
local protocol = options.protocol or "HTTP/1.1"
headers["User-Agent"] = headers["User-Agent"] or "LuCI httpclient 0.1"
-
+
if headers.Connection == nil then
headers.Connection = "close"
end
-
- if auth and not headers.Authorization then
- headers.Authorization = "Basic " .. nixio.bin.b64encode(auth)
+
+ if url.auth and not headers.Authorization then
+ headers.Authorization = "Basic " .. nixio.bin.b64encode(url.auth)
end
- local sock, code, msg = nixio.connect(host, port)
+ local addr = tostring(url.ip6addr or url.ipaddr or url.host)
+ local sock, code, msg = nixio.connect(addr, url.port)
if not sock then
return nil, code, msg
end
-
+
sock:setsockopt("socket", "sndtimeo", options.sndtimeo or 15)
sock:setsockopt("socket", "rcvtimeo", options.rcvtimeo or 15)
-
- if pr == "https" then
+
+ if url.scheme == "https" then
local tls = options.tls_context or nixio.tls()
sock = tls:create(sock)
local stat, code, error = sock:connect()
@@ -160,11 +209,12 @@ function request_raw(uri, options)
end
end
- -- Pre assemble fixes
+ -- Pre assemble fixes
if protocol == "HTTP/1.1" then
- headers.Host = headers.Host or host
+ headers.Host = headers.Host or
+ (url.default_port and url.host or string.format("%s:%d", url.host, url.port))
end
-
+
if type(options.body) == "table" then
options.body = http.urlencode_params(options.body)
end
@@ -175,7 +225,7 @@ function request_raw(uri, options)
"application/x-www-form-urlencoded"
options.method = options.method or "POST"
end
-
+
if type(options.body) == "function" then
options.method = options.method or "POST"
end
@@ -185,12 +235,12 @@ function request_raw(uri, options)
for _, c in ipairs(options.cookies) do
local cdo = c.flags.domain
local cpa = c.flags.path
- if (cdo == host or cdo == "."..host or host:sub(-#cdo) == cdo)
- and (cpa == path or cpa == "/" or cpa .. "/" == path:sub(#cpa+1))
- and (not c.flags.secure or pr == "https")
+ if (cdo == url.host or cdo == "."..url.host or url.host:sub(-#cdo) == cdo)
+ and (cpa == url.path or cpa == "/" or cpa .. "/" == url.path:sub(#cpa+1))
+ and (not c.flags.secure or url.scheme == "https")
then
cookiedata[#cookiedata+1] = c.key .. "=" .. c.value
- end
+ end
end
if headers["Cookie"] then
headers["Cookie"] = headers["Cookie"] .. "; " .. table.concat(cookiedata, "; ")
@@ -200,8 +250,8 @@ function request_raw(uri, options)
end
-- Assemble message
- local message = {(options.method or "GET") .. " " .. path .. " " .. protocol}
-
+ local message = {(options.method or "GET") .. " " .. url.path .. " " .. protocol}
+
for k, v in pairs(headers) do
if type(v) == "string" or type(v) == "number" then
message[#message+1] = k .. ": " .. v
@@ -214,10 +264,10 @@ function request_raw(uri, options)
message[#message+1] = ""
message[#message+1] = ""
-
+
-- Send request
sock:sendall(table.concat(message, "\r\n"))
-
+
if type(options.body) == "string" then
sock:sendall(options.body)
elseif type(options.body) == "function" then
@@ -227,27 +277,27 @@ function request_raw(uri, options)
return unpack(res)
end
end
-
+
-- Create source and fetch response
local linesrc = sock:linesource()
local line, code, error = linesrc()
-
+
if not line then
sock:close()
return nil, code, error
end
-
+
local protocol, status, msg = line:match("^([%w./]+) ([0-9]+) (.*)")
-
+
if not protocol then
sock:close()
return nil, -3, "invalid response magic: " .. line
end
-
+
local response = {
status = line, headers = {}, code = 0, cookies = {}, uri = uri
}
-
+
line = linesrc()
while line and line ~= "" do
local key, val = line:match("^([%w-]+)%s?:%s?(.*)")
@@ -262,32 +312,32 @@ function request_raw(uri, options)
end
line = linesrc()
end
-
+
if not line then
sock:close()
return nil, -4, "protocol error"
end
-
+
-- Parse cookies
if response.headers["Set-Cookie"] then
local cookies = response.headers["Set-Cookie"]
for _, c in ipairs(type(cookies) == "table" and cookies or {cookies}) do
local cobj = cookie_parse(c)
- cobj.flags.path = cobj.flags.path or path:match("(/.*)/?[^/]*")
+ cobj.flags.path = cobj.flags.path or url.path:match("(/.*)/?[^/]*")
if not cobj.flags.domain or cobj.flags.domain == "" then
- cobj.flags.domain = host
+ cobj.flags.domain = url.host
response.cookies[#response.cookies+1] = cobj
else
local hprt, cprt = {}, {}
-
+
-- Split hostnames and save them in reverse order
- for part in host:gmatch("[^.]*") do
+ for part in url.host:gmatch("[^.]*") do
table.insert(hprt, 1, part)
end
for part in cobj.flags.domain:gmatch("[^.]*") do
table.insert(cprt, 1, part)
end
-
+
local valid = true
for i, part in ipairs(cprt) do
-- If parts are different and no wildcard
@@ -309,8 +359,8 @@ function request_raw(uri, options)
end
end
end
-
- -- Follow
+
+ -- Follow
response.code = tonumber(status)
if response.code and options.depth > 0 then
if (response.code == 301 or response.code == 302 or response.code == 307)
@@ -319,20 +369,21 @@ function request_raw(uri, options)
if not nuri then
return nil, -5, "invalid reference"
end
- if not nuri:find("https?://") then
- nuri = pr .. "://" .. host .. ":" .. port .. nuri
+ if not nuri:match("^%w+://") then
+ nuri = url.default_port and string.format("%s://%s%s", url.scheme, url.host, nuri)
+ or string.format("%s://%s:%d%s", url.scheme, url.host, url.port, nuri)
end
-
+
options.depth = options.depth - 1
if options.headers then
options.headers.Host = nil
end
sock:close()
-
+
return request_raw(nuri, options)
end
end
-
+
return response.code, response, linesrc(true)..sock:readall(), sock
end
diff --git a/modules/luci-base/htdocs/luci-static/resources/cbi.js b/modules/luci-base/htdocs/luci-static/resources/cbi.js
index 635740a70c..61b83e8294 100644
--- a/modules/luci-base/htdocs/luci-static/resources/cbi.js
+++ b/modules/luci-base/htdocs/luci-static/resources/cbi.js
@@ -12,7 +12,6 @@
*/
var cbi_d = [];
-var cbi_t = [];
var cbi_strings = { path: {}, label: {} };
function s8(bytes, off) {
@@ -727,13 +726,13 @@ function cbi_d_update() {
parent.parentNode.style.display = (parent.options.length <= 1) ? 'none' : '';
}
- if (entry && entry.parent) {
- if (!cbi_t_update())
- cbi_tag_last(parent);
- }
+ if (entry && entry.parent)
+ cbi_tag_last(parent);
if (state)
cbi_d_update();
+ else if (parent)
+ parent.dispatchEvent(new CustomEvent('dependency-update', { bubbles: true }));
}
function cbi_init() {
@@ -1045,75 +1044,6 @@ function cbi_dynlist_init(dl, datatype, optional, choices)
cbi_dynlist_init.prototype = CBIDynamicList;
-function cbi_t_add(section, tab) {
- var t = document.getElementById('tab.' + section + '.' + tab);
- var c = document.getElementById('container.' + section + '.' + tab);
-
- if (t && c) {
- cbi_t[section] = (cbi_t[section] || [ ]);
- cbi_t[section][tab] = { 'tab': t, 'container': c, 'cid': c.id };
- }
-}
-
-function cbi_t_switch(section, tab) {
- if (cbi_t[section] && cbi_t[section][tab]) {
- var o = cbi_t[section][tab];
- var h = document.getElementById('tab.' + section);
-
- for (var tid in cbi_t[section]) {
- var o2 = cbi_t[section][tid];
-
- if (o.tab.id != o2.tab.id) {
- o2.tab.classList.remove('cbi-tab');
- o2.tab.classList.add('cbi-tab-disabled');
- o2.container.style.display = 'none';
- }
- else {
- if(h)
- h.value = tab;
-
- o2.tab.classList.remove('cbi-tab-disabled');
- o2.tab.classList.add('cbi-tab');
- o2.container.style.display = 'block';
- }
- }
- }
-
- return false;
-}
-
-function cbi_t_update() {
- var hl_tabs = [ ];
- var updated = false;
-
- for (var sid in cbi_t)
- for (var tid in cbi_t[sid]) {
- var t = cbi_t[sid][tid].tab;
- var c = cbi_t[sid][tid].container;
-
- if (!c.firstElementChild) {
- t.style.display = 'none';
- }
- else if (t.style.display == 'none') {
- t.style.display = '';
- t.classList.add('cbi-tab-highlighted');
- hl_tabs.push(t);
- }
-
- cbi_tag_last(c);
- updated = true;
- }
-
- if (hl_tabs.length > 0)
- window.setTimeout(function() {
- for (var i = 0; i < hl_tabs.length; i++)
- hl_tabs[i].classList.remove('cbi-tab-highlighted');
- }, 750);
-
- return updated;
-}
-
-
function cbi_validate_form(form, errmsg)
{
/* if triggered by a section removal or addition, don't validate */
diff --git a/modules/luci-base/htdocs/luci-static/resources/luci.js b/modules/luci-base/htdocs/luci-static/resources/luci.js
index 04c460182f..4cb8bf4e5d 100644
--- a/modules/luci-base/htdocs/luci-static/resources/luci.js
+++ b/modules/luci-base/htdocs/luci-static/resources/luci.js
@@ -129,10 +129,16 @@
tooltipDiv.style.top = y + 'px';
tooltipDiv.style.left = x + 'px';
tooltipDiv.style.opacity = 1;
+
+ tooltipDiv.dispatchEvent(new CustomEvent('tooltip-open', {
+ bubbles: true,
+ detail: { target: target }
+ }));
},
hideTooltip: function(ev) {
- if (ev.target === tooltipDiv || ev.relatedTarget === tooltipDiv)
+ if (ev.target === tooltipDiv || ev.relatedTarget === tooltipDiv ||
+ tooltipDiv.contains(ev.target) || tooltipDiv.contains(ev.relatedTarget))
return;
if (tooltipTimeout !== null) {
@@ -142,6 +148,8 @@
tooltipDiv.style.opacity = 0;
tooltipTimeout = window.setTimeout(function() { tooltipDiv.removeAttribute('style'); }, 250);
+
+ tooltipDiv.dispatchEvent(new CustomEvent('tooltip-close', { bubbles: true }));
},
@@ -173,6 +181,175 @@
}
};
+ /* Tabs */
+ LuCI.prototype.tabs = {
+ init: function() {
+ var groups = [], prevGroup = null, currGroup = null;
+
+ document.querySelectorAll('[data-tab]').forEach(function(tab) {
+ var parent = tab.parentNode;
+
+ if (!parent.hasAttribute('data-tab-group'))
+ parent.setAttribute('data-tab-group', groups.length);
+
+ currGroup = +parent.getAttribute('data-tab-group');
+
+ if (currGroup !== prevGroup) {
+ prevGroup = currGroup;
+
+ if (!groups[currGroup])
+ groups[currGroup] = [];
+ }
+
+ groups[currGroup].push(tab);
+ });
+
+ for (var i = 0; i < groups.length; i++)
+ this.initTabGroup(groups[i]);
+
+ document.addEventListener('dependency-update', this.updateTabs.bind(this));
+
+ this.updateTabs();
+
+ if (!groups.length)
+ this.setActiveTabId(-1, -1);
+ },
+
+ initTabGroup: function(panes) {
+ if (!Array.isArray(panes) || panes.length === 0)
+ return;
+
+ var menu = E('ul', { 'class': 'cbi-tabmenu' }),
+ group = panes[0].parentNode,
+ groupId = +group.getAttribute('data-tab-group'),
+ selected = null;
+
+ for (var i = 0, pane; pane = panes[i]; i++) {
+ var name = pane.getAttribute('data-tab'),
+ title = pane.getAttribute('data-tab-title'),
+ active = pane.getAttribute('data-tab-active') === 'true';
+
+ menu.appendChild(E('li', {
+ 'class': active ? 'cbi-tab' : 'cbi-tab-disabled',
+ 'data-tab': name
+ }, E('a', {
+ 'href': '#',
+ 'click': this.switchTab.bind(this)
+ }, title)));
+
+ if (active)
+ selected = i;
+ }
+
+ group.parentNode.insertBefore(menu, group);
+
+ if (selected === null) {
+ selected = this.getActiveTabId(groupId);
+
+ if (selected < 0 || selected >= panes.length)
+ selected = 0;
+
+ menu.childNodes[selected].classList.add('cbi-tab');
+ menu.childNodes[selected].classList.remove('cbi-tab-disabled');
+ panes[selected].setAttribute('data-tab-active', 'true');
+
+ this.setActiveTabId(groupId, selected);
+ }
+ },
+
+ getActiveTabState: function() {
+ var page = document.body.getAttribute('data-page');
+
+ try {
+ var val = JSON.parse(window.sessionStorage.getItem('tab'));
+ if (val.page === page && Array.isArray(val.groups))
+ return val;
+ }
+ catch(e) {}
+
+ window.sessionStorage.removeItem('tab');
+ return { page: page, groups: [] };
+ },
+
+ getActiveTabId: function(groupId) {
+ return +this.getActiveTabState().groups[groupId] || 0;
+ },
+
+ setActiveTabId: function(groupId, tabIndex) {
+ try {
+ var state = this.getActiveTabState();
+ state.groups[groupId] = tabIndex;
+
+ window.sessionStorage.setItem('tab', JSON.stringify(state));
+ }
+ catch (e) { return false; }
+
+ return true;
+ },
+
+ updateTabs: function(ev) {
+ document.querySelectorAll('[data-tab-title]').forEach(function(pane) {
+ var menu = pane.parentNode.previousElementSibling,
+ tab = menu.querySelector('[data-tab="%s"]'.format(pane.getAttribute('data-tab'))),
+ n_errors = pane.querySelectorAll('.cbi-input-invalid').length;
+
+ if (!pane.firstElementChild) {
+ tab.style.display = 'none';
+ tab.classList.remove('flash');
+ }
+ else if (tab.style.display === 'none') {
+ tab.style.display = '';
+ requestAnimationFrame(function() { tab.classList.add('flash') });
+ }
+
+ if (n_errors) {
+ tab.setAttribute('data-errors', n_errors);
+ tab.setAttribute('data-tooltip', _('%d invalid field(s)').format(n_errors));
+ tab.setAttribute('data-tooltip-style', 'error');
+ }
+ else {
+ tab.removeAttribute('data-errors');
+ tab.removeAttribute('data-tooltip');
+ }
+ });
+ },
+
+ switchTab: function(ev) {
+ var tab = ev.target.parentNode,
+ name = tab.getAttribute('data-tab'),
+ menu = tab.parentNode,
+ group = menu.nextElementSibling,
+ groupId = +group.getAttribute('data-tab-group'),
+ index = 0;
+
+ ev.preventDefault();
+
+ if (!tab.classList.contains('cbi-tab-disabled'))
+ return;
+
+ menu.querySelectorAll('[data-tab]').forEach(function(tab) {
+ tab.classList.remove('cbi-tab');
+ tab.classList.remove('cbi-tab-disabled');
+ tab.classList.add(
+ tab.getAttribute('data-tab') === name ? 'cbi-tab' : 'cbi-tab-disabled');
+ });
+
+ group.childNodes.forEach(function(pane) {
+ if (L.dom.matches(pane, '[data-tab]')) {
+ if (pane.getAttribute('data-tab') === name) {
+ pane.setAttribute('data-tab-active', 'true');
+ L.tabs.setActiveTabId(groupId, index);
+ }
+ else {
+ pane.setAttribute('data-tab-active', 'false');
+ }
+
+ index++;
+ }
+ });
+ }
+ };
+
/* DOM manipulation */
LuCI.prototype.dom = {
elem: function(e) {
@@ -308,6 +485,11 @@
}
};
+ /* Setup */
+ LuCI.prototype.setupDOM = function(ev) {
+ this.tabs.init();
+ };
+
function LuCI(env) {
this.env = env;
@@ -321,6 +503,8 @@
document.addEventListener('mouseout', this.hideTooltip.bind(this), true);
document.addEventListener('focus', this.showTooltip.bind(this), true);
document.addEventListener('blur', this.hideTooltip.bind(this), true);
+
+ document.addEventListener('DOMContentLoaded', this.setupDOM.bind(this));
}
window.LuCI = LuCI;
diff --git a/modules/luci-base/luasrc/view/cbi/map.htm b/modules/luci-base/luasrc/view/cbi/map.htm
index d65a161673..cda4d3530c 100644
--- a/modules/luci-base/luasrc/view/cbi/map.htm
+++ b/modules/luci-base/luasrc/view/cbi/map.htm
@@ -3,25 +3,25 @@
<%- end end -%>
<div class="cbi-map" id="cbi-<%=self.config%>">
- <% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
- <% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
+ <% if self.title and #self.title > 0 then %>
+ <h2 name="content"><%=self.title%></h2>
+ <% end %>
+ <% if self.description and #self.description > 0 then %>
+ <div class="cbi-map-descr"><%=self.description%></div>
+ <% end %>
<% if self.tabbed then %>
- <ul class="cbi-tabmenu map">
- <%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
- <% for i, section in ipairs(self.children) do %>
- <%- if not self.selected_tab then self.selected_tab = section.sectiontype end %>
- <li id="tab.m-<%=self.config%>.<%=section.section or section.sectiontype%>" class="cbi-tab<%=(section.sectiontype == self.selected_tab) and '' or '-disabled'%>">
- <a onclick="this.blur(); return cbi_t_switch('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')" href="<%=REQUEST_URI%>?tab.m-<%=self.config%>=<%=section.section or section.sectiontype%>"><%=section.title or section.section or section.sectiontype %></a>
- <% if section.sectiontype == self.selected_tab then %><input type="hidden" id="tab.m-<%=self.config%>" name="tab.m-<%=self.config%>" value="<%=section.section or section.sectiontype%>" /><% end %>
- </li>
+ <div>
+ <% for i, section in ipairs(self.children) do
+ tab = section.section or section.sectiontype %>
+ <div class="cbi-tabcontainer"<%=
+ attr("id", "container.m-%s.%s" %{ self.config, tab }) ..
+ attr("data-tab", tab) ..
+ attr("data-tab-title", section.title or tab)
+ %>>
+ <% section:render() %>
+ </div>
<% end %>
- </ul>
- <% for i, section in ipairs(self.children) do %>
- <div class="cbi-tabcontainer" id="container.m-<%=self.config%>.<%=section.section or section.sectiontype%>"<% if section.sectiontype ~= self.selected_tab then %> style="display:none"<% end %>>
- <% section:render() %>
- </div>
- <script type="text/javascript">cbi_t_add('m-<%=self.config%>', '<%=section.section or section.sectiontype%>')</script>
- <% end %>
+ </div>
<% if not self.save then -%>
<div class="cbi-section-error">
diff --git a/modules/luci-base/luasrc/view/cbi/nsection.htm b/modules/luci-base/luasrc/view/cbi/nsection.htm
index 63abc57734..14232e3d94 100644
--- a/modules/luci-base/luasrc/view/cbi/nsection.htm
+++ b/modules/luci-base/luasrc/view/cbi/nsection.htm
@@ -11,7 +11,6 @@
<input type="submit" class="cbi-button" name="cbi.rns.<%=self.config%>.<%=section%>" value="<%:Delete%>" />
</div>
<%- end %>
- <%+cbi/tabmenu%>
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
<%+cbi/ucisection%>
</div>
diff --git a/modules/luci-base/luasrc/view/cbi/tabcontainer.htm b/modules/luci-base/luasrc/view/cbi/tabcontainer.htm
index 38c435d6a1..7fcb835783 100644
--- a/modules/luci-base/luasrc/view/cbi/tabcontainer.htm
+++ b/modules/luci-base/luasrc/view/cbi/tabcontainer.htm
@@ -1,7 +1,14 @@
-<% for tab, data in pairs(self.tabs) do %>
- <div class="cbi-tabcontainer" id="container.<%=self.config%>.<%=section%>.<%=tab%>"<% if tab ~= self.selected_tab then %> style="display:none"<% end %>>
- <% if data.description then %><div class="cbi-tab-descr"><%=data.description%></div><% end %>
+<% for _, tab in ipairs(self.tab_names) do data = self.tabs[tab] %>
+ <div class="cbi-tabcontainer"<%=
+ attr("id", "container.%s.%s.%s" %{ self.config, section, tab }) ..
+ attr("data-tab", tab) ..
+ attr("data-tab-title", data.title) ..
+ attr("data-tab-active", tostring(tab == self.selected_tab))
+ %>>
+ <% if data.description then %>
+ <div class="cbi-tab-descr"><%=data.description%></div>
+ <% end %>
+
<% self:render_tab(tab, section, scope or {}) %>
</div>
- <script type="text/javascript">cbi_t_add('<%=self.config%>.<%=section%>', '<%=tab%>')</script>
<% end %>
diff --git a/modules/luci-base/luasrc/view/cbi/tabmenu.htm b/modules/luci-base/luasrc/view/cbi/tabmenu.htm
deleted file mode 100644
index 06c1414bf3..0000000000
--- a/modules/luci-base/luasrc/view/cbi/tabmenu.htm
+++ /dev/null
@@ -1,12 +0,0 @@
-<%- if self.tabs then %>
- <ul class="cbi-tabmenu">
- <%- self.selected_tab = luci.http.formvalue("tab." .. self.config .. "." .. section) %>
- <%- for _, tab in ipairs(self.tab_names) do if #self.tabs[tab].childs > 0 then %>
- <%- if not self.selected_tab then self.selected_tab = tab end %>
- <li id="tab.<%=self.config%>.<%=section%>.<%=tab%>" class="cbi-tab<%=(tab == self.selected_tab) and '' or '-disabled'%>">
- <a onclick="this.blur(); return cbi_t_switch('<%=self.config%>.<%=section%>', '<%=tab%>')" href="<%=REQUEST_URI%>?tab.<%=self.config%>.<%=section%>=<%=tab%>"><%=self.tabs[tab].title%></a>
- <% if tab == self.selected_tab then %><input type="hidden" id="tab.<%=self.config%>.<%=section%>" name="tab.<%=self.config%>.<%=section%>" value="<%=tab%>" /><% end %>
- </li>
- <% end end -%>
- </ul>
-<% end -%>
diff --git a/modules/luci-base/luasrc/view/cbi/tsection.htm b/modules/luci-base/luasrc/view/cbi/tsection.htm
index 1a13df0c04..547a793329 100644
--- a/modules/luci-base/luasrc/view/cbi/tsection.htm
+++ b/modules/luci-base/luasrc/view/cbi/tsection.htm
@@ -18,8 +18,6 @@
<h3><%=section:upper()%></h3>
<%- end %>
- <%+cbi/tabmenu%>
-
<div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>">
<%+cbi/ucisection%>
</div>
diff --git a/modules/luci-mod-status/luasrc/controller/admin/status.lua b/modules/luci-mod-status/luasrc/controller/admin/status.lua
index 63b9390775..0d955c95fe 100644
--- a/modules/luci-mod-status/luasrc/controller/admin/status.lua
+++ b/modules/luci-mod-status/luasrc/controller/admin/status.lua
@@ -52,22 +52,12 @@ function dump_iptables(family, table)
local s
for s in lines do
if s == table then
- local ipt = io.popen(
- "/usr/sbin/%stables -w -t %s --line-numbers -nxvL"
- %{ prefix, table })
-
- if ipt then
- luci.http.prepare_content("text/plain")
-
- while true do
- s = ipt:read(1024)
- if not s then break end
- luci.http.write(s)
- end
-
- ipt:close()
- return
- end
+ luci.http.prepare_content("text/plain")
+ luci.sys.process.exec({
+ "/usr/sbin/%stables" % prefix, "-w", "-t", table,
+ "--line-numbers", "-nxvL"
+ }, luci.http.write)
+ return
end
end
end
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index.htm b/modules/luci-mod-status/luasrc/view/admin_status/index.htm
index b11956a8af..465226fe09 100644
--- a/modules/luci-mod-status/luasrc/view/admin_status/index.htm
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index.htm
@@ -11,29 +11,24 @@
local stat = require "luci.tools.status"
local ver = require "luci.version"
- local has_ipv6 = fs.access("/proc/net/ipv6_route")
- local has_dhcp = fs.access("/etc/config/dhcp")
- local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0)
+ if luci.http.formvalue("status") == "1" then
- local sysinfo = luci.util.ubus("system", "info") or { }
- local boardinfo = luci.util.ubus("system", "board") or { }
- local unameinfo = nixio.uname() or { }
+ local sysinfo = luci.util.ubus("system", "info") or { }
- local meminfo = sysinfo.memory or {
- total = 0,
- free = 0,
- buffered = 0,
- shared = 0
- }
+ local meminfo = sysinfo.memory or {
+ total = 0,
+ free = 0,
+ buffered = 0,
+ shared = 0
+ }
- local swapinfo = sysinfo.swap or {
- total = 0,
- free = 0
- }
+ local swapinfo = sysinfo.swap or {
+ total = 0,
+ free = 0
+ }
- local has_dsl = fs.access("/etc/init.d/dsl_control")
+ local has_dsl = fs.access("/etc/init.d/dsl_control")
- if luci.http.formvalue("status") == "1" then
local ntm = require "luci.model.network".init()
local wan_nets = ntm:get_wan_networks()
local wan6_nets = ntm:get_wan6_networks()
@@ -133,98 +128,19 @@
<h2 name="content"><%:Status%></h2>
-<div class="cbi-section">
- <h3><%:System%></h3>
-
- <div class="table" width="100%">
- <div class="tr"><div class="td left" width="33%"><%:Hostname%></div><div class="td left"><%=luci.sys.hostname() or "?"%></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Model%></div><div class="td left"><%=pcdata(boardinfo.model or "?")%></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Architecture%></div><div class="td left"><%=pcdata(boardinfo.system or "?")%></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Firmware Version%></div><div class="td left">
- <%=pcdata(ver.distname)%> <%=pcdata(ver.distversion)%> /
- <%=pcdata(ver.luciname)%> (<%=pcdata(ver.luciversion)%>)
- </div></div>
- <div class="tr"><div class="td left" width="33%"><%:Kernel Version%></div><div class="td left"><%=unameinfo.release or "?"%></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Local Time%></div><div class="td left" id="localtime">-</div></div>
- <div class="tr"><div class="td left" width="33%"><%:Uptime%></div><div class="td left" id="uptime">-</div></div>
- <div class="tr"><div class="td left" width="33%"><%:Load Average%></div><div class="td left" id="loadavg">-</div></div>
- </div>
-</div>
-
-<div class="cbi-section">
- <h3><%:Memory%></h3>
-
- <div class="table" width="100%">
- <div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left"><div id="memtotal" class="cbi-progressbar" title="-"><div></div></div></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left"><div id="memfree" class="cbi-progressbar" title="-"><div></div></div></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Buffered%></div><div class="td left"><div id="membuff" class="cbi-progressbar" title="-"><div></div></div></div></div>
- </div>
-</div>
-
-<% if swapinfo.total > 0 then %>
-<div class="cbi-section">
- <h3><%:Swap%></h3>
-
- <div class="table" width="100%">
- <div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left"><div id="swaptotal" class="cbi-progressbar" title="-"><div></div></div></div></div>
- <div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left"><div id="swapfree" class="cbi-progressbar" title="-"><div></div></div></div></div>
- </div>
-</div>
-<% end %>
-
-<div class="cbi-section">
- <h3><%:Network%></h3>
-
- <div id="upstream_status_table" class="network-status-table">
- <p><em><%:Collecting data...%></em></p>
- </div>
-
- <div class="table" width="100%">
- <div class="tr"><div class="td left" width="33%"><%:Active Connections%></div><div class="td left"><div id="conns" class="cbi-progressbar" title="-"><div></div></div></div></div>
- </div>
-</div>
-
-<%
- if has_dhcp then
- include("lease_status")
- end
-%>
-
-<% if has_dsl then %>
-<div class="cbi-section">
- <h3><%:DSL%></h3>
-
- <div id="dsl_status_table" class="network-status-table">
- <p><em><%:Collecting data...%></em></p>
- </div>
-</div>
-<% end %>
-
-<% if has_wifi then %>
-<div class="cbi-section">
- <h3><%:Wireless%></h3>
-
- <div id="wifi_status_table" class="network-status-table">
- <p><em><%:Collecting data...%></em></p>
- </div>
-</div>
-
-<div class="cbi-section">
- <h3><%:Associated Stations%></h3>
-
- <%+wifi_assoclist%>
-</div>
-<% end %>
-
<%-
local incdir = util.libpath() .. "/view/admin_status/index/"
if fs.access(incdir) then
- local inc
+ local _, inc
+ local includes = {}
for inc in fs.dir(incdir) do
if inc:match("%.htm$") then
- include("admin_status/index/" .. inc:gsub("%.htm$", ""))
+ includes[#includes + 1] = inc:gsub("%.htm$", "")
end
end
+ for _, inc in luci.util.vspairs(includes) do
+ include("admin_status/index/" .. inc)
+ end
end
-%>
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index/10-system.htm b/modules/luci-mod-status/luasrc/view/admin_status/index/10-system.htm
new file mode 100644
index 0000000000..994550ec2b
--- /dev/null
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index/10-system.htm
@@ -0,0 +1,29 @@
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%
+ local boardinfo = luci.util.ubus("system", "board") or { }
+ local unameinfo = nixio.uname() or { }
+ local ver = require "luci.version"
+%>
+
+<div class="cbi-section">
+ <h3><%:System%></h3>
+
+ <div class="table" width="100%">
+ <div class="tr"><div class="td left" width="33%"><%:Hostname%></div><div class="td left"><%=luci.sys.hostname() or "?"%></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Model%></div><div class="td left"><%=pcdata(boardinfo.model or "?")%></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Architecture%></div><div class="td left"><%=pcdata(boardinfo.system or "?")%></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Firmware Version%></div><div class="td left">
+ <%=pcdata(ver.distname)%> <%=pcdata(ver.distversion)%> /
+ <%=pcdata(ver.luciname)%> (<%=pcdata(ver.luciversion)%>)
+ </div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Kernel Version%></div><div class="td left"><%=unameinfo.release or "?"%></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Local Time%></div><div class="td left" id="localtime">-</div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Uptime%></div><div class="td left" id="uptime">-</div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Load Average%></div><div class="td left" id="loadavg">-</div></div>
+ </div>
+</div>
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index/20-memory.htm b/modules/luci-mod-status/luasrc/view/admin_status/index/20-memory.htm
new file mode 100644
index 0000000000..13774704fe
--- /dev/null
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index/20-memory.htm
@@ -0,0 +1,31 @@
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%
+ local sysinfo = luci.util.ubus("system", "info") or { }
+ local has_swap = sysinfo.swap and sysinfo.swap.total > 0 or false
+%>
+
+<div class="cbi-section">
+ <h3><%:Memory%></h3>
+
+ <div class="table" width="100%">
+ <div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left"><div id="memtotal" class="cbi-progressbar" title="-"><div></div></div></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left"><div id="memfree" class="cbi-progressbar" title="-"><div></div></div></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Buffered%></div><div class="td left"><div id="membuff" class="cbi-progressbar" title="-"><div></div></div></div></div>
+ </div>
+</div>
+
+<% if has_swap then %>
+<div class="cbi-section">
+ <h3><%:Swap%></h3>
+
+ <div class="table" width="100%">
+ <div class="tr"><div class="td left" width="33%"><%:Total Available%></div><div class="td left"><div id="swaptotal" class="cbi-progressbar" title="-"><div></div></div></div></div>
+ <div class="tr"><div class="td left" width="33%"><%:Free%></div><div class="td left"><div id="swapfree" class="cbi-progressbar" title="-"><div></div></div></div></div>
+ </div>
+</div>
+<% end %>
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index/30-network.htm b/modules/luci-mod-status/luasrc/view/admin_status/index/30-network.htm
new file mode 100644
index 0000000000..945a31b2e5
--- /dev/null
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index/30-network.htm
@@ -0,0 +1,17 @@
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<div class="cbi-section">
+ <h3><%:Network%></h3>
+
+ <div id="upstream_status_table" class="network-status-table">
+ <p><em><%:Collecting data...%></em></p>
+ </div>
+
+ <div class="table" width="100%">
+ <div class="tr"><div class="td left" width="33%"><%:Active Connections%></div><div class="td left"><div id="conns" class="cbi-progressbar" title="-"><div></div></div></div></div>
+ </div>
+</div>
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index/40-dhcp-leases.htm b/modules/luci-mod-status/luasrc/view/admin_status/index/40-dhcp-leases.htm
new file mode 100644
index 0000000000..aaf3661442
--- /dev/null
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index/40-dhcp-leases.htm
@@ -0,0 +1,14 @@
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%
+ local fs = require "nixio.fs"
+ local has_dhcp = fs.access("/etc/config/dhcp")
+
+ if has_dhcp then
+ include("lease_status")
+ end
+%>
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index/50-dsl.htm b/modules/luci-mod-status/luasrc/view/admin_status/index/50-dsl.htm
new file mode 100644
index 0000000000..f37bf147a3
--- /dev/null
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index/50-dsl.htm
@@ -0,0 +1,20 @@
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%
+ local fs = require "nixio.fs"
+ local has_dsl = fs.access("/etc/init.d/dsl_control")
+%>
+
+<% if has_dsl then %>
+<div class="cbi-section">
+ <h3><%:DSL%></h3>
+
+ <div id="dsl_status_table" class="network-status-table">
+ <p><em><%:Collecting data...%></em></p>
+ </div>
+</div>
+<% end %>
diff --git a/modules/luci-mod-status/luasrc/view/admin_status/index/60-wifi.htm b/modules/luci-mod-status/luasrc/view/admin_status/index/60-wifi.htm
new file mode 100644
index 0000000000..7338bc77f1
--- /dev/null
+++ b/modules/luci-mod-status/luasrc/view/admin_status/index/60-wifi.htm
@@ -0,0 +1,26 @@
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%
+ local fs = require "nixio.fs"
+ local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0)
+%>
+
+<% if has_wifi then %>
+<div class="cbi-section">
+ <h3><%:Wireless%></h3>
+
+ <div id="wifi_status_table" class="network-status-table">
+ <p><em><%:Collecting data...%></em></p>
+ </div>
+</div>
+
+<div class="cbi-section">
+ <h3><%:Associated Stations%></h3>
+
+ <%+wifi_assoclist%>
+</div>
+<% end %>
diff --git a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css
index 3dfac33849..966e5e4fa1 100644
--- a/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css
+++ b/themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css
@@ -482,7 +482,6 @@ select,
border-radius: 3px;
position: relative;
pointer-events: none;
- word-break: break-all;
}
.cbi-dynlist > .item::after {
@@ -1054,6 +1053,7 @@ header .dropdown-menu a.hover,
text-decoration: none;
border-radius: 4px 4px 0 0;
line-height: 25px;
+ outline: none;
}
.tabs > li:not(.active):hover, .cbi-tabmenu > .cbi-tab-disabled:hover {
@@ -1065,6 +1065,18 @@ header .dropdown-menu a.hover,
background: linear-gradient(#eee 90%, #ddd 100%);
}
+.cbi-tab-disabled[data-errors]::after {
+ content: attr(data-errors);
+ background: #c43c35;
+ color: #fff;
+ min-width: 12px;
+ line-height: 14px;
+ border-radius: 7px;
+ text-align: center;
+ margin: 0 5px 0 0;
+ padding: 1px 2px;
+}
+
.cbi-tabmenu.map {
margin: 0;
}
@@ -2201,3 +2213,16 @@ html body.apply-overlay-active {
background: url(../resources/icons/loading.gif) no-repeat center;
background-size: 16px;
}
+
+[data-tab-title] {
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+}
+
+[data-tab-active="true"] {
+ opacity: 1;
+ height: auto;
+ overflow: visible;
+ transition: opacity .25s ease-in;
+}
diff --git a/themes/luci-theme-freifunk-generic/htdocs/luci-static/freifunk-generic/cascade.css b/themes/luci-theme-freifunk-generic/htdocs/luci-static/freifunk-generic/cascade.css
index 04f2941c98..590eb3d979 100644
--- a/themes/luci-theme-freifunk-generic/htdocs/luci-static/freifunk-generic/cascade.css
+++ b/themes/luci-theme-freifunk-generic/htdocs/luci-static/freifunk-generic/cascade.css
@@ -693,6 +693,18 @@ ul.cbi-tabmenu + .cbi-section-node {
margin-top: -.5em;
}
+[data-tab-title] {
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+}
+
+[data-tab-active="true"] {
+ opacity: 1;
+ height: auto;
+ overflow: visible;
+ transition: opacity .25s ease-in;
+}
div.cbi-tab-descr {
background-image: url(/luci-static/resources/cbi/help.gif);
diff --git a/themes/luci-theme-material/htdocs/luci-static/material/cascade.css b/themes/luci-theme-material/htdocs/luci-static/material/cascade.css
index 8283657038..dc56911366 100644
--- a/themes/luci-theme-material/htdocs/luci-static/material/cascade.css
+++ b/themes/luci-theme-material/htdocs/luci-static/material/cascade.css
@@ -1,653 +1,899 @@
/**
- * Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI
+ * Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI
*
- * luci-theme-material
- * Copyright 2015 Lutty Yang <lutty@wcan.in>
+ * luci-theme-material
+ * Copyright 2015 Lutty Yang <lutty@wcan.in>
*
- * Have a bug? Please create an issue here on GitHub!
- * https://github.com/LuttyYang/luci-theme-material/issues
+ * Have a bug? Please create an issue here on GitHub!
+ * https://github.com/LuttyYang/luci-theme-material/issues
*
- * luci-theme-bootstrap:
- * Copyright 2008 Steven Barth <steven@midlink.org>
- * Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
- * Copyright 2012 David Menting <david@nut-bolt.nl>
+ * luci-theme-bootstrap:
+ * Copyright 2008 Steven Barth <steven@midlink.org>
+ * Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright 2012 David Menting <david@nut-bolt.nl>
*
- * MUI:
- * https://github.com/muicss/mui
+ * MUI:
+ * https://github.com/muicss/mui
*
- * Licensed to the public under the Apache License 2.0
+ * Pure CSS ripple effect:
+ * https://github.com/mladenplavsic/css-ripple-effect
+ *
+ * Licensed to the public under the Apache License 2.0
*/
/*
- * Include custom css
+ * Include custom css
*/
@import url("custom.css");
/*
- * Font generate by Icomoon<icomoon.io>
+ * Font generate by Icomoon<icomoon.io>
*/
@font-face {
- font-family: 'icomoon';
- src: url('fonts/font.eot');
- src: url('fonts/font.eot') format('embedded-opentype'),
- url('fonts/font.ttf') format('truetype'),
- url('fonts/font.woff') format('woff'),
- url('fonts/font.svg') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-.table { display: table; position: relative; }
-.tr { display: table-row; }
-.thead { display: table-header-group; }
-.tbody { display: table-row-group; }
-.tfoot { display: table-footer-group; }
-.td, .th {
- vertical-align: middle;
- text-align: center;
- display: table-cell;
- padding: .5em;
+ font-family: "icomoon";
+ font-weight: normal;
+ font-style: normal;
+ src: url("fonts/font.eot");
+ src: url("fonts/font.eot") format("embedded-opentype"),
+ url("fonts/font.ttf") format("truetype"),
+ url("fonts/font.woff") format("woff"),
+ url("fonts/font.svg") format("svg");
+}
+
+::-webkit-scrollbar {
+ width: 10px;
+ height: 10px;
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #9e9e9e;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #757575;
+}
+
+::-webkit-scrollbar-thumb:active {
+ background: #424242;
+}
+
+.table {
+ position: relative;
+ display: table;
+}
+
+.tr {
+ display: table-row;
+}
+.thead {
+ display: table-header-group;
+}
+
+.tbody {
+ display: table-row-group;
+}
+
+.tfoot {
+ display: table-footer-group;
+}
+
+.td,
+.th {
+ line-height: normal;
+ display: table-cell;
+ padding: .5em;
+ text-align: center;
+ vertical-align: middle;
}
.th {
- font-weight: bold;
+ font-weight: bold;
}
.tr.placeholder {
- height: 4em;
+ height: 4em;
}
.tr.placeholder > .td {
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- text-align: center;
- line-height: 3em;
- background: inherit;
-}
-
-.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; }
-.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; }
-
-.col-1 { flex: 1 1 30px !important; -webkit-flex: 1 1 30px !important; }
-.col-2 { flex: 2 2 60px !important; -webkit-flex: 2 2 60px !important; }
-.col-3 { flex: 3 3 90px !important; -webkit-flex: 3 3 90px !important; }
-.col-4 { flex: 4 4 120px !important; -webkit-flex: 4 4 120px !important; }
-.col-5 { flex: 5 5 150px !important; -webkit-flex: 5 5 150px !important; }
-.col-6 { flex: 6 6 180px !important; -webkit-flex: 6 6 180px !important; }
-.col-7 { flex: 7 7 210px !important; -webkit-flex: 7 7 210px !important; }
-.col-8 { flex: 8 8 240px !important; -webkit-flex: 8 8 240px !important; }
-.col-9 { flex: 9 9 270px !important; -webkit-flex: 9 9 270px !important; }
-.col-10 { flex: 10 10 300px !important; -webkit-flex: 10 10 300px !important; }
+ line-height: 3;
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ text-align: center !important;
+ background: inherit;
+}
+
+.td[width="33%"] {
+ padding: 1.1em;
+}
+
+.table[width="33%"],
+.th[width="33%"],
+.td[width="33%"] {
+ width: 33%;
+}
+
+.table[width="100%"],
+.th[width="100%"],
+.td[width="100%"] {
+ width: 100%;
+}
+
+.col-1 {
+ flex: 1 1 30px !important;
+}
+
+.col-2 {
+ flex: 2 2 60px !important;
+}
+
+.col-3 {
+ flex: 3 3 90px !important;
+}
+
+.col-4 {
+ flex: 4 4 120px !important;
+}
+
+.col-5 {
+ flex: 5 5 150px !important;
+}
+
+.col-6 {
+ flex: 6 6 180px !important;
+}
+
+.col-7 {
+ flex: 7 7 210px !important;
+}
+
+.col-8 {
+ flex: 8 8 240px !important;
+}
+
+.col-9 {
+ flex: 9 9 270px !important;
+}
+
+.col-10 {
+ flex: 10 10 300px !important;
+}
.cbi-button-up,
.cbi-button-down,
.cbi-value-helpicon,
-.showSide,
-.main > .loading > span {
- font-family: 'icomoon' !important;
- speak: none;
- font-style: normal !important;
- font-weight: normal !important;
- font-variant: normal !important;
- text-transform: none !important;
- line-height: 1;
-
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+.showSide {
+ font-family: "icomoon" !important;
+ font-weight: normal;
+ font-style: normal;
+ font-variant: normal;
+ line-height: 1;
+ text-transform: none;
+ -webkit-font-smoothing: antialiased;
+ speak: none;
}
* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
- font-family: inherit;
- font-weight: 400;
- line-height: 1.1;
- color: inherit;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-family: inherit;
+ font-weight: normal;
+ line-height: 1.1 !important;
+ color: inherit;
}
html {
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
+ overflow-y: hidden;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
}
body {
- font-size: 0.8rem;
- background-color: #EEE;
+ font-size: .8rem;
+ background-color: #eee;
}
-html, body {
- margin: 0px;
- padding: 0px;
- height: 100%;
- font-family: var(--font-body, "Microsoft Yahei", "WenQuanYi Micro Hei", "sans-serif", "Helvetica Neue", "Helvetica", "Hiragino Sans GB");
+html,
+body {
+ font-family: "Microsoft Yahei", "WenQuanYi Micro Hei", "sans-serif", "Helvetica Neue", "Helvetica", "Hiragino Sans GB";
+ font-family: var(--font-body);
+ height: 100%;
+ margin: 0;
+ padding: 0;
}
select {
- padding: 0.36rem 0.8rem;
- color: #555;
- background-color: #fff;
- background-image: none;
- border: 1px solid #ccc;
+ padding: .36rem .8rem;
+ color: #555;
+ border: thin solid #ccc;
+ background-color: #fff;
+ background-image: none;
}
+.btn,
+button,
select,
input,
.cbi-dropdown {
- background-color: transparent;
- color: rgba(0, 0, 0, .87);
- border: none;
- border-bottom: 2px solid rgba(0, 0, 0, .26);
- outline: 0;
- padding: 0;
- box-shadow: none;
- border-radius: 0;
- background-image: none;
- height: 1.8rem;
- font-size: 0.8rem;
+ height: 1.8rem;
+ padding: 0;
+ color: rgba(0, 0, 0, .87);
+ border: 0;
+ border-bottom: 2px solid rgba(0, 0, 0, .26);
+ border-radius: 0;
+ outline: 0;
+ background-color: transparent;
+ background-image: none;
+ box-shadow: none;
+}
+
+select,
+.cbi-dropdown {
+ width: inherit;
}
select:not([multiple="multiple"]):focus,
-input:focus,
+input:not(.cbi-button):focus,
.cbi-dropdown:focus,
.cbi-dynlist > .item:focus {
- border-color: var(--main-color, #0099CC);
+ border-color: #09c;
+ border-color: var(--main-color);
}
select[multiple="multiple"] {
- height: auto;
+ height: auto;
+}
+
+pre {
+ overflow: auto;
}
code {
- color: var(--main-color, #0099CC);
+ font-size: 1rem;
+ font-size-adjust: .35;
+ padding: 1px 3px;
+ color: #101010;
+ border: thin solid #999;
+ border-radius: 2px;
+ background: #ddd;
}
abbr {
- color: #005470;
- text-decoration: underline;
- cursor: help;
+ cursor: help;
+ text-decoration: underline;
+ color: #005470;
}
hr {
- margin: 1rem 0;
- border-color: #EEE;
- opacity: 0.1;
+ margin: 1rem 0;
+ opacity: .1;
+ border-color: #eee;
}
-header, .main {
- width: 100%;
- position: absolute;
+header,
+.main {
+ position: absolute;
+ width: 100%;
}
header {
- box-shadow: 0 2px 5px rgba(0, 0, 0, .26);
- transition: box-shadow .2s;
- float: left;
- position: fixed;
- z-index: 2000;
+ position: fixed;
+ z-index: 2000;
+ float: left;
+ height: 4rem;
+ transition: box-shadow .2s;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, .26);
}
footer {
- text-align: right;
- padding: 1rem;
- color: #aaa;
- font-size: 0.8rem;
- text-shadow: 0px 0px 2px #BBB;
+ font-size: .8rem;
+ overflow: hidden;
+ padding: 1rem;
+ text-align: right;
+ white-space: nowrap;
+ color: #aaa;
+ text-shadow: 0 0 2px #bbb;
}
footer > a {
- color: #aaa;
- text-decoration: none;
+ text-decoration: none;
+ color: #aaa;
}
.main {
- top: 5rem;
- bottom: 0rem;
- position: relative;
- height: 100%;
- height: calc(100% - 4rem);
+ position: relative;
+ top: 4rem;
+ bottom: 0;
+ overflow-y: auto;
+ height: 100%;
+ height: calc(100% - 4rem);
}
.main > .loading {
- position: fixed;
- width: 100%;
- height: 100%;
- z-index: 1000;
- display: block;
- background-color: rgb(240, 240, 240);
- top: 0;
+ position: fixed;
+ z-index: 1000;
+ top: 0;
+ display: block;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ background-color: rgb(240, 240, 240);
}
.main > .loading > span {
- display: block;
- text-align: center;
- margin-top: 2rem;
- color: #888;
- font-size: 1.2rem;
+ font-family: monospace;
+ font-size: 2.0rem;
+ font-size-adjust: .35;
+ position: relative;
+ top: 12.5%;
+ display: block;
+ text-align: center;
+ color: #888;
}
.main > .loading > span > .loading-img:before {
- content: "\e603";
+ content: "\e603";
}
.main > .loading > span > .loading-img {
- animation: anim-rotate 2s infinite linear;
- display: inline-block;
- margin: 5rem;
+ font-family: "icomoon" !important;
+ font-size: 1.0rem;
+ font-size-adjust: .6;
+ display: inline-block;
+ margin-right: 1rem;
+ animation: anim-rotate 2s infinite linear;
}
@keyframes anim-rotate {
- 0% {
- -webkit-transform: rotate(0);
- -ms-transform: rotate(0);
- transform: rotate(0);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- -ms-transform: rotate(360deg);
- transform: rotate(360deg)
- }
+ 0% {
+ -webkit-transform: rotate(0);
+ -ms-transform: rotate(0);
+ transform: rotate(0);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
}
.main-left {
- float: left;
- top: 5rem;
- width: 15%;
- width: calc(0% + 15rem);
- height: 100%;
- height: calc(100% - 4rem);
- background-color: var(--menu-bg-color, #FFFFFF);
- overflow-x: auto;
- position: fixed;
+ position: fixed;
+ top: 4rem;
+ float: left;
+ overflow-x: auto;
+ width: 15%;
+ width: calc(0% + 15rem);
+ height: 100%;
+ height: calc(100% - 4rem);
+ background-color: #fff;
+ background-color: var(--menu-bg-color);
}
.main-right {
- width: 85%;
- width: calc(100% - 15rem);
- float: right;
- height: 100%;
- background-color: #EEE;
+ float: right;
+ width: 85%;
+ width: calc(100% - 15rem);
+ height: 100%;
+ background-color: #eee;
}
.main-right > #maincontent {
- background-color: #EEE;
+ background-color: #eee;
}
.pull-right {
- float: right;
+ float: right;
}
.pull-left {
- float: left;
+ float: left;
+}
+
+.nowrap:not(.td) {
+ white-space: nowrap;
+}
+
+[disabled="disabled"] {
+ pointer-events: none;
}
header {
- background: var(--header-bg, #0099CC);
- color: var(--header-color, #FFFFFF);
- height: 5rem;
+ color: #fff;
+ color: var(--header-color);
+ background: #09c;
+ background: var(--header-bg);
}
header > .fill > .container {
- padding-top: 0.25rem;
- padding-right: 1rem;
- padding-bottom: 0.25rem;
- display: flex;
- align-items: center;
- height: 5rem;
+ margin-top: .5rem;
+ padding: .5rem 1rem 0 1rem;
+ user-select: none;
}
-header > .fill > .container > .brand {
- font-size: 2rem;
- color: var(--header-color, #FFFFFF);
- text-decoration: none;
- cursor: default;
- margin-left: 1rem;
+header > .fill > .container > #logo {
+ margin: 0 3.5rem 0 1.5rem;
+}
+
+header > .fill > .container > #logo > img {
+ width: calc(0% + 10rem);
+ margin-top: -.1rem;
+}
+
+body:not(.logged-in) > header > .fill > .container > #logo {
+ display: none;
}
-header > .fill > .container > img{
- max-height: 4.5rem;
- width: calc(0% + 13rem);
- margin: 1rem;
+header > .fill > .container > .brand {
+ font-size: 1.4rem;
+ position: absolute;
+ cursor: default;
+ vertical-align: text-bottom;
+ text-decoration: none;
+ color: #fff;
+ color: var(--header-color);
}
header > .fill > .container > .status {
- display: flex;
- justify-content: flex-end;
- flex-grow: 8;
+ position: absolute;
+ top: 25%;
+ right: 1em;
+ float: right;
+}
+
+header > .fill > .container > .status > * {
+ position: relative;
+ top: .2rem;
+ float: left;
+ margin-left: .3rem;
+ cursor: pointer;
+}
+
+#xhr_poll_status {
+ display: flex;
}
.danger {
- background-color: #FA8072 !important;
- color: black;
+ background-color: #ff7d60 !important;
}
.warning {
- background-color: #F0E68C !important;
- color: black;
+ background-color: #f0e68c !important;
}
.success {
- background-color: #90EE90 !important;
- color: black;
+ background-color: #5cb85c !important;
}
-.alert-message {
- margin: 2rem 0 0 0;
- padding: 1rem;
- border: 0;
- font-weight: normal;
- font-style: normal;
- line-height: 1;
- font-family: inherit;
- min-width: inherit;
- overflow: auto;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+.notice {
+ background-color: #5bc0de !important;
}
.error {
- color: red;
+ color: #f00;
+}
+
+.alert,
+.alert-message {
+ font-weight: bold;
+ margin-bottom: 1em;
+ padding: 1rem;
+ border: 0;
+ border-radius: 0 !important;
+ background-color: #fff;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ text-shadow: 1px 1px rgba(0, 0, 0, .1);
}
.alert-message > h4 {
- font-weight: bold;
- font-size: 110%;
+ font-size: 110%;
+ font-weight: bold;
}
.alert-message > * {
- margin: .5rem 0;
-}
-
-#maincontent > .container > div:nth-child(1).alert-message.warning > a {
- font: inherit;
- overflow: visible;
- text-transform: none;
- display: inline-block;
- margin-bottom: 0;
- font-weight: 400;
- text-align: center;
- white-space: nowrap;
- vertical-align: middle;
- touch-action: manipulation;
- cursor: pointer;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- background-image: none;
- min-width: 6rem;
- padding: 0.5rem 1rem;
- font-size: 0.9rem;
- line-height: 1.42857143;
- color: #fff;
- background-color: #5bc0de;
- border-color: #46b8da;
- margin-top: 2rem;
- text-decoration: inherit;
+ margin: .5rem 0;
+}
+
+.alert-message .btn {
+ padding: .3rem .6rem;
+}
+
+.container .alert,
+.container .alert-message {
+ margin-top: 1rem;
}
.main > .main-left > .nav {
- margin-top: 0.5rem;
+ margin-top: .5rem;
}
-.main > .main-left > .nav > li a {
- color: var(--menu-color, #404040);
- display: block;
+.main > .main-left > .nav > li {
+ padding: .5rem 1rem;
+ cursor: pointer;
}
.main > .main-left > .nav > li:nth-last-child(1) {
- margin-top: 1rem;
- margin-bottom: 1rem;
- font-size: 1.2rem;
+ font-size: 1.2rem;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
}
-.main > .main-left > .nav > li {
- padding: 0.5rem 1rem;
- cursor: pointer;
+.main > .main-left > .nav > li a {
+ display: block;
+ color: #5f6368;
+ color: var(--menu-color);
}
.main > .main-left > .nav > .slide {
- padding: 0;
+ padding: 0;
}
.main > .main-left > .nav > .slide > ul {
- display: none;
+ display: none;
+}
+
+.main > .main-left > .nav > .slide > .menu::before {
+ font-weight: 900;
+ position: absolute;
+ right: 17px;
+ content: "\2228";
+ transform: scale(1.3, .75);
+}
+
+.main > .main-left > .nav > .slide > .menu.active::before {
+ content: "\2227";
+}
+
+.main > .main-left[style$="overflow: hidden;"] > .nav > .slide > .menu::before {
+ display: none;
}
.main > .main-left > .nav > .slide > .menu {
- display: block;
- padding: 0.5rem 1rem;
- text-decoration: none;
- cursor: default;
- font-size: 1.15rem;
+ font-size: 1.15rem;
+ font-weight: 500;
+ display: block;
+ padding: .5rem 1rem;
+ text-decoration: none;
+ color: #202124;
}
.main > .main-left > .nav > li:hover,
.main > .main-left > .nav > .slide > .menu:hover {
- background: var(--submenu-bg-hover, #D4D4D4)
+ background: #d4d4d4;
+ background: var(--submenu-bg-hover);
}
.main > .main-left > .nav > .slide:hover {
- background: none;
+ background: none;
}
.main > .main-left > .nav > .slide > .slide-menu > li {
- padding: 0.4rem 2rem;
+ padding: .4rem 2rem;
}
.main > .main-left > .nav > .slide > .slide-menu > .active {
- background-color: var(--submenu-bg-hover-active, #0099CC);
+ background-color: #09c;
+ background-color: var(--submenu-bg-hover-active);
}
.main > .main-left > .nav > .slide > .slide-menu > li > a {
- text-decoration: none;
- white-space: nowrap;
+ white-space: nowrap;
+ text-decoration: none;
}
.main > .main-left > .nav > .slide > .slide-menu > .active > a {
- color: white;
+ color: #fff;
}
.main > .main-left > .nav > .slide > .slide-menu > li:hover {
- background: var(--submenu-bg-hover, #D4D4D4)
+ background: #d4d4d4;
+ background: var(--submenu-bg-hover);
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > li:not(.active):hover > a {
+ color: #202124;
+ color: var(--menu-color-hover);
}
.main > .main-left > .nav > .slide > .slide-menu > .active:hover {
- background-color: var(--main-color, #0099CC);
- cursor: hand;
+ cursor: hand;
+ background-color: #09c;
+ background-color: var(--main-color);
}
-li {
- list-style-type: none;
+/* ripple effect */
+.main > .main-left > .nav > .slide > .menu,
+.main > .main-left > .nav > .slide > .slide-menu > li {
+ position: relative;
+ overflow: hidden;
+ transform: translate3d(0, 0, 0);
+}
+
+.main > .main-left > .nav > .slide > .menu:after,
+.main > .main-left > .nav > .slide > .slide-menu > li:after {
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: block;
+ width: 100%;
+ height: 100%;
+ content: "";
+ transition: transform .5s, opacity 1s;
+ transform: scale(10, 10);
+ pointer-events: none;
+ opacity: 0;
+ background-image: radial-gradient(circle, #000 10%, transparent 10.01%);
+ background-repeat: no-repeat;
+ background-position: 50%;
+}
+
+.main > .main-left > .nav > .slide > .menu:active:after,
+.main > .main-left > .nav > .slide > .slide-menu > li:active:after {
+ transition: 0s;
+ transform: scale(0, 0);
+ opacity: .2;
}
#maincontent > .container {
- margin: 0 2rem 1rem 2rem;
+ margin: 0 2rem 1rem 2rem;
+}
+
+.Processes #maincontent > .container {
+ margin-right: 0;
+}
+
+ul {
+ line-height: normal;
+}
+
+li {
+ list-style-type: none;
}
h1 {
- font-size: 2rem;
- padding-bottom: 10px;
- border-bottom: 1px solid #eee;
+ font-size: 2rem;
+ padding-bottom: 10px;
+ border-bottom: thin solid #eee;
}
h2 {
- margin: 2rem 0 0 0;
- font-size: 1.8rem;
- padding-bottom: 10px;
- border-bottom: 1px solid #eee;
+ font-size: 1.8rem;
+ margin: 2rem 0 0 0;
+ padding-bottom: 10px;
+ border-bottom: thin solid #eee;
}
h3 {
- margin: 2rem 0 0 0;
- font-size: 1.4rem;
- padding-bottom: 10px;
+ font-size: 1.4rem;
+ margin: 2rem 0 0 0;
+ padding-bottom: 10px;
}
h4 {
- margin: 1.5rem 0 0 0;
- font-size: 1.2rem;
- padding-bottom: 10px;
-}
-
-.cbi-section {
- margin: 1rem 0 0 0;
- padding: 2rem;
- border: 0;
- font-weight: normal;
- font-style: normal;
- line-height: 1;
- font-family: inherit;
- min-width: inherit;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
-
- -webkit-overflow-scrolling: touch;
+ font-size: 1.2rem;
+ margin: 2rem 0 0 0;
+ padding-bottom: 10px;
+}
+
+h5 {
+ font-size: 1rem;
+ margin: 2rem 0 0 0;
+ padding-bottom: 10px;
+}
+
+.cbi-section,
+.cbi-section-error,
+#cbi-network > .cbi-section-node,
+#cbi-wireless > .cbi-section-node,
+#cbi-wireless > #wifi_assoclist_table,
+[data-page^="admin-system-admin"]:not(.node-main-login) .cbi-map:not(#cbi-dropbear),
+[data-page="admin-system-opkg"] #maincontent > .container {
+ font-family: inherit;
+ font-weight: normal;
+ font-style: normal;
+ line-height: normal;
+ min-width: inherit;
+ margin: 1rem 0 0 0;
+ padding: 2rem;
+ border: 0;
+ border-radius: 0;
+ background-color: #fff;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
}
.cbi-map-descr + fieldset {
- margin-top: 1rem;
+ margin-top: 1rem;
}
.cbi-section > legend {
- display: none !important;
+ display: none !important;
}
-fieldset > fieldset {
- margin: 0;
- padding: 0;
- border: none;
- box-shadow: none;
+fieldset > fieldset,
+.cbi-section > .cbi-section {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ box-shadow: none;
}
.cbi-section > h3:first-child,
.panel-title {
- width: 100%;
- display: block;
- line-height: 1;
- color: #404040;
- font-size: 1.4rem;
- padding-bottom: 1rem;
- border-bottom: 1px solid #eee;
- margin: 0;
+ font-size: 1.4rem;
+ line-height: 1;
+ display: block;
+ width: 100%;
+ margin: 0;
+ margin-bottom: .5rem;
+ padding-bottom: 1rem;
+ color: #404040;
+ border-bottom: thin solid #eee;
}
table {
- border-spacing: 0;
- border-collapse: collapse;
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+table,
+.table {
+ overflow-y: hidden;
+ width: 100%;
+ box-shadow: 0 0 0 1px #ddd;
}
-table, .table {
- width: 100%;
- border: 1px solid #eee;
+table > tbody > tr > td,
+table > tbody > tr > th,
+table > tfoot > tr > td,
+table > tfoot > tr > th,
+table > thead > tr > td,
+table > thead > tr > th,
+.table > .tbody > .tr > .td,
+.table > .tbody > .tr > .th,
+.table > .tfoot > .tr > .td,
+.table > .tfoot > .tr > .th,
+.table > .thead > .tr > .td,
+.table > .thead > .tr > .th,
+.table > .tr > .td.cbi-value-field,
+.table > .tr > .th.cbi-section-table-cell {
+ padding: .5rem;
}
-table > tbody > tr > td, table > tbody > tr > th, table > tfoot > tr > td, table > tfoot > tr > th, table > thead > tr > td, table > thead > tr > th,
-.table > .tbody > .tr > .td, .table > .tbody > .tr > .th, .table > .tfoot > .tr > .td, .table > .tfoot > .tr > .th, .table > .thead > .tr > .td, .table > .thead > .tr > .th {
- padding: .5rem;
- border-top: 1px solid #ddd;
- white-space: nowrap;
+.container > .cbi-section:first-of-type > .table[width="100%"] > .tr > .td {
+ padding: .6rem;
}
.cbi-section-table-cell {
- white-space: nowrap;
- align-self: flex-end;
- flex: 1 1 auto;
+ line-height: 1.1;
+ align-self: flex-end;
+ flex: 1 1 auto;
}
-.cbi-section-table {
- border: none;
+tr > td,
+tr > th,
+.tr > .td,
+.tr > .th,
+.cbi-section-table-row::before,
+#cbi-wireless > #wifi_assoclist_table > .tr:nth-child(2) {
+ border-top: thin solid #ddd;
+}
+
+tr:first-child > td
+.tr:first-child > .td,
+#cbi-wireless .td,
+#cbi-network .tr:first-child > .td,
+.table[width="100%"] > .tr:first-child > .td,
+[data-page="admin-network-diagnostics"] .tr > .td,
+.tr.table-titles > .th,
+.tr.cbi-section-table-titles > .th {
+ border-top: 0 !important;
}
.cbi-section-table-row {
- text-align: center;
- margin-bottom: 1rem;
- background: #f4f4f4;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ margin-bottom: 1rem;
+ text-align: center !important;
+ background: #f4f4f4;
}
.cbi-section-table-row:last-child {
- margin-bottom: 0;
+ margin-bottom: 0;
}
.cbi-section-table-row > .cbi-value-field .cbi-input-select,
.cbi-section-table-row > .cbi-value-field .cbi-input-text,
.cbi-section-table-row > .cbi-value-field .cbi-input-password,
.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
- width: 100%;
+ width: 100%;
}
.cbi-section-table-row > .cbi-value-field [data-dynlist] > input,
.cbi-section-table-row > .cbi-value-field input.cbi-input-password {
- width: calc(100% - 1.5rem);
+ width: calc(100% - 1.5rem);
}
-div > table > tbody > tr:nth-of-type(2n),
-div > .table > .tbody > .tr:nth-of-type(2n) {
- background-color: #f9f9f9;
+.cbi-section-table-row .td {
+ text-align: center !important;
}
div > table > tbody > tr:nth-of-type(2n),
-div > .table > .tbody > .tr:nth-of-type(2n) {
- background-color: #f9f9f9;
+div > .table > .tr:nth-of-type(2n) {
+ background-color: #f9f9f9;
}
/* fix multiple table */
-
table table,
.table .table {
- border: none;
+ border: 0;
}
.cbi-value-field table,
.cbi-value-field .table {
- border: none;
+ border: 0;
}
td > table > tbody > tr > td,
.td > .table > .tbody > .tr > .td {
- border: none;
+ border: 0;
}
.cbi-value-field > table > tbody > tr > td,
.cbi-value-field > .table > .tbody > .tr > .td {
- border: none;
+ border: 0;
}
/* button style */
+.btn,
+.cbi-button,
+.item::after {
+ font-size: .8rem;
+ display: inline-block;
+ width: auto !important;
+ padding: 0 .8rem;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ transition: all .2s ease-in-out;
+ text-align: center;
+ vertical-align: middle;
+ white-space: nowrap;
+ text-decoration: none;
+ text-transform: uppercase;
+ color: rgba(0, 0, 0, .87);
+ border: 0;
+ border-radius: .2rem;
+ background-color: #f0f0f0;
+ background-image: none;
+ -webkit-appearance: none;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+}
-.btn, .cbi-button, .item::after {
- -webkit-appearance: none;
- text-transform: uppercase;
- color: rgba(0, 0, 0, 0.87);
- background-color: #F0F0F0;
- transition: all 0.2s ease-in-out;
- display: inline-block;
- padding: 0 0.8rem;
- border: none;
- border-radius: 0.2rem;
- cursor: pointer;
- -ms-touch-action: manipulation;
- touch-action: manipulation;
- background-image: none;
- text-align: center;
- vertical-align: middle;
- white-space: nowrap;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- font-size: 0.8rem;
- width: auto !important;
- display: inline-block;
- text-decoration: none;
+.cbi-button:not(select) {
+ -webkit-appearance: none !important;
+}
+
+form[method="post"] + form[method="post"],
+.cbi-button + .cbi-button {
+ margin-left: .6rem;
}
.btn:hover,
@@ -657,420 +903,526 @@ td > table > tbody > tr > td,
.cbi-button:focus,
.cbi-button:active,
.item:hover::after,
+.item:focus::after,
+.item:active::after,
.cbi-page-actions .cbi-button-apply + .cbi-button-save:hover,
.cbi-page-actions .cbi-button-apply + .cbi-button-save:focus,
.cbi-page-actions .cbi-button-apply + .cbi-button-save:active {
- outline: 0;
- text-decoration: none;
- background-color: rgba(250, 250, 250, 0.7);
+ text-decoration: none;
+ outline: 0;
}
.btn:hover,
.btn:focus,
.cbi-button:hover,
.cbi-button:focus {
- box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2);
}
.btn:active,
.cbi-button:active {
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
+ box-shadow: 0 10px 20px rgba(0, 0, 0, .19), 0 6px 6px rgba(0, 0, 0, .23);
}
.btn:disabled,
.cbi-button:disabled {
- cursor: not-allowed;
- pointer-events: none;
- opacity: 0.60;
- box-shadow: none;
-}
-
-.cbi-page-actions .cbi-button-apply,
-.cbi-section-actions .cbi-button-edit,
-.cbi-button-edit.important,
-.cbi-button-apply.important,
-.cbi-button-reload.important,
-.cbi-button-action.important {
- color: #fff;
- background-color: #337ab7;
-}
-
-.cbi-page-actions .cbi-button-save,
-.cbi-button-add.important,
-.cbi-button-save.important,
-.cbi-button-positive.important {
- color: #fff;
- background-color: #5bc0de;
-}
-
-.cbi-button-remove.important,
-.cbi-button-reset.important,
-.cbi-button-negative.important {
- color: #fff;
- background-color: #d9534f;
+ cursor: not-allowed;
+ pointer-events: none;
+ opacity: .5;
+ box-shadow: none;
}
+/* gray */
+.alert-message [class="btn"],
+.modal div[class="btn"],
.cbi-button-find,
.cbi-button-link,
.cbi-button-up,
.cbi-button-down,
-.cbi-button-neutral {
- border: 1px solid #bfbfbf;
- background-color: transparent;
-}
-
-.cbi-button-edit,
-.cbi-button-apply,
-.cbi-button-reload,
-.cbi-button-action {
- color: #2e6da4;
- border: 1px solid #2e6da4;
- background-color: transparent;
+.cbi-button-neutral,
+.cbi-button[name="zero"],
+.cbi-button[name="restart"],
+.cbi-button[onclick="hide_empty(this)"] {
+ font-weight: bold;
+ border: thin solid #bfbfbf;
+ background-color: #d4d4d4;
}
+/* dark blue */
+.btn.primary,
+.cbi-page-actions .cbi-button-save,
.cbi-page-actions .cbi-button-apply + .cbi-button-save,
.cbi-button-add,
.cbi-button-save,
-.cbi-button-positive {
- color: #46b8da;
- border: 1px solid #46b8da;
- background-color: transparent;
+.cbi-button-positive,
+.cbi-button-link,
+.cbi-button[value="Enable"],
+.cbi-button[value="Scan"],
+.cbi-button[value^="Back"],
+.cbi-button-neutral[onclick="handleConfig(event)"] {
+ font-weight: normal;
+ color: #fff;
+ border: thin solid #2e6da4;
+ background-color: #337ab7;
}
+/* light blue */
+.cbi-page-actions .cbi-button-apply,
+.cbi-section-actions .cbi-button-edit,
+.cbi-button-edit,
+.cbi-button-apply,
+.cbi-button-reload,
+.cbi-button-action,
+.cbi-button[value="Submit"],
+.cbi-button[value$="Apply"],
+.cbi-button[onclick="addKey(event)"] {
+ font-weight: normal;
+ color: #fff;
+ border: thin solid #46b8da;
+ background-color: #5bc0de;
+}
+
+/* red */
+.btn.danger,
.cbi-section-remove > .cbi-button,
.cbi-button-remove,
.cbi-button-reset,
-.cbi-button-negative {
- color: #d43f3a;
- border: 1px solid #d43f3a;
- background-color: transparent;
+.cbi-button-negative,
+.cbi-button[value="Stop"],
+.cbi-button[value="Kill"],
+.cbi-button[onclick="reboot(this)"],
+.cbi-button-neutral[value="Restart"] {
+ font-weight: normal;
+ color: #fff;
+ border: thin solid #d43f3a;
+ background-color: #d9534f;
+}
+
+/* yellow */
+.btn[value="Dismiss"],
+.cbi-button[value="Terminate"],
+.cbi-button[value="Reset"],
+.cbi-button[value="Disabled"],
+.cbi-button[onclick^="iface_reconnect"],
+.cbi-button[onclick="handleReset(event)"],
+.cbi-button-neutral[value="Disable"] {
+ font-weight: normal;
+ color: #fff;
+ border: thin solid #eea236;
+ background-color: #f0ad4e;
+}
+
+/* green */
+.cbi-button-success,
+.cbi-button-download,
+.cbi-button[name="backup"],
+.cbi-button[value="Upload"],
+.cbi-button[value="Save mtdblock"] {
+ font-weight: normal;
+ color: #fff;
+ border: thin solid #4cae4c;
+ background-color: #5cb85c;
}
.cbi-page-actions .cbi-button-link:first-child {
- float: left;
+ float: left;
}
.a-to-btn {
- text-decoration: none;
+ text-decoration: none;
}
-/* table */
+.cbi-value-field .cbi-button-add {
+ font-weight: bold;
+ padding: 1px 6px;
+}
+.cbi-value-field .cbi-button-neutral {
+ padding: 1px 8px;
+}
+
+/* table */
.tabs {
- margin: 0 -2rem;
- padding-left: 0.5rem;
- background-color: #FFFFFF;
+ margin: 0 -2rem;
+ padding-left: .5rem;
+ background-color: #fff;
}
.cbi-tabmenu > li,
.tabs > li {
- display: inline-block;
- padding: 0.6rem 0rem;
+ display: inline-block;
+ padding: .6rem 0;
}
.cbi-tabmenu > li > a,
.tabs > li > a {
- text-decoration: none;
- color: #404040;
- padding: 0.5rem 0.8rem;
+ padding: .5rem .8rem;
+ text-decoration: none;
+ color: #404040;
}
.tabs > li[class~="active"],
.tabs > li:hover {
- cursor: pointer;
- border-bottom: 0.2rem solid var(--main-color, #0099CC);
- color: var(--main-color, #0099CC);
- margin-bottom: -0.18751rem;
+ margin-bottom: -.18751rem;
+ cursor: pointer;
+ color: #09c;
+ color: var(--main-color);
+ border-bottom: #09c;
+ border-bottom: .2rem solid var(--main-color);
}
.tabs > li[class~="active"] > a {
- color: var(--main-color, #0099CC);
+ color: #09c;
+ color: var(--main-color);
}
.tabs > li:hover {
- border-bottom: 0.18751rem solid #C9C9C9;
+ border-bottom: .18751rem solid #c9c9c9;
}
.cbi-tabmenu {
- border-top: 1px solid #D4D4D4;
- border-left: 1px solid #D4D4D4;
- border-right: 1px solid #D4D4D4;
+ border: thin solid #d4d4d4;
+ border-bottom: 0;
}
.cbi-tabmenu > li:hover {
- background-color: #F1F1F1;
+ background-color: #f1f1f1;
}
.cbi-tabmenu > li[class~="cbi-tab"] {
- background-color: white;
+ background-color: #fff;
}
.cbi-tabmenu {
- background-color: #D4D4D4;
+ background-color: #d4d4d4;
+}
+
+.cbi-section .cbi-section-remove:nth-of-type(2n),
+.container > .cbi-section .cbi-section-node:nth-of-type(2n) {
+ background-color: #f9f9f9;
+}
+
+[data-tab-title] {
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+}
+
+[data-tab-active="true"] {
+ opacity: 1;
+ height: auto;
+ overflow: visible;
+ transition: opacity .25s ease-in;
}
-.cbi-section-remove:nth-of-type(2n),
-.cbi-section-node:nth-of-type(2n){
- background-color: #f9f9f9;
+.cbi-section[id] .cbi-section-remove:nth-of-type(4n+3),
+.cbi-section[id] .cbi-section-node:nth-of-type(4n+4) {
+ background-color: #f9f9f9;
}
.cbi-section-node-tabbed {
- padding: 0;
- margin-top: 0;
- border-bottom: 1px solid #D4D4D4;
- border-left: 1px solid #D4D4D4;
- border-right: 1px solid #D4D4D4;
+ margin-top: 0;
+ padding: 0;
+ border: thin solid #d4d4d4;
+ border-top: 0;
}
.cbi-tabcontainer > .cbi-value:nth-of-type(2n) {
- background-color: #f9f9f9;
+ background-color: #f9f9f9;
}
.cbi-value-field,
.cbi-value-description {
- display: table-cell;
- line-height: 1.25;
+ line-height: 1.25;
+ display: table-cell;
}
-.cbi-input-invalid,
-.cbi-value-error input {
- color: #f00;
- border-color: #f00;
+.cbi-input-invalid {
+ color: #f00;
+ border-color: #f00;
}
.cbi-section-error {
- border: 1px solid #f00;
- border-radius: 3px;
- background-color: #fce6e6;
- padding: 5px;
- margin: 18px;
+ font-weight: bold;
+ line-height: 1.42857143;
+ margin: 18px;
+ padding: 6px;
+ border: thin solid #f00;
+ border-radius: 3px;
+ background-color: #fce6e6;
}
.cbi-section-error ul {
- margin: 0 0 0 20px;
+ margin: 0 0 0 20px;
}
.cbi-section-error ul li {
- color: #f00;
- font-weight: bold;
+ font-weight: bold;
+ color: #f00;
}
.cbi-value-helpicon > img {
- display: none;
+ display: none;
}
.cbi-value-helpicon:before {
- content: "\f059";
+ content: "\f059";
}
.cbi-value-description {
- font-size: small;
- opacity: 0.5;
- padding: 0.5rem 0 0 0;
+ font-size: small;
+ padding: .5rem 0 0 0;
+ opacity: .5;
}
.cbi-value-title {
- word-wrap: break-word;
- padding-top: 0.6rem;
- width: 23rem;
- float: left;
- text-align: right;
- padding-right: 2rem;
- display: table-cell;
+ display: table-cell;
+ float: left;
+ width: 23rem;
+ padding-top: .4rem;
+ padding-right: 2rem;
+ text-align: right;
+ word-wrap: break-word;
}
.cbi-value {
- padding: 0.3rem 1rem;
- display: inline-block;
- width: 100%;
+ display: inline-block;
+ width: 100%;
+ padding: .3rem 1rem;
}
-.cbi-section-table-descr > .cbi-section-table-cell,
-.cbi-section-table-titles > .cbi-section-table-cell {
- border: none;
+.cbi-value ul {
+ line-height: 1.25;
}
.td[data-title]::before {
- content: attr(data-title) ":\20";
- font-weight: bold;
- text-align: left;
- display: none;
- padding: .25rem 0;
- white-space: nowrap;
+ font-weight: bold;
+ display: none;
+ padding: .25rem 0;
+ content: attr(data-title) ":\20";
+ text-align: left;
+ white-space: nowrap;
}
.tr.placeholder .td[data-title]::before {
- display: none;
+ display: none;
}
.tr[data-title]::before,
.tr.cbi-section-table-titles.named::before {
- content: attr(data-title) "\20";
- font-weight: bold;
- text-align: center;
- display: table-cell;
- align-self: center;
- flex: 1 1 5%;
- padding: .25rem;
- white-space: normal;
- word-wrap: break-word;
- vertical-align: middle;
+ font-weight: bold;
+ display: table-cell;
+ align-self: center;
+ flex: 1 1 5%;
+ padding: .25rem;
+ content: attr(data-title) "\20";
+ text-align: center;
+ vertical-align: middle;
+ white-space: normal;
+ word-wrap: break-word;
}
.cbi-rowstyle-1 {
- background-color: #f9f9f9;
+ background-color: #f9f9f9;
}
.cbi-rowstyle-2 {
- background-color: #eee;
+ background-color: #eee;
}
.cbi-rowstyle-2 .cbi-button-up,
-.cbi-rowstyle-2 .cbi-button-down {
- background-color: #FFF !important;
+.cbi-rowstyle-2 .cbi-button-down,
+.cbi-rowstyle-2:first-child {
+ background-color: #fff !important;
}
.cbi-section-table .cbi-section-table-titles .cbi-section-table-cell {
- width: auto !important;
+ width: auto !important;
}
.td.cbi-section-actions {
- text-align: right;
- vertical-align: middle;
+ text-align: right !important;
+ vertical-align: middle;
}
.td.cbi-section-actions > * {
- display: flex;
+ display: inline-flex;
}
.td.cbi-section-actions > * > *,
.td.cbi-section-actions > * > form > * {
- flex: 1 1 4em;
- margin: 0 1px;
+ margin: 0 5px;
}
.td.cbi-section-actions > * > form {
- display: inline-flex;
- margin: 0;
+ display: inline-flex;
+ margin: 0;
}
/* desc */
.cbi-section-descr,
.cbi-map-descr {
- padding: 0.5rem;
- color: #999;
- font-size: small;
+ font-size: small;
+ line-height: 1.42857143;
+ padding: .5rem;
+ color: #999;
}
+.cbi-dynlist {
+ line-height: 1.3;
+ flex-direction: column;
+ min-height: 30px;
+}
+
+.cbi-dynlist > .item {
+ position: relative;
+ max-width: 24.9rem;
+ margin: 0 2em 4px 0;
+ padding: 2px 4px;
+ cursor: default;
+ pointer-events: none;
+ color: #666;
+ border-bottom: 2px solid rgba(0, 0, 0, .26);
+}
+
+.cbi-dynlist[name="sshkeys"] > .item {
+ max-width: none;
+}
+
+.cbi-dynlist > .item::after {
+ font-weight: bold;
+ position: absolute;
+ right: -2em;
+ bottom: 0;
+ display: inline-flex;
+ min-height: 17px;
+ padding: 0 6px;
+ content: "\00D7";
+ pointer-events: auto;
+ color: #fff;
+ border: thin solid #d43f3a;
+ background-color: #d9534f;
+}
+
+.cbi-dynlist > .item > span {
+ white-space: normal;
+ word-break: break-word;
+}
.cbi-dynlist,
.cbi-dropdown {
- display: inline-flex;
- cursor: pointer;
- position: relative;
- padding: 0;
- height: auto;
+ position: relative;
+ display: inline-flex;
+ height: auto;
+ padding: 0;
+ cursor: default;
}
.cbi-dropdown > ul {
- margin: 0 !important;
- padding: 0;
- list-style: none;
- overflow-x: hidden;
- overflow-y: auto;
- display: flex;
- width: 100%;
+ display: flex;
+ overflow-x: hidden;
+ overflow-y: auto;
+ width: 100%;
+ margin: 0 !important;
+ padding: 0;
+ list-style: none;
}
.cbi-dropdown > ul.preview {
- display: none;
+ display: none;
}
.cbi-dropdown > .open {
- border: 2px outset #eee;
- flex-basis: 15px;
- background: #eee;
+ flex-basis: 15px;
}
.cbi-dropdown > .open,
.cbi-dropdown > .more {
- flex-grow: 0;
- flex-shrink: 0;
- display: flex;
- flex-direction: column;
- justify-content: center;
- text-align: center;
- line-height: 2em;
- padding: 0 .25em;
+ font-size: 1rem;
+ font-weight: 900;
+ line-height: 2;
+ display: flex;
+ flex-direction: column;
+ flex-grow: 0;
+ flex-shrink: 0;
+ justify-content: center;
+ padding: 0 .25em;
+ text-align: center;
}
.cbi-dropdown > .more,
.cbi-dropdown > ul > li[placeholder] {
- color: #777;
- font-weight: bold;
- text-shadow: 1px 1px 0px #fff;
- display: none;
+ font-weight: bold;
+ display: none;
+ color: #777;
+ text-shadow: 1px 1px 0 #fff;
}
.cbi-dropdown > ul > li {
- display: none;
- padding: .25em;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- flex-shrink: 1;
- flex-grow: 1;
- align-items: center;
- align-self: center;
- min-height: 20px;
+ display: none;
+ overflow: hidden;
+ align-items: center;
+ align-self: center;
+ flex-grow: 1;
+ flex-shrink: 1;
+ min-height: 20px;
+ padding: .25em;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.cbi-dropdown > ul > li .hide-open {
+ display: initial;
}
-.cbi-dropdown > ul > li .hide-open { display: initial; }
-.cbi-dropdown > ul > li .hide-close { display: none; }
+.cbi-dropdown > ul > li .hide-close {
+ display: none;
+}
.cbi-dropdown > ul > li[display]:not([display="0"]) {
- border-left: 1px solid #ccc;
+ border-left: thin solid #ccc;
}
.cbi-dropdown[empty] > ul {
- max-width: 1px;
+ max-width: 1px;
}
.cbi-dropdown > ul > li > form {
- display: none;
- margin: 0;
- padding: 0;
- pointer-events: none;
+ display: none;
+ margin: 0;
+ padding: 0;
+ pointer-events: none;
}
.cbi-dropdown > ul > li img {
- vertical-align: middle;
- margin-right: .25em;
+ margin-right: .25em;
+ vertical-align: middle;
}
.cbi-dropdown > ul > li > form > input[type="checkbox"] {
- margin: 0;
- height: auto;
+ height: auto;
+ margin: 0;
}
.cbi-dropdown > ul > li input[type="text"] {
- height: 20px;
+ height: 20px;
}
.cbi-dropdown[open] {
- position: relative;
+ position: relative;
}
.cbi-dropdown[open] > ul.dropdown {
- display: block;
- background: #f6f6f5;
- border: 1px solid #918e8c;
- box-shadow: 0 0 4px #918e8c;
- position: absolute;
- z-index: 1100;
- max-width: none;
- min-width: 100%;
- width: auto;
+ position: absolute;
+ z-index: 1100;
+ display: block;
+ width: auto;
+ min-width: 100%;
+ max-width: none;
+ max-height: 200px !important;
+ border: thin solid #918e8c;
+ background: #f6f6f6;
+ box-shadow: 0 0 4px #918e8c;
}
.cbi-dropdown > ul > li[display],
@@ -1080,207 +1432,149 @@ td > table > tbody > tr > td,
.cbi-dropdown[multiple][open] > ul.dropdown > li,
.cbi-dropdown[multiple][more] > .more,
.cbi-dropdown[multiple][empty] > .more {
- flex-grow: 1;
- display: flex;
- align-items: center;
+ display: flex;
+ align-items: center;
+ flex-grow: 1;
}
.cbi-dropdown[empty] > ul > li,
.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder],
.cbi-dropdown[multiple][open] > ul.dropdown > li > form {
- display: block;
+ display: block;
}
-.cbi-dropdown[open] > ul.dropdown > li .hide-open { display: none; }
-.cbi-dropdown[open] > ul.dropdown > li .hide-close { display: initial; }
+.cbi-dropdown[open] > ul.dropdown > li .hide-open {
+ display: none;
+}
+
+.cbi-dropdown[open] > ul.dropdown > li .hide-close {
+ display: initial;
+}
.cbi-dropdown[open] > ul.dropdown > li {
- border-bottom: 1px solid #ccc;
+ border-bottom: thin solid #ccc;
}
.cbi-dropdown[open] > ul.dropdown > li[selected] {
- background: #b0d0f0;
+ background: #b0d0f0;
}
.cbi-dropdown[open] > ul.dropdown > li.focus {
- background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%);
+ background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%);
}
.cbi-dropdown[open] > ul.dropdown > li:last-child {
- margin-bottom: 0;
- border-bottom: none;
+ margin-bottom: 0;
+ border-bottom: 0;
}
.cbi-dropdown[open] > ul.dropdown > li[unselectable] {
- opacity: 0.7;
+ opacity: .7;
}
.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child {
- width: 100%;
-}
-
-.cbi-dropdown[open] > ul.dropdown > li[unselectable] {
- opacity: 0.7;
-}
-
-.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child {
- width: 100%;
+ width: 100%;
}
.cbi-dropdown[disabled] {
- pointer-events: none;
- opacity: .6;
+ pointer-events: none;
+ opacity: .6;
}
.cbi-dropdown .zonebadge {
- width: 100%;
+ width: 100%;
}
.cbi-dropdown[open] .zonebadge {
- width: auto;
-}
-
-.cbi-dynlist {
- height: auto;
- min-height: 30px;
- display: inline-flex;
- flex-direction: column;
-}
-
-.cbi-dynlist > .item {
- margin: 0 2em 4px 0;
- padding: 2px 4px;
- border-bottom: 2px solid rgba(0, 0, 0, .26);
- position: relative;
- pointer-events: none;
- cursor: default;
-}
-
-.cbi-dynlist > .item::after {
- content: "×";
- position: absolute;
- display: inline-flex;
- align-items: center;
- top: 0;
- right: -2em;
- bottom: 0;
- padding: 0 6px;
- border: 1px solid #c44;
- font-weight: bold;
- color: #c44;
- pointer-events: auto;
-}
-
-.cbi-dynlist {
- height: auto;
- min-height: 30px;
- display: inline-flex;
- flex-direction: column;
-}
-
-.cbi-dynlist > .item {
- margin: 0 2em 4px 0;
- padding: 2px 4px;
- border-bottom: 2px solid rgba(0, 0, 0, .26);
- position: relative;
- pointer-events: none;
- cursor: default;
-}
-
-.cbi-dynlist > .item::after {
- content: "×";
- position: absolute;
- display: inline-flex;
- align-items: center;
- top: 0;
- right: -2em;
- bottom: 0;
- padding: 0 6px;
- border: 1px solid #c44;
- font-weight: bold;
- color: #c44;
- pointer-events: auto;
+ width: auto;
}
#modal_overlay {
position: fixed;
- top: 5rem;
+ z-index: 900;
+ top: 4rem;
+ right: 10000px;
bottom: 0;
left: -10000px;
- right: 10000px;
- background: rgba(0, 0, 0, 0.7);
- z-index: 900;
overflow-y: scroll;
- -webkit-overflow-scrolling: touch;
transition: opacity .125s ease-in;
opacity: 0;
+ background: rgba(0, 0, 0, .7);
+ -webkit-overflow-scrolling: touch;
}
.modal {
- width: 90%;
- margin: 5em auto;
display: flex;
+ align-items: center;
flex-wrap: wrap;
- min-height: 32px;
+ width: 90%;
+ min-width: 270px;
max-width: 600px;
- align-items: center;
- border-radius: 3px;
- background: #fff;
- box-shadow: 0 0 3px #444;
- padding: 1em 1em .5em 1em;
+ min-height: 32px;
max-height: 2400px;
- min-width: 270px;
+ margin: 5em auto;
+ padding: 1em;
+ border-radius: 3px !important;
+ background: #fff;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
}
.modal > * {
- flex-basis: 100%;
line-height: normal;
- margin-bottom: .5em;
+ flex-basis: 100%;
}
.modal > pre,
.modal > textarea {
- white-space: pre-wrap;
+ font-size: 1rem;
+ font-size-adjust: .35;
overflow: auto;
+ margin-bottom: .5em;
+ padding: 8.5px;
+ white-space: pre-wrap;
+ color: #eee;
+ outline: 0;
+ background-color: #101010;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
}
-body.modal-overlay-active {
- overflow: hidden;
- height: 100vh;
+.modal > h4 {
+ margin: .5em 0;
}
-body.modal-overlay-active #modal_overlay {
- left: 0;
- right: 0;
- opacity: 1;
+.modal ul {
+ margin-left: 2.2em;
}
-#modal_overlay > .modal {
- width: 90%;
- margin: 5em auto;
- display: flex;
- flex-wrap: wrap;
- min-height: 32px;
- max-width: 600px;
- align-items: center;
- border-radius: 3px;
- background: #fff;
- box-shadow: 0 0 3px #444;
- padding: 1em 1em 1em 1em;
- max-height: 2400px;
- min-width: 270px;
+.modal li {
+ list-style-type: square;
+ color: #808080;
}
-#modal_overlay .modal > * {
- flex-basis: 100%;
- line-height: normal;
- margin-bottom: .5em;
+.modal p {
+ padding-left: .25rem;
+ word-break: break-word;
}
-#modal_overlay .modal > pre,
-#modal_overlay .modal > textarea {
- white-space: pre-wrap;
- overflow: auto;
+.modal .label {
+ font-size: .6rem;
+ font-weight: normal;
+ padding: .1rem .3rem;
+ padding-bottom: 0;
+ cursor: default;
+ border-radius: 0;
+}
+
+.modal .label.warning {
+ background-color: #f0ad4e !important;
+}
+
+.modal .btn {
+ padding: .3rem .6rem;
+}
+
+.modal .spinning {
+ margin-bottom: 2em;
}
body.modal-overlay-active {
@@ -1289,8 +1583,8 @@ body.modal-overlay-active {
}
body.modal-overlay-active #modal_overlay {
- left: 0;
right: 0;
+ left: 0;
opacity: 1;
}
@@ -1302,8 +1596,8 @@ body.modal-overlay-active #modal_overlay {
.spinning::before {
position: absolute;
top: 0;
- left: 0;
bottom: 0;
+ left: .2em;
width: 32px;
content: " ";
background: url(../resources/icons/loading.gif) no-repeat center;
@@ -1311,1096 +1605,1369 @@ body.modal-overlay-active #modal_overlay {
}
/* luci */
-
.hidden {
- display: none
+ display: none;
}
-.left, .left::before {
- text-align: left !important;
+.left,
+.left::before {
+ text-align: left !important;
}
-.right, .right::before {
- text-align: right !important;
+.right,
+.right::before {
+ text-align: right !important;
}
-.center, .center::before {
- text-align: center !important;
+.center,
+.center::before {
+ text-align: center !important;
}
.top {
- align-self: flex-start !important;
- vertical-align: top !important;
+ align-self: flex-start !important;
+ vertical-align: top !important;
}
.bottom {
- align-self: flex-end !important;
- vertical-align: bottom !important;
+ align-self: flex-end !important;
+ vertical-align: bottom !important;
}
.inline {
- display: inline;
+ display: inline;
}
.cbi-page-actions {
- border-top: 1px solid #eee;
- padding-top: 1rem;
- text-align: right;
+ padding-top: 1rem;
+ text-align: right;
+}
+
+.cbi-page-actions > form[method="post"] {
+ display: inline-block;
}
/* input */
.cbi-value input[type="password"],
.cbi-value input[type="text"] {
- min-width: 15rem;
+ min-width: 15rem;
}
/* select */
-.cbi-value-field .cbi-dropdown {
- min-width: 15rem;
+.cbi-value-field .cbi-dropdown,
+.cbi-value-field .cbi-input-select {
+ min-width: 15rem;
+}
+
+.cbi-value-field .cbi-input-invalid {
+ color: #f00;
+ border-bottom-color: #f00;
}
/* progressbar */
.cbi-progressbar {
- border: 1px solid #ccc;
- border-radius: 3px;
position: relative;
min-width: 170px;
height: 20px;
- margin: 0;
- background: #fff;
+ margin: 4px 0;
+ border: thin solid #999;
+ background: #eee;
}
.cbi-progressbar > div {
- background: var(--main-color, #0099CC);
+ width: 0;
height: 100%;
transition: width .25s ease-in;
- width: 0%;
+ background: #5bc0de;
+ background: var(--bar-bg);
}
.cbi-progressbar::after {
+ font-family: monospace;
+ font-size: 1.3em;
+ font-weight: bold;
+ font-size-adjust: .38;
+ line-height: normal;
position: absolute;
- bottom: 2px;
top: 2px;
right: 0;
+ bottom: 2px;
left: 0;
- text-align: center;
- text-shadow: 0 0 2px #fff;
+ overflow: hidden;
content: attr(title);
+ text-align: center;
white-space: pre;
- overflow: hidden;
text-overflow: ellipsis;
+ text-shadow: 0 0 2px #eee;
}
-.cbi-value-field .cbi-input-select {
- width: 15rem;
-}
-
-.cbi-value-field .cbi-input-invalid {
- border-bottom-color: #f00;
- color: #f00;
-}
-
-.th[data-type="button"], .td[data-type="button"],
-.th[data-type="fvalue"], .td[data-type="fvalue"] {
- flex: 1 1 2em;
- text-align: center;
+.th[data-type="button"],
+.td[data-type="button"],
+.th[data-type="fvalue"],
+.td[data-type="fvalue"] {
+ flex: 1 1 2em;
+ text-align: center;
}
.ifacebadge {
- display: inline-flex;
- border-bottom: 1px solid #CCCCCC;
- padding: 0.5rem 1rem;
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- background: #fff;
+ display: inline-flex;
+ padding: .5rem .8rem;
+ border-bottom: thin solid #ccc;
+ background: #eee;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 1px 2px rgba(0, 0, 0, .05);
}
td > .ifacebadge,
.td > .ifacebadge {
- background-color: #F0F0F0;
- font-size: 0.9rem;
+ font-size: .8rem;
+ background-color: #f0f0f0;
}
.ifacebadge > em,
.ifacebadge > img {
- display: inline-block;
- margin: 0 .2rem;
- align-self: flex-start;
+ display: inline-block;
+ align-self: flex-start;
+ margin: 0 .2rem;
}
.ifacebadge > img + img {
- margin: 0 .2rem 0 0;
+ margin: 0 .2rem 0 0;
}
.network-status-table {
- display: flex;
- flex-wrap: wrap;
+ display: flex;
+ flex-wrap: wrap;
}
.network-status-table .ifacebox {
- margin: .5em;
- flex-grow: 1;
+ flex-grow: 1;
+ margin: .5em;
}
.network-status-table .ifacebox-body {
- display: flex;
- flex-direction: column;
- height: 100%;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
}
.network-status-table .ifacebox-body > span {
- flex: 10 10 auto;
+ flex: 10 10 auto;
}
.network-status-table .ifacebox-body > div {
- display: flex;
- flex-wrap: wrap;
+ display: flex;
+ flex-wrap: wrap;
}
.network-status-table .ifacebox-body .ifacebadge {
- flex: 1 1 auto;
- margin: .5em .25em 0 .25em;
- padding: .5em;
- min-width: 220px;
- background-color: #fff;
- align-items: center;
+ align-items: center;
+ flex: 1 1 auto;
+ min-width: 220px;
+ margin: .5em .25em 0 .25em;
+ padding: .5em;
+ background-color: #fff;
}
-/*textarea*/
-
+/* textarea */
.cbi-input-textarea {
- width: 100%;
- min-height: 14rem;
- padding: 0.8rem;
- font-size: 0.8rem;
- font-family: monospace;
- color: black;
+ font-family: monospace;
+ width: 100%;
+ min-height: 14rem;
+ padding: .8rem;
+ color: #000;
}
#syslog {
- width: 100%;
- min-height: 15rem;
- padding: 1rem;
- font-size: small;
- color: #5F5F5F;
-
- margin-bottom: 20px;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
- border: none;
+ font-size: small;
+ width: 100%;
+ min-height: 15rem;
+ margin-bottom: 20px;
+ padding: 1rem;
+ resize: none;
+ color: #eee;
+ border: 0;
+ border-radius: 0;
+ background-color: #101010;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
}
-/* change */
+#syslog:focus {
+ outline: 0;
+}
+/* config changes */
.uci-change-list {
- font-family: monospace;
+ font-family: monospace;
}
.uci-change-list ins,
.uci-change-legend-label ins {
- text-decoration: none;
- border: 1px solid #00FF00;
- background-color: #CCFFCC;
- display: block;
- padding: 2px;
+ display: block;
+ padding: 2px;
+ text-decoration: none;
+ border: thin solid #0f0;
+ background-color: #cfc;
}
.uci-change-list del,
.uci-change-legend-label del {
- text-decoration: none;
- border: 1px solid #FF0000;
- background-color: #FFCCCC;
- display: block;
- font-style: normal;
- padding: 2px;
+ font-style: normal;
+ display: block;
+ padding: 2px;
+ text-decoration: none;
+ border: thin solid #f00;
+ background-color: #fcc;
}
.uci-change-list var,
.uci-change-legend-label var {
- text-decoration: none;
- border: 1px solid #CCCCCC;
- background-color: #EEEEEE;
- display: block;
- font-style: normal;
- padding: 2px;
+ font-style: normal;
+ display: block;
+ padding: 2px;
+ text-decoration: none;
+ border: thin solid #ccc;
+ background-color: #eee;
}
.uci-change-list var ins,
.uci-change-list var del {
- border: none;
- white-space: pre;
- font-style: normal;
- padding: 0px;
+ font-style: normal;
+ padding: 0;
+ white-space: pre;
+ border: 0;
}
.uci-change-legend {
- padding: 5px;
+ padding: 5px;
}
.uci-change-legend-label {
- width: 150px;
- float: left;
+ float: left;
+ width: 150px;
}
.uci-change-legend-label > ins,
.uci-change-legend-label > del,
.uci-change-legend-label > var {
- float: left;
- margin-right: 4px;
- width: 10px;
- height: 10px;
- display: block;
+ display: block;
+ float: left;
+ width: 10px;
+ height: 10px;
+ margin-right: 4px;
}
.uci-change-legend-label var ins,
.uci-change-legend-label var del {
- line-height: 6px;
- border: none;
+ line-height: .4;
+ border: 0;
}
.uci-change-list var,
.uci-change-list del,
.uci-change-list ins {
- padding: 0.5rem;
+ padding: .5rem;
}
/* other fix */
#iwsvg,
#iwsvg2,
#bwsvg {
- border: 1px solid #D4D4D4 !important;
- border-top: none !important;
+ border: thin solid #d4d4d4 !important;
+}
+
+#iwsvg,
+[data-page="admin-status-realtime-bandwidth"] #bwsvg {
+ border-top: 0 !important;
}
.ifacebox {
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 2px rgba(0, 0, 0, 0.2);
- border-bottom: 1px solid #ccc;
- background-color: #f9f9f9;
- display: inline-flex;
- flex-direction: column;
- line-height: 1.2em;
- min-width: 100px;
+ line-height: 1.25;
+ display: inline-flex;
+ flex-direction: column;
+ min-width: 100px;
+ border-bottom: thin solid #ccc;
+ background-color: #f9f9f9;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), 0 1px 2px rgba(0, 0, 0, .2);
}
.ifacebox-head {
- padding: .25em;
- background: #eee;
+ padding: .25em;
+ background: #eee;
}
.ifacebox-head.active {
- background: #90c0e0;
+ background: #5bc0de;
+ background: var(--bar-bg);
}
.ifacebox-body {
- padding: .25em;
+ padding: .25em;
}
.cbi-image-button {
- margin-left: 0.5rem;
+ margin-left: .5rem;
}
.zonebadge {
- padding: 0.2rem 0.5rem;
- display: inline-block;
+ display: inline-block;
+ padding: .2rem .5rem;
}
.zonebadge .ifacebadge {
- padding: .2rem .3rem;
- margin: 0.1rem 0.2rem;
- border: 1px solid #6C6C6C;
+ margin: .1rem .2rem;
+ padding: .2rem .3rem;
+ border: thin solid #6c6c6c;
}
.zonebadge > input[type="text"] {
- padding: 0.16rem 1rem;
- min-width: 10rem;
- margin-top: 0.3rem;
+ min-width: 10rem;
+ margin-top: .3rem;
+ padding: .16rem 1rem;
}
.zonebadge > em,
.zonebadge > strong {
- margin: 0 0.2rem;
- display: inline-block;
+ display: inline-block;
+ margin: 0 .2rem;
}
.cbi-value-field .cbi-input-checkbox,
.cbi-value-field .cbi-input-radio {
- margin-top: 0.5rem;
- height: 1rem;
-}
-
-.td .cbi-input-checkbox,
-.td .cbi-input-radio {
- margin-top: 0;
-}
-
-.cbi-value-field > input + .cbi-value-description {
- padding: 0;
+ margin-top: .15rem;
}
.cbi-value-field > ul > li {
- display: flex;
+ display: flex;
}
.cbi-value-field > ul > li > label {
- margin-top: 0.5rem;
+ margin-top: .5rem;
}
.cbi-value-field > ul > li .ifacebadge {
- background-color: #eee;
- margin-left: 0.4rem;
- margin-top: -0.5rem;
+ margin-top: -.5rem;
+ margin-left: .4rem;
+ background-color: #eee;
}
.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
- min-width: 7rem;
+ min-width: 7rem;
}
.cbi-section-create {
- margin: .5rem -3px;
- display: inline-flex;
- align-items: center;
+ display: inline-flex;
+ align-items: center;
+ margin: .5rem -3px;
}
.cbi-section-create > * {
- margin: 0.5rem;
+ margin: .5rem;
}
.cbi-section-remove {
- padding: 0.5rem;
+ padding: .5rem;
}
-div.cbi-value var, td.cbi-value-field var, .td.cbi-value-field var {
- font-style: italic;
- color: #0069D6;
+div.cbi-value var,
+td.cbi-value-field var,
+.td.cbi-value-field var {
+ font-style: italic;
+ color: #0069d6;
}
small {
- font-size: 90%;
- white-space: normal;
- line-height: 1.42857143;
+ font-size: 90%;
+ line-height: 1.42857143;
+ white-space: normal;
}
.cbi-button-up,
.cbi-button-down {
- display: inline-block;
- min-width: 0;
- padding: 0.2rem 0.3rem;
- font-size: 1.2rem;
+ font-size: 1.2rem;
+ display: inline-block;
+ min-width: 0;
+ padding: .2rem .3rem;
}
.cbi-optionals {
- padding: 1rem 1rem 0 1rem;
- border-top: 1px solid #CCC;
+ padding: 1rem 1rem 0 1rem;
+ border-top: thin solid #ccc;
}
.cbi-dropdown-container {
- position: relative;
+ position: relative;
}
-.cbi-tooltip-container {
- cursor: help;
+.cbi-tooltip-container,
+span[data-tooltip],
+span[data-tooltip] .label {
+ cursor: help !important;
}
.cbi-tooltip {
- position: absolute;
- z-index: 1000;
- left: -1000px;
- border-radius: 3px;
- background: #fff;
- padding: 2px 5px;
- white-space: pre;
- opacity: 0;
- transition: opacity .25s ease-out;
- pointer-events: none;
- box-shadow: 0 0 2px #444;
+ position: absolute;
+ z-index: 1000;
+ left: -1000px;
+ padding: 2px 5px;
+ transition: opacity .25s ease-out;
+ white-space: pre;
+ pointer-events: none;
+ opacity: 0;
+ border-radius: 3px;
+ background: #fff;
+ box-shadow: 0 0 2px #444;
}
.cbi-tooltip-container:hover .cbi-tooltip {
- left: auto;
- opacity: 1;
- transition: opacity .25s ease-in;
+ left: auto;
+ transition: opacity .25s ease-in;
+ opacity: 1;
}
.zonebadge .cbi-tooltip {
- padding: .25rem;
- background: inherit;
- margin: -1.5rem 0 0 -.5rem;
+ margin: -1.5rem 0 0 -.5rem;
+ padding: .25rem;
+ background: inherit;
}
.zonebadge-empty {
- background: repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px);
- color: #404040;
+ color: #404040;
+ background: repeating-linear-gradient(45deg, rgba(204, 204, 204, .5), rgba(204, 204, 204, .5) 5px, rgba(255, 255, 255, .5) 5px, rgba(255, 255, 255, .5) 10px);
}
.zone-forwards {
- display: flex;
- min-width: 10rem;
+ display: flex;
+ min-width: 10rem;
}
.zone-forwards > * {
- flex: 1 1 45%;
+ flex: 1 1 45%;
}
.zone-forwards > span {
- flex-basis: 10%;
- text-align: center;
- padding: 0 .25rem;
+ flex-basis: 10%;
+ padding: 0 .25rem;
+ text-align: center;
}
.zone-forwards .zone-src,
.zone-forwards .zone-dest {
- display: flex;
- flex-direction: column;
-}
-
-#diag-rc-output > pre {
- background-color: #f5f5f5;
- display: block;
- padding: 8.5px;
- margin: 0 0 18px;
- line-height: 1.5rem;
- -moz-border-radius: 3px;
- white-space: pre-wrap;
- word-wrap: break-word;
- font-size: 1.4rem;
- color: #404040;
-}
-
-input[name="ping"],
-input[name="traceroute"],
-input[name="nslookup"] {
- width: 80%;
-}
-
-header > .container > .pull-right > * {
- position: relative;
- top: 0.45rem;
- cursor: pointer;
-}
-
-#xhr_poll_status > .label.success {
- background-color: #14CE14;
-}
-
-#xhr_poll_status {
- display: flex;
+ display: flex;
+ flex-direction: column;
}
.label {
- padding: 0.3rem 0.8rem;
- font-size: 0.8rem;
- font-weight: bold;
- color: #ffffff !important;
- text-transform: uppercase;
- white-space: nowrap;
- background-color: #bfbfbf;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
- text-shadow: none;
- text-decoration: none;
+ font-size: .8rem;
+ font-weight: bold;
+ padding: .3rem .8rem;
+ white-space: nowrap;
+ text-decoration: none;
+ text-transform: uppercase;
+ color: #fff !important;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ background-color: #bfbfbf;
+ text-shadow: none;
}
label > input[type="checkbox"],
label > input[type="radio"] {
- vertical-align: bottom;
+ position: relative;
+ top: .4rem;
+ right: .2rem;
margin: 0;
-}
-
-.notice {
- background-color: #5BC0DE !important;
+ vertical-align: bottom;
}
.showSide {
- display: none;
+ display: none;
}
.darkMask {
- width: 100%;
- height: 100%;
- position: fixed;
- background-color: rgba(0, 0, 0, 0.56);
- content: "";
- z-index: 99;
- display: none;
+ position: fixed;
+ z-index: 99;
+ display: none;
+ width: 100%;
+ height: 100%;
+ content: "";
+ background-color: rgba(0, 0, 0, .56);
+}
+
+/* diagnostics */
+#diag-rc-output > pre,
+#command-rc-output > pre {
+ font-size: 1.2rem;
+ font-size-adjust: .35;
+ line-height: normal;
+ display: block;
+ width: 100%;
+ padding: 8.5px;
+ white-space: pre;
+ color: #eee;
+ background-color: #101010;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
}
-/* fix Main Login*/
+[data-page="admin-network-diagnostics"] .table {
+ box-shadow: none;
+}
+
+input[name="ping"],
+input[name="traceroute"],
+input[name="nslookup"] {
+ width: 80%;
+}
+
+/* fix Main Login */
.node-main-login > .main > .main-left {
- display: none;
+ display: none;
}
.node-main-login > .main > .main-right {
- width: 100%;
+ width: 100%;
}
.node-main-login > .main fieldset {
- padding: 0.5rem;
- margin-bottom: 1rem;
- display: inline;
- background: none;
- border: none;
- box-shadow: none;
- overflow: hidden;
+ display: inline;
+ overflow: hidden;
+ margin-bottom: 1rem;
+ padding: .5rem;
+ border: 0;
+ background: none;
+ box-shadow: none;
}
.node-main-login > .main .cbi-value-title {
- width: 8rem;
+ width: 9.5rem;
}
.node-main-login > .main #maincontent {
-
- text-align: center;
+ text-align: center;
}
.node-main-login > .main .container {
- display: inline-block;
- padding: 2rem 4rem;
- margin-top: 2rem !important;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
- text-align: left;
+ display: inline-block;
+ margin-top: 2rem !important;
+ padding: 1rem 3.5rem 2rem;
+ text-align: left;
+ background-color: #fff;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
}
.node-main-login > .main form > div:nth-last-child(1) {
- float: right;
+ float: right;
}
.node-main-login > .main .cbi-value {
- display: block;
+ display: block;
}
.node-main-login > .main .cbi-value > * {
- display: inline-block !important;
+ display: inline-block !important;
}
-.node-main-login > .main .cbi-input-user,
-.node-main-login > .main .cbi-input-password {
- min-width: 15rem;
+.node-main-login > .main .cbi-input-text {
+ min-width: 15rem;
}
-.node-main-login footer {
- bottom: 0;
- position: absolute;
- width: 100%;
+.node-main-login .cbi-section {
+ box-shadow: none;
}
-/* fix status overview */
+@media screen and (min-height: 585px) {
+ .node-main-login footer {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ }
+}
+/* fix status overview */
.node-status-overview > .main fieldset:nth-child(4) .td:nth-child(2) {
- white-space: normal;
+ white-space: normal;
}
/* fix status processes */
-
.node-status-processes > .main .table .tr .td:nth-child(3) {
- white-space: normal;
+ white-space: normal;
}
-.node-status-iptables > .main div > .cbi-map > form {
- margin: 2rem 2rem 0 0;
+.node-admin-status form {
+ margin: 2rem 2rem 0 0;
}
/* fix system reboot */
+[data-page="admin-system-reboot"] p {
+ padding-left: 2rem;
+}
-.node-system-reboot > .main > .main-right p,
-.node-system-reboot > .main > .main-right h3 {
- padding-left: 2rem;
+[data-page="admin-system-reboot"] p > span {
+ position: relative;
+ top: .1rem;
+ left: 1rem;
}
-/* fix Services Network Shares*/
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-title {
- margin-bottom: 1rem;
- width: auto;
+/* samba */
+#cbi-samba .cbi-value-last .cbi-value-field {
+ display: block;
}
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-field {
- display: list-item;
+#cbi-samba .cbi-value-last .cbi-value-title {
+ width: auto;
+ padding-bottom: .6rem;
}
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-description {
- padding-top: 1rem;
+/* software */
+.controls > * > .btn:not([aria-label$="page"]) {
+ flex-grow: initial !important;
+ margin-top: .1rem;
}
-/* fix System Software*/
-.node-system-packages > .main table tr td:nth-child(1) {
- width: auto !important;
+.controls > #pager > .btn[aria-label$="page"] {
+ font-size: 1.4rem;
+ font-weight: bold;
}
-.node-system-packages > .main table tr td:nth-last-child(1) {
- white-space: normal;
- font-size: small;
- color: #404040;
+.controls > * > label {
+ margin-bottom: .2rem;
}
-.node-system-packages > .main .cbi-tabmenu > li > a, .tabs > li > a {
- padding: 0.5rem 0.8rem;
+[data-page="admin-system-opkg"] div.btn {
+ line-height: 3;
+ display: inline;
+ padding: .3rem .6rem;
}
-.node-system-packages > .main .cbi-value > pre {
- background-color: #eee;
- padding: 0.5rem;
- overflow: auto;
+[data-page^="admin-system-admin"]:not(.node-main-login) .cbi-map:not(#cbi-dropbear),
+[data-page="admin-system-opkg"] #maincontent > .container {
+ margin-top: 2rem;
+ padding-top: .1rem;
+}
+
+[data-page="admin-system-opkg"] #maincontent > .container {
+ margin: 2rem;
+ margin-bottom: 1rem;
+}
+
+.td.version,
+.td.size {
+ white-space: normal !important;
+ word-break: break-word;
}
.cbi-tabmenu + .cbi-section {
- margin-top: 0;
+ margin-top: 0;
+}
+
+/* wireless overview */
+#cbi-wireless > #wifi_assoclist_table > .tr {
+ box-shadow: inset 1px -1px 0 #ddd, inset -1px -1px 0 #ddd;
+}
+
+#cbi-wireless > #wifi_assoclist_table > .tr.placeholder > .td {
+ right: 33px;
+ bottom: 33px;
+ left: 33px;
+ border-top: thin solid #ddd !important;
+}
+
+#cbi-wireless > #wifi_assoclist_table > .tr.table-titles {
+ box-shadow: inset 1px 0 0 #ddd, inset -1px 0 0 #ddd;
}
-.node-status-iptables fieldset,
-.node-system-packages fieldset,
-.node-system-flashops fieldset {
- margin-top: 0;
+#cbi-wireless > #wifi_assoclist_table > .tr.table-titles > .th {
+ border-bottom: thin solid #ddd;
+ box-shadow: 0 -1px 0 0 #ddd;
}
-.node-status-iptables .cbi-tabmenu,
-.node-system-packages .cbi-tabmenu,
-.node-system-flashops .cbi-tabmenu {
- border: none;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+#wifi_assoclist_table > .tr > .td[data-title="RX Rate / TX Rate"] {
+ width: 23rem;
}
-.node-system-flashops form.inline + form.inline {
- margin-left: 0;
+/* firewall */
+#iptables {
+ font-family: inherit;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ min-width: inherit;
+ margin: 0 0 2rem 0;
+ padding: 2rem;
+ border: 0;
+ border-radius: 0;
+ background-color: #fff;
}
#cbi-firewall-redirect table *,
#cbi-network-switch_vlan table *,
#cbi-firewall-zone table * {
- font-size: small;
+ font-size: small;
}
#cbi-firewall-redirect table input[type="text"],
#cbi-network-switch_vlan table input[type="text"],
#cbi-firewall-zone table input[type="text"] {
- width: 5rem;
+ width: 5rem;
}
#cbi-firewall-redirect table select,
#cbi-network-switch_vlan table select,
#cbi-firewall-zone table select {
- min-width: 3.5rem;
+ min-width: 3.5rem;
}
#cbi-network-switch_vlan .th,
#cbi-network-switch_vlan .td {
- flex-basis: 12%;
+ flex-basis: 12%;
}
-/* language fix */
-body.lang_pl.node-main-login .cbi-value-title {
- width: 12rem;
+#cbi-firewall-zone .table,
+#cbi-network-switch_vlan .table {
+ display: block;
}
-/* applyreboot fix */
+#cbi-firewall-zone .td.cbi-section-actions {
+ width: 100%;
+}
+/* applyreboot fix */
#applyreboot-container {
margin: 2rem;
}
#applyreboot-section {
- margin: 2rem;
line-height: 300%;
+ margin: 2rem;
+}
+
+/* openvpn bug fix */
+.OpenVPN a {
+ line-height: initial !important;
+}
+
+/* custom commands */
+.commandbox {
+ width: 24% !important;
+ padding: .5rem 1rem;
+ border-bottom: thin solid #ccc;
+ background: #eee;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 1px 2px rgba(0, 0, 0, .05);
+}
+
+.commandbox h3 {
+ line-height: normal !important;
+ overflow: hidden;
+ margin: 6px 0 !important;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.commandbox div {
+ left: auto !important;
+}
+
+.commandbox code {
+ position: absolute;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-width: 60%;
+ max-height: 55px;
+ margin-top: -3px;
+ margin-left: 4px;
+ padding: 2px 3px;
+ text-overflow: ellipsis;
+}
+
+.commandbox p:first-of-type {
+ margin-top: -6px;
+}
+
+.commandbox p:nth-of-type(2) {
+ margin-top: 2px;
+}
+
+[data-page^="admin-system-commands"] .panel-title,
+[data-page^="command-cfg"] .mobile-hide,
+[data-page^="command-cfg"] header > .fill > .container > #logo {
+ display: none;
+}
+
+#command-rc-output .alert-message {
+ line-height: 1.42857143;
+ position: absolute;
+ top: 40px;
+ right: 32px;
+ max-width: 40%;
+ margin: 0;
+ animation: anim-fade-in 1.5s forwards;
+ opacity: 0;
+}
+
+@keyframes anim-fade-in {
+ 100% {
+ opacity: 1;
+ }
}
@media screen and (max-width: 1600px) {
- .btn,
- .cbi-button {
- padding: 0.3rem 0.6rem;
- font-size: 0.8rem;
- }
-
- header > .container > .pull-right > * {
- top: 0.35rem;
- }
-
- .label {
- padding: 0.2rem 0.6rem;
- }
-
- .cbi-value-title {
- width: 15rem;
- padding-right: 0.6rem;
- }
-
- fieldset {
- padding: 1rem;
- }
-
- .cbi-input-textarea {
- font-size: small;
- }
-
- .node-status-iptables > .main fieldset li > a {
- padding: 0.3rem 0.6rem;
- }
-}
-
-@media screen and (max-width: 1280px) {
- header > .container {
- margin-top: 0.25rem;
- }
-
- .cbi-tabmenu > li > a, .tabs > li > a {
- padding: 0.2rem 0.5rem;
- }
-
- .panel-title {
- font-size: 1.1rem;
- padding-bottom: 1rem;
- }
-
- table {
- font-size: 0.7rem !important;
- width: 100% !important;
- }
-}
-
-@media screen and (max-width: 992px) {
- header > .fill > .container > img {
- display: none;
- }
-
- .main-left {
- width: 0;
- position: fixed;
- z-index: 100;
- }
-
- .main-right {
- width: 100%;
- }
-
- .showSide {
- padding: 0.1rem;
- margin-right: 0.5rem;
- display: inline-block;
- }
-
- .showSide:before {
- content: "\e20e";
- font-size: 1.7rem;
- }
-
- .node-main-login .showSide {
- display: none !important;
- }
-
- .cbi-value-title {
- width: 9rem;
- padding-right: 1rem;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div * {
- width: 100% !important;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div input[type="text"] {
- margin: 3rem 0 0 0 !important;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div:nth-child(4) input[type="text"] {
- margin: 0 !important;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div select,
- .node-network-diagnostics > .main .cbi-map fieldset > div input[type="button"] {
- margin: 1rem 0 0 0;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div {
- width: 100% !important;
- }
-
- #diag-rc-output > pre {
- font-size: 1rem;
- }
-
- .node-main-login > .main .cbi-value-title {
- text-align: left;
- }
-
- .tr {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- }
-
- .th, .td {
- flex: 2 2 25%;
- align-self: flex-start;
- overflow: hidden;
- text-overflow: ellipsis;
- word-wrap: break-word;
- display: inline-block;
- }
-
- .td select,
- .td input[type="text"] {
- word-wrap: normal;
- width: 100%;
- }
-
- .td [data-dynlist] > input,
- .td input.cbi-input-password {
- width: calc(100% - 1.5rem);
- }
-
- .td[data-type="button"],
- .td[data-type="fvalue"] {
- flex: 1 1 12.5%;
- text-align: left;
- }
-
- .th.cbi-value-field,
- .td.cbi-value-field,
- .th.cbi-section-table-cell,
- .td.cbi-section-table-cell {
- flex-basis: auto;
- }
-
- .cbi-section-table-row {
- display: flex;
- flex-wrap: wrap;
- flex-direction: row;
- justify-content: space-between;
- }
-
- .td.cbi-value-field,
- .cbi-section-table-cell {
- text-align: center;
- display: inline-block;
- flex: 10 10 auto;
- }
-
- .td.cbi-section-actions {
- text-align: right;
- align-self: flex-end;
- vertical-align: bottom;
- }
-
- .tr.table-titles,
- .tr.cbi-section-table-titles,
- .tr.cbi-section-table-descr {
- display: none;
- }
-
- .tr[data-title]::before,
- .tr.cbi-section-table-titles.named::before {
- display: block;
- flex: 1 1 100%;
- background: #eef;
- font-size: .9rem;
- border-bottom: 1px solid rgba(0, 0, 0, .26);
- }
-
- .td[data-title] {
- text-align: left;
- }
-
- .td[data-title]::before {
- display: block;
- }
-
- .hide-sm,
- .hide-xs {
- display: none;
- }
-}
-
-@media screen and (max-width: 480px) {
- body {
- font-size: 1rem;
- }
-
- fieldset {
- padding: 1rem;
- margin: 1rem 0 0 0;
- }
-
- .tabs {
- margin: 0 -1rem;
- }
-
- #maincontent > .container {
- margin: 0 1rem 1.5rem 1rem;
- }
-
- .main > .main-left > .nav > .slide > .menu {
- font-size: 1.3rem;
- }
-
- .main > .main-left > .nav > .slide > .slide-menu > li > a {
- font-size: 1.1rem;
- }
-
- .cbi-value-title {
- width: 100%;
- min-width: 0rem !important;
- display: block;
- margin-top: 1rem;
- margin-bottom: 0.5rem;
- text-align: left;
- }
-
- .cbi-value-field, .cbi-value-description {
- width: 100%;
- }
-
- .cbi-value > .cbi-value-field {
- display: inline-block;
- }
-
- .cbi-tabmenu > li, .tabs > li {
- padding: 0.6rem 0rem;
- }
-
- .cbi-tabmenu > li > a, .tabs > li > a {
- padding: 0.2rem 0.3rem;
- font-size: 0.9rem;
- }
-
- .cbi-page-actions > div > input {
- display: none;
- }
-
- .node-main-login > .main .container {
- padding: 0.5rem 1rem 2rem 1rem;
- }
-
- .node-main-login > .main .cbi-value {
- padding: 0;
- }
-
- .node-main-login > .main form > div:nth-last-child(1) {
- margin-top: 2rem;
- }
-
- .node-main-login > .main .cbi-value-title {
- width: 100% !important;
- font-size: 1.2rem;
- }
-
- .node-main-login > .main fieldset {
- margin: 0;
- padding: 0.5rem;
- }
-
- h2 {
- font-size: 2rem;
- }
-
- .tabs > li > a {
- font-size: 0.9rem;
- }
-
- select,
- input {
- font-size: 0.9rem;
- }
-
- .mobile-hide {
- display: none;
- }
-
- .panel-title {
- font-size: 1.4rem;
- padding-bottom: 1rem;
- }
-
- .node-system-packages > .main .cbi-value.cbi-value-last > div {
- width: 100% !important;
- }
-
- .node-system-packages > .main .cbi-value .cbi-value-field input {
- width: 100%;
- }
-
- .node-status-iptables > .main div > .cbi-map > form {
- position: static !important;
- margin: 0 0 2rem 0;
- padding: 2rem;
- border: 0;
- font-weight: normal;
- font-style: normal;
- line-height: 1;
- font-family: inherit;
- min-width: inherit;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
- -webkit-overflow-scrolling: touch;
- }
-
- .node-status-iptables > .main div > .cbi-map > form input[type="submit"] {
- width: 100% !important;
- margin: 0;
- }
-
- .node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] {
- margin-top: 1rem;
- }
-
- .th, .td {
- flex-basis: 50%;
- }
-
- .td.cbi-value-field {
- flex-basis: 100%;
- }
-
- .td.cbi-value-field[data-type="dvalue"] {
- flex-basis: 50%;
- }
-
- .td.cbi-value-field[data-type="button"],
- .td.cbi-value-field[data-type="fvalue"] {
- flex-basis: 25%;
- text-align: left;
- }
-
- .tr[data-title]::before,
- .tr.cbi-section-table-titles.named::before {
- font-size: 1rem;
- }
-
- .hide-xs {
- display: none;
- }
-}
-
-@media screen and (min-width: 992px) {
- .cbi-value input[type="password"],
- .cbi-value input[type="text"],
- .cbi-value-field .cbi-input-select {
- width: 20rem;
- }
-
- .cbi-value-field .cbi-dropdown {
- min-width: 20rem;
- }
-}
-
-@media screen and (min-width: 1280px) {
- .cbi-value input[type="password"],
- .cbi-value input[type="text"],
- .cbi-value-field .cbi-input-select {
- width: 22rem;
- }
-
- .cbi-value-field .cbi-dropdown {
- min-width: 22rem;
- }
+ header > .fill > .container > #logo {
+ margin: 0 2.5rem 0 .5rem;
+ }
+
+ .main-left {
+ width: calc(0% + 13rem);
+ }
+
+ .main-right {
+ width: calc(100% - 13rem);
+ }
+
+ .cbi-dynlist > .item {
+ max-width: 21.9rem;
+ }
+
+ .btn:not(button),
+ .cbi-button {
+ font-size: .8rem;
+ padding: .3rem .6rem;
+ }
+
+ .label {
+ padding: .2rem .6rem;
+ }
+
+ .cbi-value-title {
+ width: 15rem;
+ padding-right: .6rem;
+ }
+
+ fieldset,
+ .cbi-section {
+ padding: 1rem;
+ }
+
+ .cbi-input-textarea {
+ font-size: small;
+ }
+
+ .node-admin-status > .main fieldset li > a {
+ padding: .3rem .6rem;
+ }
+
+ #cbi-firewall-zone > .table {
+ display: block;
+ }
+}
+
+@media screen and (max-width: 1366px) {
+ header {
+ height: 3.5rem;
+ }
+
+ header > .fill > .container {
+ margin-top: .25rem;
+ cursor: default;
+ }
+
+ .main {
+ top: 3.5rem;
+ height: calc(100% - 3.5rem);
+ }
+
+ .main-left {
+ top: 3.5rem;
+ width: calc(0% + 13rem);
+ height: calc(100% - 3.5rem);
+ }
+
+ .main-right {
+ width: calc(100% - 13rem);
+ }
+
+ .cbi-dynlist > .item {
+ max-width: 19.9rem;
+ }
+
+ .cbi-tabmenu > li > a,
+ .tabs > li > a {
+ padding: .2rem .5rem;
+ }
+
+ .panel-title {
+ font-size: 1.1rem;
+ padding-bottom: 1rem;
+ }
+
+ table {
+ font-size: .7rem !important;
+ width: 100% !important;
+ }
+
+ .table .cbi-input-text {
+ width: 100%;
+ }
+
+ .main > .main-left > .nav > li,
+ .main > .main-left > .nav > li a,
+ .main > .main-left > .nav > .slide > .menu {
+ font-size: .9rem;
+ }
+
+ .main > .main-left > .nav > .slide > .slide-menu > li > a {
+ font-size: .7rem;
+ }
+
+ #modal_overlay {
+ top: 3.5rem;
+ }
+
+ [data-page="admin-network-firewall-forwards"] .table:not(.cbi-section-table) {
+ display: block;
+ }
+
+ [data-page="admin-network-firewall-forwards"] .table:not(.cbi-section-table),
+ [data-page="admin-network-firewall-rules"] .table:not(.cbi-section-table),
+ [data-page="admin-network-hosts"] .table {
+ overflow-y: visible;
+ }
+
+ .commandbox {
+ width: 32% !important;
+ }
+}
+
+@media screen and (max-width: 1152px) {
+ header > .fill > .container > #logo {
+ display: none;
+ }
+
+ header > .fill > .container > .brand {
+ position: relative;
+ }
+
+ [data-page^="command-cfg"] header > .fill > .container > .brand {
+ display: block;
+ margin-top: -1.75rem;
+ }
+
+ html,
+ .main {
+ overflow-y: visible;
+ }
+
+ .main-left {
+ position: fixed;
+ z-index: 100;
+ width: 0;
+ }
+
+ .main-right {
+ width: 100%;
+ }
+
+ .cbi-dynlist > .item {
+ max-width: 14.9rem;
+ }
+
+ .showSide {
+ display: inline-block;
+ overflow: visible;
+ margin-right: .5rem;
+ padding: .1rem;
+ cursor: pointer;
+ border-radius: 50%;
+ }
+
+ .showSide:before {
+ font-size: 1.7rem;
+ content: "\e20e";
+ }
+
+ body:not(.logged-in) .showSide {
+ visibility: hidden;
+ width: 0;
+ margin: 0;
+ padding: 0;
+ }
+
+ .node-main-login > .main .cbi-value-title {
+ text-align: left;
+ }
+
+ .cbi-value-title {
+ width: 9rem;
+ padding-right: 1rem;
+ }
+
+ #diag-rc-output > pre,
+ #command-rc-output > pre {
+ font-size: 1rem;
+ }
+
+ .table {
+ display: block;
+ }
+
+ #packages.table {
+ display: grid;
+ }
+
+ .tr {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
+
+ .Overview .table[width="100%"] > .tr {
+ flex-wrap: nowrap;
+ }
+
+ .tr.placeholder {
+ border-bottom: thin solid #ddd;
+ }
+
+ .tr.placeholder > .td,
+ #cbi-firewall .tr > .td,
+ #iptables .tr:nth-child(2) > .td,
+ #cbi-network .tr:nth-child(2) > .td,
+ .cbi-section #wifi_assoclist_table .tr > .td {
+ border-top: 0;
+ }
+
+ .th,
+ .td {
+ display: inline-block;
+ align-self: flex-start;
+ flex: 2 2 25%;
+ text-overflow: ellipsis;
+ word-wrap: break-word;
+ }
+
+ .td select,
+ .td input[type="text"] {
+ width: 100%;
+ word-wrap: normal;
+ }
+
+ .td [data-dynlist] > input,
+ .td input.cbi-input-password {
+ width: calc(100% - 1.5rem);
+ }
+
+ .td[data-type="button"],
+ .td[data-type="fvalue"] {
+ flex: 1 1 12.5%;
+ text-align: left;
+ }
+
+ .th.cbi-value-field,
+ .td.cbi-value-field,
+ .th.cbi-section-table-cell,
+ .td.cbi-section-table-cell {
+ flex-basis: auto;
+ padding-top: 1rem;
+ }
+
+ .cbi-section-table-row {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ }
+
+ .td.cbi-value-field,
+ .cbi-section-table-cell {
+ display: inline-block;
+ flex: 10 10 auto;
+ flex-basis: 50%;
+ text-align: center;
+ }
+
+ .td.cbi-section-actions {
+ vertical-align: bottom;
+ }
+
+ .tr.table-titles,
+ .tr.cbi-section-table-titles,
+ .tr.cbi-section-table-descr {
+ display: none;
+ }
+
+ .tr[data-title]::before,
+ .tr.cbi-section-table-titles.named::before {
+ font-size: .9rem;
+ display: block;
+ flex: 1 1 100%;
+ border-bottom: thin solid rgba(0, 0, 0, .26);
+ background: #90c0e0;
+ }
+
+ .td[data-title],
+ [data-page^="admin-status-realtime"] .td[id] {
+ text-align: left;
+ }
+
+ .td[data-title]::before {
+ display: block;
+ }
+
+ .cbi-button + .cbi-button {
+ margin-left: 0;
+ }
+
+ .td.cbi-section-actions > * > *,
+ .td.cbi-section-actions > * > form > * {
+ margin: 2.1px 3px;
+ }
+
+ .Firewall form {
+ font-family: inherit;
+ font-weight: normal;
+ font-style: normal;
+ line-height: normal;
+ position: static !important;
+ min-width: inherit;
+ margin: 0 0 2rem 0;
+ padding: 2rem;
+ border: 0;
+ border-radius: 0;
+ background-color: #fff;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ }
+
+ .Firewall form input {
+ width: 100% !important;
+ margin: 0;
+ margin-top: 1rem;
+ }
+
+ .Firewall .center,
+ .Firewall .center::before {
+ text-align: left !important;
+ }
+
+ .commandbox {
+ width: 100% !important;
+ }
+}
+
+@media screen and (max-width: 600px) {
+ body {
+ font-size: .8rem;
+ }
+
+ .cbi-progressbar::after {
+ font-size: .95em;
+ line-height: 1.5;
+ }
+
+ fieldset,
+ .cbi-section {
+ margin: 1rem 0 0 0;
+ padding: 1rem;
+ }
+
+ .tabs {
+ margin: 0 -1rem;
+ }
+
+ #maincontent > .container {
+ margin: 0 1rem 1.5rem 1rem;
+ }
+
+ .main > .main-left > .nav > .slide > .menu {
+ font-size: 1.2rem;
+ }
+
+ .main > .main-left > .nav > .slide > .slide-menu > li > a {
+ font-size: 1rem;
+ }
+
+ .cbi-value-title {
+ display: block;
+ width: 100%;
+ min-width: 0 !important;
+ margin-top: 1rem;
+ margin-bottom: .5rem;
+ text-align: left;
+ }
+
+ .cbi-value-field,
+ .cbi-value-description {
+ width: 100%;
+ }
+
+ .cbi-value > .cbi-value-field {
+ display: inline-block;
+ }
+
+ .cbi-tabmenu > li,
+ .tabs > li {
+ padding: .6rem 0;
+ }
+
+ .cbi-tabmenu > li > a,
+ .tabs > li > a {
+ font-size: .9rem;
+ padding: .2rem .3rem;
+ }
+
+ .cbi-page-actions > div > input {
+ display: none;
+ }
+
+ .cbi-page-actions > .cbi-button {
+ margin-top: .2rem;
+ }
+
+ .node-main-login > .main .container {
+ margin: 2rem 1.2rem 1.5rem 1.2rem !important;
+ padding: .3rem 1.7rem 2rem 1.6rem;
+ }
+
+ .node-main-login > .main .cbi-value {
+ padding: 0;
+ }
+
+ .node-main-login > .main form > div:nth-last-child(1) {
+ margin-top: 2rem;
+ }
+
+ .node-main-login > .main .cbi-value-title {
+ font-size: 1.2rem;
+ width: 100% !important;
+ }
+
+ .node-main-login > .main fieldset {
+ margin: 0;
+ padding: .5rem;
+ }
+
+ .commandbox p:first-of-type {
+ margin-top: -8px;
+ }
+
+ #diag-rc-output > pre,
+ #command-rc-output > pre {
+ font-size: .8rem;
+ }
+
+ h2 {
+ font-size: 2rem;
+ }
+
+ .tabs > li > a {
+ font-size: .9rem;
+ }
+
+ select,
+ input {
+ font-size: .9rem;
+ }
+
+ code {
+ font-size: .8rem;
+ }
+
+ .mobile-hide {
+ display: none;
+ }
+
+ .panel-title {
+ font-size: 1.4rem;
+ padding-bottom: 1rem;
+ }
+
+ .node-system-packages > .main .cbi-value.cbi-value-last > div {
+ width: 100% !important;
+ }
+
+ .node-system-packages > .main .cbi-value .cbi-value-field input {
+ width: 100%;
+ }
+
+ .th,
+ .td {
+ flex-basis: 50%;
+ }
+
+ .td.cbi-value-field {
+ flex-basis: 100%;
+ }
+
+ .td.cbi-value-field[data-type="button"],
+ .td.cbi-value-field[data-type="fvalue"] {
+ flex-basis: 25%;
+ text-align: left;
+ }
+
+ .tr[data-title]::before,
+ .tr.cbi-section-table-titles.named::before {
+ font-size: 1rem;
+ }
+
+ td > .ifacebadge,
+ .td > .ifacebadge {
+ font-size: .62rem;
+ }
+
+ #cbi-wireless .td {
+ overflow: hidden;
+ }
+
+ .hide-sm,
+ .hide-xs:not([data-title="MAC-Address"]) {
+ display: none;
+ }
+}
+
+@media screen and (min-width: 1152px) {
+ .cbi-value input[type="password"],
+ .cbi-value input[type="text"] {
+ min-width: 20rem;
+ }
+
+ .cbi-value-field .cbi-input-select {
+ width: 20rem;
+ }
+
+ .cbi-value-field .cbi-dropdown {
+ min-width: 20rem;
+ }
+
+ .cbi-section-node .tr {
+ overflow: hidden;
+ }
+}
+
+@media screen and (min-width: 1366px) {
+ .cbi-value input[type="password"],
+ .cbi-value input[type="text"] {
+ min-width: 22rem;
+ }
+
+ .cbi-value-field .cbi-input-select {
+ width: 22rem;
+ }
+
+ .cbi-value-field .cbi-dropdown {
+ min-width: 22rem;
+ }
}
@media screen and (min-width: 1600px) {
- .cbi-value input[type="password"],
- .cbi-value input[type="text"],
- .cbi-value-field .cbi-input-select {
- width: 25rem;
- }
-
- .cbi-value-field .cbi-dropdown {
- min-width: 25rem;
- }
+ .cbi-value input[type="password"],
+ .cbi-value input[type="text"] {
+ min-width: 25rem;
+ }
+
+ .cbi-value-field .cbi-input-select {
+ width: 25rem;
+ }
+
+ .cbi-value-field .cbi-dropdown {
+ min-width: 25rem;
+ }
}
diff --git a/themes/luci-theme-material/htdocs/luci-static/material/custom.css b/themes/luci-theme-material/htdocs/luci-static/material/custom.css
index e53ac6db4c..6acd5aa3dd 100644
--- a/themes/luci-theme-material/htdocs/luci-static/material/custom.css
+++ b/themes/luci-theme-material/htdocs/luci-static/material/custom.css
@@ -1,11 +1,12 @@
-
:root {
- --main-color: #0099CC;
- --header-bg: #0099CC;
- --header-color: #FFFFFF;
- --menu-bg-color: #FFFFFF;
- --menu-color: #404040;
- --submenu-bg-hover: #D4D4D4;
- --submenu-bg-hover-active: #0099CC;
+ --main-color: #09c;
+ --header-bg: #09c;
+ --header-color: #fff;
+ --bar-bg: #5bc0de;
+ --menu-bg-color: #fff;
+ --menu-color: #5f6368;
+ --menu-color-hover: #202124;
+ --submenu-bg-hover: #d4d4d4;
+ --submenu-bg-hover-active: #09c;
--font-body: "Microsoft Yahei", "WenQuanYi Micro Hei", "sans-serif", "Helvetica Neue", "Helvetica", "Hiragino Sans GB";
}
diff --git a/themes/luci-theme-material/htdocs/luci-static/material/js/script.js b/themes/luci-theme-material/htdocs/luci-static/material/js/script.js
index 27bb5ac038..3c25ed712d 100755
--- a/themes/luci-theme-material/htdocs/luci-static/material/js/script.js
+++ b/themes/luci-theme-material/htdocs/luci-static/material/js/script.js
@@ -159,7 +159,7 @@
$(".main-left").stop(true).animate({
width: "0"
}, "fast");
- $(".main-right").css("overflow-y", "auto");
+ $(".main-right").css("overflow-y", "visible");
showSide = false;
} else {
$(".darkMask").stop(true).fadeIn("fast");
@@ -179,7 +179,7 @@
$(".main-left").stop(true).animate({
width: "0"
}, "fast");
- $(".main-right").css("overflow-y", "auto");
+ $(".main-right").css("overflow-y", "visible");
}
});
diff --git a/themes/luci-theme-material/luasrc/view/themes/material/header.htm b/themes/luci-theme-material/luasrc/view/themes/material/header.htm
index 052c174dca..f463ef5cb2 100644
--- a/themes/luci-theme-material/luasrc/view/themes/material/header.htm
+++ b/themes/luci-theme-material/luasrc/view/themes/material/header.htm
@@ -206,7 +206,7 @@
<div class="fill">
<div class="container">
<span class="showSide"></span>
- <img src="<%=media%>/brand.png"/>
+ <a id="logo" href="<%=url("admin/status/overview")%>"><img src="<%=media%>/brand.png" alt="OpenWrt"></a>
<a class="brand" href="#"><%=boardinfo.hostname or "?"%></a>
<div class="status">
<% render_changes() %>
diff --git a/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css b/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css
index 58065948f4..cbe0e11505 100644
--- a/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css
+++ b/themes/luci-theme-openwrt/htdocs/luci-static/openwrt.org/cascade.css
@@ -29,12 +29,12 @@ body {
box-sizing: border-box;
}
-.table { display: table; width: 100%; position: relative; }
+.table { display: table; width: 100%; position: relative; border-collapse: collapse; }
.tr { display: table-row; }
.thead { display: table-header-group; }
.tbody { display: table-row-group; }
.tfoot { display: table-footer-group; }
-.td, .th { display: table-cell; }
+.td, .th { display: table-cell; vertical-align: middle; }
.th { font-weight: bold; }
.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; }
@@ -568,8 +568,9 @@ input[type=text],
input[type=password],
.cbi-dropdown {
width: 20em;
- font-size: 12px;
height: 22px;
+ font-family: inherit;
+ font-size: inherit;
}
select[multiple] {
@@ -945,7 +946,7 @@ div.cbi-optionals {
font-weight: bold;
text-align: left;
display: none;
- padding: 1px;
+ padding: 1px 0;
white-space: nowrap;
}
@@ -1035,15 +1036,29 @@ ul.cbi-tabmenu li a:hover {
flex: 1 1 auto;
width: 100%;
height: 100%;
+ outline: none;
}
-ul.cbi-tabmenu li.cbi-tab-highlighted {
+ul.cbi-tabmenu li.cbi-tab {
color: #000;
- background: #fea;
+ background: #f5f5f5;
}
-ul.cbi-tabmenu li.cbi-tab {
- color: #000;
+ul.cbi-tabmenu li.cbi-tab-disabled[data-errors]::after {
+ content: attr(data-errors);
+ background: #c43c35;
+ color: #fff;
+ min-width: 12px;
+ line-height: 14px;
+ border-radius: 8px;
+ text-align: center;
+ margin: 4px 5px 4px 0;
+ padding: 1px 2px;
+ word-wrap: normal;
+ flex: 1 0 auto;
+}
+
+.cbi-section ul.cbi-tabmenu li.cbi-tab {
background: #fff;
}
@@ -1056,6 +1071,19 @@ ul.cbi-tabmenu li.cbi-tab {
padding: .5em .5em .5em 2em;
}
+[data-tab-title] {
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+}
+
+[data-tab-active="true"] {
+ opacity: 1;
+ height: auto;
+ overflow: visible;
+ transition: opacity .25s ease-in;
+}
+
.cbi-dropdown {
border: 1px inset #000;
@@ -1242,7 +1270,9 @@ ul.cbi-tabmenu li.cbi-tab {
border-radius: 3px;
position: relative;
pointer-events: none;
- word-break: break-all;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.cbi-dynlist > .item::after {
diff --git a/themes/luci-theme-rosy/htdocs/luci-static/rosy/cascade.css b/themes/luci-theme-rosy/htdocs/luci-static/rosy/cascade.css
index 3df1101959..77f0ecf3e2 100644
--- a/themes/luci-theme-rosy/htdocs/luci-static/rosy/cascade.css
+++ b/themes/luci-theme-rosy/htdocs/luci-static/rosy/cascade.css
@@ -19,40 +19,44 @@
@font-face {
font-family: 'icomoon';
src: url('fonts/font.eot');
- src: url('fonts/font.eot') format('embedded-opentype'),
- url('fonts/font.ttf') format('truetype'),
- url('fonts/font.woff') format('woff'),
- url('fonts/font.svg') format('svg');
+ src: url('fonts/font.eot') format('embedded-opentype'), url('fonts/font.ttf') format('truetype'), url('fonts/font.woff') format('woff'), url('fonts/font.svg') format('svg');
font-weight: normal;
font-style: normal;
}
-
strong {
font-weight: normal;
}
-
-.table { display: table; position: relative; }
-.tr { display: table-row; }
-.thead { display: table-header-group; }
-.tbody { display: table-row-group; }
-.tfoot { display: table-footer-group; }
-.td, .th {
+.table {
+ display: table;
+ position: relative;
+}
+.tr {
+ display: table-row;
+}
+.thead {
+ display: table-header-group;
+}
+.tbody {
+ display: table-row-group;
+}
+.tfoot {
+ display: table-footer-group;
+}
+.td,
+.th {
vertical-align: middle;
text-align: center;
display: table-cell;
padding: .8em;
}
-
.th {
- font-weight: bold;
+ font-weight: normal;
}
-
.tr.placeholder {
height: 4em;
background-color: #f9f9f9;
}
-
-.tr.placeholder > .td {
+.tr.placeholder>.td {
position: absolute;
left: 0;
right: 0;
@@ -61,25 +65,60 @@ strong {
line-height: 3em;
background: #f9f9f9;
}
-
-.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; }
-.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; }
-
-.col-1 { flex: 1 1 30px !important; -webkit-flex: 1 1 30px !important; }
-.col-2 { flex: 2 2 60px !important; -webkit-flex: 2 2 60px !important; }
-.col-3 { flex: 3 3 90px !important; -webkit-flex: 3 3 90px !important; }
-.col-4 { flex: 4 4 120px !important; -webkit-flex: 4 4 120px !important; }
-.col-5 { flex: 5 5 150px !important; -webkit-flex: 5 5 150px !important; }
-.col-6 { flex: 6 6 180px !important; -webkit-flex: 6 6 180px !important; }
-.col-7 { flex: 7 7 210px !important; -webkit-flex: 7 7 210px !important; }
-.col-8 { flex: 8 8 240px !important; -webkit-flex: 8 8 240px !important; }
-.col-9 { flex: 9 9 270px !important; -webkit-flex: 9 9 270px !important; }
-.col-10 { flex: 10 10 300px !important; -webkit-flex: 10 10 300px !important; }
-
+.table[width="33%"],
+.th[width="33%"],
+.td[width="33%"] {
+ width: 33%;
+}
+.table[width="100%"],
+.th[width="100%"],
+.td[width="100%"] {
+ width: 100%;
+}
+.col-1 {
+ flex: 1 1 30px !important;
+ -webkit-flex: 1 1 30px !important;
+}
+.col-2 {
+ flex: 2 2 60px !important;
+ -webkit-flex: 2 2 60px !important;
+}
+.col-3 {
+ flex: 3 3 90px !important;
+ -webkit-flex: 3 3 90px !important;
+}
+.col-4 {
+ flex: 4 4 120px !important;
+ -webkit-flex: 4 4 120px !important;
+}
+.col-5 {
+ flex: 5 5 150px !important;
+ -webkit-flex: 5 5 150px !important;
+}
+.col-6 {
+ flex: 6 6 180px !important;
+ -webkit-flex: 6 6 180px !important;
+}
+.col-7 {
+ flex: 7 7 210px !important;
+ -webkit-flex: 7 7 210px !important;
+}
+.col-8 {
+ flex: 8 8 240px !important;
+ -webkit-flex: 8 8 240px !important;
+}
+.col-9 {
+ flex: 9 9 270px !important;
+ -webkit-flex: 9 9 270px !important;
+}
+.col-10 {
+ flex: 10 10 300px !important;
+ -webkit-flex: 10 10 300px !important;
+}
.cbi-button-up,
.cbi-button-down,
.cbi-value-helpicon,
-.main > .loading > span {
+.main>.loading>span {
font-family: 'icomoon' !important;
speak: none;
font-style: normal !important;
@@ -87,43 +126,37 @@ strong {
font-variant: normal !important;
text-transform: none !important;
line-height: 1;
-
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
-
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
-
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
font-family: inherit;
- font-weight: 400;
+ font-weight: normal;
line-height: 1.1;
color: inherit;
}
-
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
position: relative;
}
-
body {
font-size: 0.8rem;
background-color: #EEE;
}
-
-html, body {
+html,
+body {
margin: 0px;
padding: 0px;
height: auto;
min-height: 100%;
font-family: Microsoft Yahei, WenQuanYi Micro Hei, sans-serif, "Helvetica Neue", Helvetica, Hiragino Sans GB;
}
-
select {
padding: 0.36rem 0.8rem;
color: #555;
@@ -131,7 +164,6 @@ select {
background-image: none;
border: 1px solid #ccc;
}
-
select,
input,
.cbi-dropdown {
@@ -147,38 +179,31 @@ input,
height: auto;
font-size: 0.8rem;
}
-
select:not([multiple="multiple"]):focus,
input:focus {
border-color: #0099CC;
}
-
select[multiple="multiple"] {
height: auto;
}
-
code {
color: #0099CC;
}
-
abbr {
color: #005470;
text-decoration: underline;
cursor: help;
}
-
hr {
margin: 1rem 0;
border-color: #EEE;
opacity: 0.1;
}
-
-footer > a {
+footer>a {
color: #aaa;
text-decoration: none;
}
-
-.main > .loading {
+.main>.loading {
position: fixed;
width: 100%;
height: 100%;
@@ -187,8 +212,7 @@ footer > a {
background-color: #354057;
top: 0;
}
-
-.main > .loading > span {
+.main>.loading>span {
display: block;
text-align: center;
margin-top: 2rem;
@@ -196,33 +220,27 @@ footer > a {
font-size: 1.2rem;
line-height: 45px;
}
-
-.main > .loading > span > .loading-img {
+.main>.loading>span>.loading-img {
margin-right: 0.2rem;
display: inline-block;
}
-
-.main > .loading > span > .loading-img img {
+.main>.loading>span>.loading-img img {
vertical-align: middle;
}
-
.pull-right {
float: right;
}
-
.pull-left {
float: left;
}
li {
list-style-type: none;
}
-
h1 {
font-size: 2rem;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
-
h2 {
margin: 2rem 0 0 0;
color: #354057;
@@ -230,28 +248,23 @@ h2 {
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
-
h3 {
margin: 2rem 0 0 0;
font-size: 1.4rem;
padding-bottom: 10px;
}
-
h4 {
margin: 2rem 0 0 0;
font-size: 1.2rem;
padding-bottom: 10px;
}
-
.mobile-hide {
display: inline-block;
}
-
.PC-hide {
width: 100%;
display: none;
}
-
.cbi-section {
margin: 1rem 0 0 0;
padding: 2rem;
@@ -263,15 +276,12 @@ h4 {
min-width: inherit;
border-radius: 20px;
background-color: #FFF;
-
-webkit-overflow-scrolling: touch;
}
-
-.cbi-section > legend {
+.cbi-section>legend {
display: none !important;
}
-
-.cbi-section > h3:first-child,
+.cbi-section>h3:first-child,
.panel-title {
width: 100%;
display: block;
@@ -281,82 +291,54 @@ h4 {
padding-bottom: 1rem;
margin: 0;
}
-
.table {
width: 100%;
border-radius: 20px;
}
-
-.table > .tbody > .tr > .td,
-.table > .tbody > .tr > .th,
-.table > .tfoot > .tr > .td,
-.table > .tfoot > .tr > .th,
-.table > .thead > .tr > .td,
-.table > .thead > .tr > .th {
+.table>.tbody>.tr>.td,
+.table>.tbody>.tr>.th,
+.table>.tfoot>.tr>.td,
+.table>.tfoot>.tr>.th,
+.table>.thead>.tr>.td,
+.table>.thead>.tr>.th {
padding: .5rem;
border-top: 1px solid #ddd;
white-space: nowrap;
}
-
.cbi-section-table-cell {
white-space: nowrap;
align-self: flex-end;
flex: 1 1 auto;
}
-
.cbi-section-table {
border: none;
}
-
.cbi-section-table-row {
text-align: center;
margin-bottom: 1rem;
background: #f4f4f4;
}
-
.cbi-section-table-row:last-child {
margin-bottom: 0;
}
-
-.cbi-section-table-row > .cbi-value-field .cbi-input-select,
-.cbi-section-table-row > .cbi-value-field .cbi-input-text,
-.cbi-section-table-row > .cbi-value-field .cbi-input-password,
-.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
+.cbi-section-table-row>.cbi-value-field .cbi-input-select,
+.cbi-section-table-row>.cbi-value-field .cbi-input-text,
+.cbi-section-table-row>.cbi-value-field .cbi-input-password,
+.cbi-section-table-row>.cbi-value-field .cbi-dropdown {
width: 100%;
}
-
-.cbi-section-table-row > .cbi-value-field [data-dynlist] > input,
-.cbi-section-table-row > .cbi-value-field input.cbi-input-password {
+.cbi-section-table-row>.cbi-value-field [data-dynlist]>input,
+.cbi-section-table-row>.cbi-value-field input.cbi-input-password {
width: calc(100% - 1.5rem);
}
-
-div > table > tbody > tr:nth-of-type(2n),
-div > .table > .tbody > .tr:nth-of-type(2n) {
+div>table>tbody>tr:nth-of-type(2n),
+div>.table>.tbody>.tr:nth-of-type(2n) {
background-color: #f9f9f9;
}
-
-div > table > tbody > tr:nth-of-type(2n),
-div > .table > .tbody > .tr:nth-of-type(2n) {
+div>table>tbody>tr:nth-of-type(2n),
+div>.table>.tbody>.tr:nth-of-type(2n) {
background-color: #f9f9f9;
}
-
-.cbi-section .table #memtotal > div,
-.cbi-section .table #memfree > div,
-.cbi-section .table #membuff > div,
-.cbi-section .table #conns > div {
- border-radius: 20px;
- overflow: hidden;
- border: none !important;
- background-color: #9bc1cc;
-}
-
-.cbi-section .table #memtotal > div > div > div,
-.cbi-section .table #memfree > div > div > div,
-.cbi-section .table #membuff > div > div > div,
-.cbi-section .table #conns > div > div > div {
- color: #fff !important;
-}
-
.cbi-section .table .tr.table-titles {
background-color: #eee;
}
@@ -369,7 +351,7 @@ div > .table > .tbody > .tr:nth-of-type(2n) {
.table .tr:first-child .th:last-child {
border-top-right-radius: 10px;
}
-.table .tr:last-child .td:first-child,
+.table .tr:last-child .td:first-child,
.table .tr:last-child::before {
border-bottom-left-radius: 10px;
}
@@ -379,65 +361,60 @@ div > .table > .tbody > .tr:nth-of-type(2n) {
.table .tr.placeholder:last-child {
background-color: transparent;
}
-
.cbi-section .table .cbi-section-table-titles {
background-color: #e0e0e0;
}
-
/* fix progress bar */
-#swaptotal > div,
-#swapfree > div,
-#memfree > div,
-#membuff > div,
-#conns > div,
-#memtotal > div {
- width: 100% !important;
- height: 1.2rem !important;
-}
-
-#swaptotal > div > div,
-#swapfree > div > div,
-#memfree > div > div,
-#membuff > div > div,
-#conns > div > div,
-#memtotal > div > div {
- height: 100% !important;
- background-color: #468ea4 !important;
+.cbi-progressbar {
+ background-color: #9bc1cc;
+ border-radius: 20px;
+ overflow: hidden;
+ position: relative;
+}
+.cbi-progressbar div {
+ background-color: #468ea4;
+ height: 20px;
+ border-radius: 20px;
+}
+.cbi-progressbar::after {
+ content: attr(title);
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ text-align: center;
+ line-height: 1.2rem;
+ color: #fff;
}
-
/* fix multiple table */
-
table table,
.table .table {
border: none;
}
-
.cbi-value-field table,
.cbi-value-field .table {
border: none;
}
-
-td > table > tbody > tr > td,
-.td > .table > .tbody > .tr > .td {
+td>table>tbody>tr>td,
+.td>.table>.tbody>.tr>.td {
border: none;
}
-
-.cbi-value-field > table > tbody > tr > td,
-.cbi-value-field > .table > .tbody > .tr > .td {
+.cbi-value-field>table>tbody>tr>td,
+.cbi-value-field>.table>.tbody>.tr>.td {
border: none;
}
-
/* button style */
-
-.btn, .cbi-button {
+.btn,
+.cbi-button {
margin: 0 .8rem .5rem 0;
-webkit-appearance: none;
- color: rgba(0, 0, 0, 0.87);
- background-color: #F0F0F0;
+ color: #354057;
+ background-color: transparent;
transition: all 0.2s ease-in-out;
display: inline-block;
padding: .5rem .8rem;
- border: none;
+ border: 1px solid;
border-radius: 25px;
cursor: pointer;
-ms-touch-action: manipulation;
@@ -455,7 +432,6 @@ td > table > tbody > tr > td,
display: inline-block;
text-decoration: none;
}
-
.btn:disabled,
.cbi-button:disabled {
cursor: not-allowed;
@@ -463,156 +439,152 @@ td > table > tbody > tr > td,
opacity: 0.60;
box-shadow: none;
}
-
.cbi-page-actions .cbi-button-apply,
.cbi-section-actions .cbi-button-edit,
.cbi-button-edit.important,
.cbi-button-apply.important,
.cbi-button-reload.important,
-.cbi-button-action.important {
+.cbi-button-apply,
+.cbi-page-actions .cbi-button-save {
color: #fff;
background-color: #337ab7;
+ border: none;
}
-
-.cbi-page-actions .cbi-button-save,
.cbi-button-add.important,
.cbi-button-save.important,
-.cbi-button-positive.important {
- color: #fff;
- background-color: #5bc0de;
+.cbi-button-positive.important,
+.cbi-button-action.important,
+.cbi-section-actions .cbi-button-edit {
+ color: #337ab7;
+ background-color: transparent;
+ border: 1px solid #337ab7;
}
-
.cbi-button-remove.important,
.cbi-button-reset.important,
.cbi-button-negative.important {
color: #fff;
background-color: #d9534f;
+ border: none;
}
-
.cbi-button-find,
.cbi-button-link,
.cbi-button-up,
.cbi-button-down,
.cbi-button-neutral {
- background-color: #468ea4;
- color: #fff;
+ color: #468ea4;
+ background-color: transparent;
+ border: 1px solid #468ea4;
}
-
.cbi-button-edit,
-.cbi-button-apply,
.cbi-button-reload,
.cbi-button-action {
- color: #fff;
- background-color: #468ea4;
+ color: #468ea4;
+ background-color: transparent;
+ border: 1px solid #468ea4;
}
-
-.cbi-page-actions .cbi-button-apply + .cbi-button-save,
+.cbi-page-actions .cbi-button-apply+.cbi-button-save,
.cbi-button-add,
.cbi-button-save,
.cbi-button-positive {
- color: #fff;
- background-color: #354057;
+ color: #354057;
+ background-color: transparent;
+ border: 1px solid #354057;
}
-
-.cbi-section-remove > .cbi-button,
+.cbi-section-remove>.cbi-button,
.cbi-button-remove,
.cbi-button-reset,
.cbi-button-negative {
- color: #fff;
- background-color: #F24C7C;
+ color: #F24C7C;
+ background-color: transparent;
+ border: 1px solid #F24C7C;
}
-
.cbi-page-actions .cbi-button-link:first-child {
float: left;
}
-
.a-to-btn {
text-decoration: none;
}
-
/* table */
-
-.container > .tabs,
-.container > .tabs > li[class~="active"],
-.container > .tabs > li:hover,
-.container > .cbi-tabmenu,
-.container > .cbi-tabmenu > li[class~="cbi-tab"],
-.container > .cbi-tabmenu > li:hover {
+.container>.tabs,
+.container>.tabs>li[class~="active"],
+.container>.tabs>li:hover,
+.container>.cbi-tabmenu,
+.container>.cbi-tabmenu>li[class~="cbi-tab"],
+.container>.cbi-tabmenu>li:hover {
border-radius: 20px;
}
-
.container .cbi-map .cbi-tabmenu,
-.container .cbi-map .cbi-tabmenu > li[class~="cbi-tab"],
-.container .cbi-map .cbi-tabmenu > li:hover {
+.container .cbi-map .cbi-tabmenu>li[class~="cbi-tab"],
+.container .cbi-map .cbi-tabmenu>li:hover {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
-
.container .cbi-map .cbi-tabmenu,
-.container > .tabs,
-.container > .cbi-tabmenu {
+.container>.tabs,
+.container>.cbi-tabmenu {
overflow: hidden;
}
-
-.container .cbi-map .cbi-tabmenu + div {
+.container .cbi-map .cbi-tabmenu+div {
border-radius: 0;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
- overflow: hidden;
}
-
.tabs {
background-color: #FFFFFF;
margin-top: 1rem;
}
-
-.cbi-tabmenu > li,
-.tabs > li {
+.cbi-tabmenu>li,
+.tabs>li {
margin-right: .4rem;
display: inline-block;
padding: 0.6rem 0rem;
}
-
-.cbi-tabmenu > li > a,
-.tabs > li > a {
+.cbi-tabmenu>li>a,
+.tabs>li>a {
text-decoration: none;
color: #404040;
padding: 0.5rem 0.8rem;
}
-
-.tabs > li[class~="active"],
-.tabs > li:hover {
+.tabs>li[class~="active"],
+.tabs>li:hover {
cursor: pointer;
background-color: #337ab7;
}
-
-.tabs > li[class~="active"] > a,
-.tabs > li:hover > a {
+.tabs>li[class~="active"]>a,
+.tabs>li:hover>a {
color: #fff;
}
-
.cbi-tabmenu {
border-top: 1px solid #D4D4D4;
border-left: 1px solid #D4D4D4;
border-right: 1px solid #D4D4D4;
}
-
-.cbi-tabmenu > li:hover {
+.cbi-tabmenu>li:hover {
background-color: #F1F1F1;
}
-
-.cbi-tabmenu > li[class~="cbi-tab"] {
+.cbi-tabmenu>li[class~="cbi-tab"] {
background-color: #fff;
}
-
.cbi-tabmenu {
background-color: #D4D4D4;
}
-.cbi-section-remove:nth-of-type(2n){
- background-color: #f9f9f9;
+[data-tab-title] {
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
}
+[data-tab-active="true"] {
+ opacity: 1;
+ height: auto;
+ overflow: visible;
+ transition: opacity .25s ease-in;
+}
+
+.cbi-section-remove:nth-of-type(2n) {
+ background-color: #f9f9f9;
+}
.cbi-section-node-tabbed {
padding: 0;
margin-top: 0;
@@ -620,25 +592,20 @@ td > table > tbody > tr > td,
border-left: 1px solid #D4D4D4;
border-right: 1px solid #D4D4D4;
}
-
-.cbi-tabcontainer > .cbi-value:nth-of-type(2n) {
+.cbi-tabcontainer>.cbi-value:nth-of-type(2n) {
background-color: #f9f9f9;
}
-
.cbi-value-field,
.cbi-value-description {
display: table-cell;
line-height: 1.25;
}
-
-.cbi-value-helpicon > img {
+.cbi-value-helpicon>img {
display: none;
}
-
.cbi-value-helpicon:before {
content: "\f059";
}
-
.cbi-value-description {
font-size: small;
opacity: 0.5;
@@ -660,8 +627,8 @@ td > table > tbody > tr > td,
width: 100%;
}
-.cbi-section-table-descr > .cbi-section-table-cell,
-.cbi-section-table-titles > .cbi-section-table-cell {
+.cbi-section-table-descr>.cbi-section-table-cell,
+.cbi-section-table-titles>.cbi-section-table-cell {
border: none;
}
@@ -700,11 +667,6 @@ td > table > tbody > tr > td,
background-color: #eee;
}
-.cbi-rowstyle-2 .cbi-button-up,
-.cbi-rowstyle-2 .cbi-button-down {
- background-color: #FFF !important;
-}
-
.cbi-section-table .cbi-section-table-titles .cbi-section-table-cell {
width: auto !important;
}
@@ -714,22 +676,23 @@ td > table > tbody > tr > td,
vertical-align: middle;
}
-.td.cbi-section-actions > * {
+.td.cbi-section-actions>* {
display: flex;
}
-.td.cbi-section-actions > * > *,
-.td.cbi-section-actions > * > form > * {
+.td.cbi-section-actions>*>*,
+.td.cbi-section-actions>*>form>* {
flex: 1 1 4em;
margin: 0 1px;
}
-.td.cbi-section-actions > * > form {
+.td.cbi-section-actions>*>form {
display: inline-flex;
margin: 0;
}
/* desc */
+
.cbi-section-descr,
.cbi-map-descr {
padding: 0.5rem;
@@ -737,7 +700,6 @@ td > table > tbody > tr > td,
font-size: small;
}
-
.cbi-dropdown {
display: inline-flex;
cursor: pointer;
@@ -750,7 +712,7 @@ td > table > tbody > tr > td,
outline: 2px solid #4b6e9b;
}
-.cbi-dropdown > ul {
+.cbi-dropdown>ul {
margin: 0 !important;
padding: 0;
list-style: none;
@@ -760,18 +722,18 @@ td > table > tbody > tr > td,
width: 100%;
}
-.cbi-dropdown > ul.preview {
+.cbi-dropdown>ul.preview {
display: none;
}
-.cbi-dropdown > .open {
+.cbi-dropdown>.open {
border: 2px outset #eee;
flex-basis: 15px;
background: #eee;
}
-.cbi-dropdown > .open,
-.cbi-dropdown > .more {
+.cbi-dropdown>.open,
+.cbi-dropdown>.more {
flex-grow: 0;
flex-shrink: 0;
display: flex;
@@ -782,15 +744,15 @@ td > table > tbody > tr > td,
padding: 0 .25em;
}
-.cbi-dropdown > .more,
-.cbi-dropdown > ul > li[placeholder] {
+.cbi-dropdown>.more,
+.cbi-dropdown>ul>li[placeholder] {
color: #777;
font-weight: bold;
text-shadow: 1px 1px 0px #fff;
display: none;
}
-.cbi-dropdown > ul > li {
+.cbi-dropdown>ul>li {
display: none;
padding: .25em;
white-space: nowrap;
@@ -803,35 +765,40 @@ td > table > tbody > tr > td,
min-height: 20px;
}
-.cbi-dropdown > ul > li .hide-open { display: initial; }
-.cbi-dropdown > ul > li .hide-close { display: none; }
+.cbi-dropdown>ul>li .hide-open {
+ display: initial;
+}
-.cbi-dropdown > ul > li[display]:not([display="0"]) {
+.cbi-dropdown>ul>li .hide-close {
+ display: none;
+}
+
+.cbi-dropdown>ul>li[display]:not([display="0"]) {
border-left: 1px solid #ccc;
}
-.cbi-dropdown[empty] > ul {
+.cbi-dropdown[empty]>ul {
max-width: 1px;
}
-.cbi-dropdown > ul > li > form {
+.cbi-dropdown>ul>li>form {
display: none;
margin: 0;
padding: 0;
pointer-events: none;
}
-.cbi-dropdown > ul > li img {
+.cbi-dropdown>ul>li img {
vertical-align: middle;
margin-right: .25em;
}
-.cbi-dropdown > ul > li > form > input[type="checkbox"] {
+.cbi-dropdown>ul>li>form>input[type="checkbox"] {
margin: 0;
height: auto;
}
-.cbi-dropdown > ul > li input[type="text"] {
+.cbi-dropdown>ul>li input[type="text"] {
height: 20px;
}
@@ -839,7 +806,7 @@ td > table > tbody > tr > td,
position: relative;
}
-.cbi-dropdown[open] > ul.dropdown {
+.cbi-dropdown[open]>ul.dropdown {
display: block;
background: #f6f6f5;
border: 1px solid #918e8c;
@@ -850,40 +817,45 @@ td > table > tbody > tr > td,
width: auto;
}
-.cbi-dropdown > ul > li[display],
-.cbi-dropdown[open] > ul.preview,
-.cbi-dropdown[open] > ul.dropdown > li,
-.cbi-dropdown[multiple] > ul > li > label,
-.cbi-dropdown[multiple][open] > ul.dropdown > li,
-.cbi-dropdown[multiple][more] > .more,
-.cbi-dropdown[multiple][empty] > .more {
+.cbi-dropdown>ul>li[display],
+.cbi-dropdown[open]>ul.preview,
+.cbi-dropdown[open]>ul.dropdown>li,
+.cbi-dropdown[multiple]>ul>li>label,
+.cbi-dropdown[multiple][open]>ul.dropdown>li,
+.cbi-dropdown[multiple][more]>.more,
+.cbi-dropdown[multiple][empty]>.more {
flex-grow: 1;
display: flex;
align-items: center;
}
-.cbi-dropdown[empty] > ul > li,
-.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder],
-.cbi-dropdown[multiple][open] > ul.dropdown > li > form {
+.cbi-dropdown[empty]>ul>li,
+.cbi-dropdown[optional][open]>ul.dropdown>li[placeholder],
+.cbi-dropdown[multiple][open]>ul.dropdown>li>form {
display: block;
}
-.cbi-dropdown[open] > ul.dropdown > li .hide-open { display: none; }
-.cbi-dropdown[open] > ul.dropdown > li .hide-close { display: initial; }
+.cbi-dropdown[open]>ul.dropdown>li .hide-open {
+ display: none;
+}
+
+.cbi-dropdown[open]>ul.dropdown>li .hide-close {
+ display: initial;
+}
-.cbi-dropdown[open] > ul.dropdown > li {
+.cbi-dropdown[open]>ul.dropdown>li {
border-bottom: 1px solid #ccc;
}
-.cbi-dropdown[open] > ul.dropdown > li[selected] {
+.cbi-dropdown[open]>ul.dropdown>li[selected] {
background: #b0d0f0;
}
-.cbi-dropdown[open] > ul.dropdown > li.focus {
+.cbi-dropdown[open]>ul.dropdown>li.focus {
background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%);
}
-.cbi-dropdown[open] > ul.dropdown > li:last-child {
+.cbi-dropdown[open]>ul.dropdown>li:last-child {
margin-bottom: 0;
border-bottom: none;
}
@@ -903,22 +875,24 @@ td > table > tbody > tr > td,
width: auto;
}
-
/* luci */
.hidden {
display: none
}
-.left, .left::before {
+.left,
+.left::before {
text-align: left !important;
}
-.right, .right::before {
+.right,
+.right::before {
text-align: right !important;
}
-.center, .center::before {
+.center,
+.center::before {
text-align: center !important;
}
@@ -943,6 +917,7 @@ td > table > tbody > tr > td,
}
/* select */
+
.cbi-value-field .cbi-dropdown {
min-width: 15rem;
}
@@ -951,8 +926,10 @@ td > table > tbody > tr > td,
width: 15rem;
}
-.th[data-type="button"], .td[data-type="button"],
-.th[data-type="fvalue"], .td[data-type="fvalue"] {
+.th[data-type="button"],
+.td[data-type="button"],
+.th[data-type="fvalue"],
+.td[data-type="fvalue"] {
flex: 1 1 2em;
text-align: center;
}
@@ -965,20 +942,20 @@ td > table > tbody > tr > td,
border-radius: 20px;
}
-td > .ifacebadge,
-.td > .ifacebadge {
+td>.ifacebadge,
+.td>.ifacebadge {
background-color: #F0F0F0;
font-size: 0.9rem;
}
-.ifacebadge > em,
-.ifacebadge > img {
+.ifacebadge>em,
+.ifacebadge>img {
display: inline-block;
margin: 0 .2rem;
align-self: flex-start;
}
-.ifacebadge > img + img {
+.ifacebadge>img+img {
margin: 0 .2rem 0 0;
}
@@ -998,11 +975,11 @@ td > .ifacebadge,
height: 100%;
}
-.network-status-table .ifacebox-body > span {
+.network-status-table .ifacebox-body>span {
flex: 10 10 auto;
}
-.network-status-table .ifacebox-body > div {
+.network-status-table .ifacebox-body>div {
display: flex;
flex-wrap: wrap;
}
@@ -1094,9 +1071,9 @@ td > .ifacebadge,
float: left;
}
-.uci-change-legend-label > ins,
-.uci-change-legend-label > del,
-.uci-change-legend-label > var {
+.uci-change-legend-label>ins,
+.uci-change-legend-label>del,
+.uci-change-legend-label>var {
float: left;
margin-right: 4px;
width: 10px;
@@ -1117,6 +1094,7 @@ td > .ifacebadge,
}
/* other fix */
+
#iwsvg,
#iwsvg2,
#bwsvg {
@@ -1124,7 +1102,9 @@ td > .ifacebadge,
overflow: hidden;
border-radius: 20px;
}
-#iwsvg, #bwsvg {
+
+#iwsvg,
+#bwsvg {
margin-top: 1rem;
}
@@ -1167,14 +1147,14 @@ td > .ifacebadge,
border: none;
}
-.zonebadge > input[type="text"] {
+.zonebadge>input[type="text"] {
padding: 0.16rem 1rem;
min-width: 10rem;
margin-top: 0.3rem;
}
-.zonebadge > em,
-.zonebadge > strong {
+.zonebadge>em,
+.zonebadge>strong {
margin: 0 0.2rem;
display: inline-block;
}
@@ -1190,25 +1170,25 @@ td > .ifacebadge,
margin-top: 0;
}
-.cbi-value-field > input + .cbi-value-description {
+.cbi-value-field>input+.cbi-value-description {
padding: 0;
}
-.cbi-value-field > ul > li {
+.cbi-value-field>ul>li {
display: flex;
}
-.cbi-value-field > ul > li > label {
+.cbi-value-field>ul>li>label {
margin-top: 0.5rem;
}
-.cbi-value-field > ul > li .ifacebadge {
+.cbi-value-field>ul>li .ifacebadge {
background-color: #eee;
margin-left: 0.4rem;
margin-top: -0.5rem;
}
-.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
+.cbi-section-table-row>.cbi-value-field .cbi-dropdown {
min-width: 7rem;
}
@@ -1218,7 +1198,7 @@ td > .ifacebadge,
align-items: center;
}
-.cbi-section-create > * {
+.cbi-section-create>* {
margin: 0.5rem;
}
@@ -1226,7 +1206,9 @@ td > .ifacebadge,
padding: 0.5rem;
}
-div.cbi-value var, td.cbi-value-field var, .td.cbi-value-field var {
+div.cbi-value var,
+td.cbi-value-field var,
+.td.cbi-value-field var {
font-style: italic;
color: #0069D6;
}
@@ -1281,7 +1263,7 @@ small {
}
.zonebadge-empty {
- background: repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px);
+ background: repeating-linear-gradient(45deg, rgba(204, 204, 204, 0.5), rgba(204, 204, 204, 0.5) 5px, rgba(255, 255, 255, 0.5) 5px, rgba(255, 255, 255, 0.5) 10px);
color: #404040;
}
@@ -1290,11 +1272,11 @@ small {
min-width: 10rem;
}
-.zone-forwards > * {
+.zone-forwards>* {
flex: 1 1 45%;
}
-.zone-forwards > span {
+.zone-forwards>span {
flex-basis: 10%;
text-align: center;
padding: 0 .25rem;
@@ -1306,7 +1288,7 @@ small {
flex-direction: column;
}
-#diag-rc-output > pre {
+#diag-rc-output>pre {
background-color: #f5f5f5;
display: block;
padding: 8.5px;
@@ -1325,13 +1307,13 @@ input[name="nslookup"] {
width: 80%;
}
-header > .container > .pull-right > * {
+header>.container>.pull-right>* {
position: relative;
top: 0.45rem;
cursor: pointer;
}
-#xhr_poll_status > .label.success {
+#xhr_poll_status>.label.success {
background-color: #F24C7C;
}
@@ -1340,7 +1322,6 @@ header > .container > .pull-right > * {
font-size: 0.8rem;
font-weight: bold;
color: #ffffff !important;
- text-transform: uppercase;
white-space: nowrap;
background-color: #bfbfbf;
-webkit-border-radius: 3px;
@@ -1372,15 +1353,16 @@ header > .container > .pull-right > * {
}
/* fix status processes */
-.node-status-processes > .main .table .tr .td:nth-child(3) {
+
+.node-status-processes>.main .table .tr .td:nth-child(3) {
white-space: normal;
}
-.node-status-iptables > .main div > .cbi-map > form {
+.node-status-iptables>.main div>.cbi-map>form {
margin: 2rem 2rem 0 0;
}
-.node-status-iptables > .main div > .cbi-map > form input {
+.node-status-iptables>.main div>.cbi-map>form input {
padding: .8em;
border-radius: 20px;
}
@@ -1388,81 +1370,97 @@ header > .container > .pull-right > * {
.node-status-processes .cbi-section {
overflow-x: scroll;
}
+.node-status-iptables #iptables .table-titles,
+.node-system-opkg #packages .cbi-section-table-titles {
+ background-color: #eee;
+}
/* fix status realtime traffic and wireless */
+
.node-status-realtime.lang_enTraffic .cbi-tabmenu,
.node-status-realtime.lang_enWireless .cbi-tabmenu {
background-color: #d4d4d4;
}
-.node-status-realtime.lang_enTraffic .cbi-tabmenu > li[class~="cbi-tab"],
-.node-status-realtime.lang_enTraffic .cbi-tabmenu > li:hover,
-.node-status-realtime.lang_enWireless .cbi-tabmenu > li[class~="cbi-tab"],
-.node-status-realtime.lang_enWireless .cbi-tabmenu > li:hover {
+
+.node-status-realtime.lang_enTraffic .cbi-tabmenu>li[class~="cbi-tab"],
+.node-status-realtime.lang_enTraffic .cbi-tabmenu>li:hover,
+.node-status-realtime.lang_enWireless .cbi-tabmenu>li[class~="cbi-tab"],
+.node-status-realtime.lang_enWireless .cbi-tabmenu>li:hover {
background-color: #F1F1F1;
}
-.node-status-realtime.lang_enTraffic #bwsvg,
-.node-status-realtime.lang_enWireless #iwsvg,
-.node-system-packages .cbi-map > .cbi-section,
-.node-system-packages form .cbi-section{
+
+.node-status-realtime.lang_enTraffic #bwsvg,
+.node-status-realtime.lang_enWireless #iwsvg,
+.node-system-packages .cbi-map>.cbi-section,
+.node-system-packages form .cbi-section {
border-top-right-radius: 0;
border-top-left-radius: 0;
}
/* fix system system */
+
.node-system-system .cbi-tabmenu {
background-color: #d4d4d4;
}
-.node-system-system .cbi-tabmenu > li[class~="cbi-tab"]{
+
+.node-system-system .cbi-tabmenu>li[class~="cbi-tab"] {
background-color: #fff;
}
/* fix system reboot */
-.node-system-reboot > .main > .main-right p,
-.node-system-reboot > .main > .main-right h3 {
+.node-system-reboot>.main>.main-right p,
+.node-system-reboot>.main>.main-right h3 {
padding-left: 2rem;
}
/* fix Services Network Shares*/
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-title {
+.node-services-samba.lang_enNetwork #cbi-samba-sambashare .table-container {
+ overflow-x: scroll;
+}
+.node-services-samba>.main .cbi-tabcontainer:nth-child(3) .cbi-value-title {
margin-bottom: 1rem;
width: auto;
}
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-field {
+.node-services-samba>.main .cbi-tabcontainer:nth-child(3) .cbi-value-field {
display: list-item;
}
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-description {
+.node-services-samba>.main .cbi-tabcontainer:nth-child(3) .cbi-value-description {
padding-top: 1rem;
}
/* fix System Software*/
+
.node-system-packages #swfreespace {
background-color: #468ea4 !important;
border: none !important;
border-radius: 20px
}
-.node-system-packages #swfreespace > div {
+
+.node-system-packages #swfreespace>div {
background-color: #f24c7c !important;
border: none !important;
border-radius: 20px
}
-.node-system-packages > .main table tr td:nth-child(1) {
+
+.node-system-packages>.main table tr td:nth-child(1) {
width: auto !important;
}
-.node-system-packages > .main table tr td:nth-last-child(1) {
+.node-system-packages>.main table tr td:nth-last-child(1) {
white-space: normal;
font-size: small;
color: #404040;
}
-.node-system-packages > .main .cbi-tabmenu > li > a, .tabs > li > a {
+.node-system-packages>.main .cbi-tabmenu>li>a,
+.tabs>li>a {
padding: 0.5rem 0.8rem;
}
-.node-system-packages > .main .cbi-value > pre {
+.node-system-packages>.main .cbi-value>pre {
background-color: #eee;
padding: 0.5rem;
overflow: auto;
@@ -1476,7 +1474,7 @@ header > .container > .pull-right > * {
margin: 0;
}
-.cbi-tabmenu + .cbi-section {
+.cbi-tabmenu+.cbi-section {
margin-top: 0;
}
@@ -1485,7 +1483,7 @@ header > .container > .pull-right > * {
border: none;
}
-.node-system-flashops form.inline + form.inline {
+.node-system-flashops form.inline+form.inline {
margin-left: 0;
}
@@ -1517,22 +1515,28 @@ header > .container > .pull-right > * {
}
/* fix Network Network*/
+
.node-network-network .cbi-rowstyle-2 .ifacebox-body {
background-color: #fff;
}
-.lang_zh-cnInterfaces .container .cbi-map .cbi-tabmenu + div {
+
+.lang_zh-cnInterfaces .container .cbi-map .cbi-tabmenu+div {
overflow: inherit;
}
+
/* fix Network Wireless*/
+
.node-network-wireless .cbi-section-node {
margin-bottom: 1rem;
}
/* applyreboot fix */
+
#maincontainer {
text-align: center;
}
-#maincontainer > #maincontent {
+
+#maincontainer>#maincontent {
padding: 1rem;
margin: 0 auto;
border-radius: 10px;
@@ -1540,29 +1544,34 @@ header > .container > .pull-right > * {
max-width: 800px;
width: 40%;
}
+
#applyreboot-container {
margin-bottom: 1rem;
}
+
#applyreboot-section {
text-align: left;
background: #fff;
padding: 1rem;
border-radius: 10px;
}
-#applyreboot-section > div {
+
+#applyreboot-section>div {
margin: 1rem 0;
line-height: 1.5rem;
}
+
#applyreboot-container {
- margin: 90px 2rem 2rem 2rem;
+ margin: 90px 2rem 2rem 2rem;
}
#applyreboot-section {
- margin: 2rem;
- line-height: 300%;
+ margin: 2rem;
+ line-height: 300%;
}
/* Shared style */
+
header {
height: 0;
position: fixed;
@@ -1572,16 +1581,19 @@ header {
z-index: 100;
overflow: hidden;
}
+
header {
padding-right: 1rem;
background: #fff;
color: white;
border-bottom: 1px solid #dadada;
}
+
header .fill,
header .container {
height: 100%;
}
+
header .brand {
padding-left: .8rem;
color: #354057;
@@ -1593,23 +1605,29 @@ header .brand {
width: 10%;
text-align: center;
}
+
header .btn-con {
line-height: 70px;
}
+
header .logout {
background-color: #354057;
}
+
header .logout a {
text-decoration: none;
color: #fff;
}
+
.main {
height: auto;
min-height: 100%;
}
+
.main-right {
height: auto;
}
+
.main-left {
top: 10px;
bottom: 10px;
@@ -1621,7 +1639,8 @@ header .logout a {
border-radius: 20px;
min-width: 170px;
}
-.main > .main-left .navbar-container {
+
+.main>.main-left .navbar-container {
margin-top: 0.5rem;
float: right;
width: calc(100% + 10px);
@@ -1629,28 +1648,34 @@ header .logout a {
overflow-y: scroll;
overflow-x: hidden;
}
-.main > .main-left .nav {
+
+.main>.main-left .nav {
height: auto;
}
-.main > .main-left .nav > li a {
+
+.main>.main-left .nav>li a {
color: #fff;
display: block;
}
-.main > .main-left .nav > li {
+
+.main>.main-left .nav>li {
padding: 0.5rem 1.7rem;
cursor: pointer;
}
-.main > .main-left .nav > .slide {
+
+.main>.main-left .nav>.slide {
padding: 0 15px 0 0;
margin-bottom: 8px;
overflow: hidden;
}
-.main > .main-left .nav > .slide > ul {
+
+.main>.main-left .nav>.slide>ul {
display: none;
float: right;
width: calc(100% - 10px);
}
-.main > .main-left .nav > .slide > .menu {
+
+.main>.main-left .nav>.slide>.menu {
display: block;
padding: 0.5rem 1.7rem;
text-decoration: none;
@@ -1659,66 +1684,81 @@ header .logout a {
width: 100%;
float: right;
}
-.main > .main-left .nav > li > a.active,
-.main > .main-left .nav > .slide > .menu:hover,
-.main > .main-left .nav > .slide > .menu.active {
+
+.main>.main-left .nav>li>a.active,
+.main>.main-left .nav>.slide>.menu:hover,
+.main>.main-left .nav>.slide>.menu.active {
background: #485267;
float: right;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
}
-.main > .main-left .nav > .slide:hover {
+
+.main>.main-left .nav>.slide:hover {
background: none;
}
-.main > .main-left .nav > .slide > .slide-menu > li {
+
+.main>.main-left .nav>.slide>.slide-menu>li {
padding: 0.6rem 2rem;
margin: 8px 0;
}
-.main > .main-left .nav > .slide > .slide-menu > .active {
+
+.main>.main-left .nav>.slide>.slide-menu>.active {
background-color: #F24C7C;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
}
-.main > .main-left .nav > .slide > .slide-menu > li > a {
+
+.main>.main-left .nav>.slide>.slide-menu>li>a {
text-decoration: none;
white-space: nowrap;
}
-.main > .main-left .nav > .slide > .slide-menu > .active > a {
+
+.main>.main-left .nav>.slide>.slide-menu>.active>a {
color: white;
}
-.main > .main-left .nav > .slide > .slide-menu > li:hover {
+
+.main>.main-left .nav>.slide>.slide-menu>li:hover {
background: #F24C7C;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
}
-.main > .main-left .nav > .slide > .slide-menu > .active:hover {
+
+.main>.main-left .nav>.slide>.slide-menu>.active:hover {
background-color: #F24C7C;
cursor: hand;
}
/* The scroll bar of the navigation bar is compatible with each browser. */
+
/* Google */
-.main > .main-left .navbar-container::-webkit-scrollbar {
+
+.main>.main-left .navbar-container::-webkit-scrollbar {
width: 6px;
background: transparent;
}
-.main > .main-left .navbar-container::-webkit-scrollbar-button {
+
+.main>.main-left .navbar-container::-webkit-scrollbar-button {
display: none;
}
-.main > .main-left .navbar-container::-webkit-scrollbar-thumb {
+
+.main>.main-left .navbar-container::-webkit-scrollbar-thumb {
background-color: #ffffff61;
border-radius: 10px;
}
-.main > .main-left .navbar-container::-webkit-scrollbar-thumb {
+
+.main>.main-left .navbar-container::-webkit-scrollbar-thumb {
background-color: #839dd67a;
border-radius: 10px;
}
-.main > .main-left .navbar-container:hover::-webkit-scrollbar-thumb {
+
+.main>.main-left .navbar-container:hover::-webkit-scrollbar-thumb {
background-color: #839dd67a;
}
/* IE */
-.main > .main-left .navbar-container {
+
+.main>.main-left .navbar-container {
scrollbar-track-color: transparent;
scrollbar-face-color: #839dd67a;
scrollbar-arrow-color: transparent;
@@ -1726,9 +1766,10 @@ header .logout a {
scrollbar-highlight-color: transparent;
scrollbar-shadow-color: transparent;
scrollbar-darkshadow-color: transparent;
- scrollbar-base-color:transparent;
+ scrollbar-base-color: transparent;
}
-.main > .main-left .navbar-container:hover {
+
+.main>.main-left .navbar-container:hover {
scrollbar-face-color: #839dd67a;
}
@@ -1743,9 +1784,8 @@ footer {
right: 0;
}
-
-
/* The style of the prompt message */
+
.alert-message {
padding: 13px 11%;
border-radius: 10px;
@@ -1766,7 +1806,7 @@ footer {
color: red;
}
-.alert-message > h4 {
+.alert-message>h4 {
padding: 7px 0 7px 36px;
margin: 0;
font-weight: normal;
@@ -1775,7 +1815,7 @@ footer {
display: inline-block;
}
-.alert-message > p {
+.alert-message>p {
font-size: 14px;
line-height: 1.5rem;
}
@@ -1791,7 +1831,6 @@ footer {
border-radius: 50px;
}
-
/* All styles of the login interface */
.node-main-login {
height: auto;
@@ -1804,17 +1843,15 @@ footer {
.node-main-login .main {
height: auto;
}
-.node-main-login > .main > .main-left {
+.node-main-login>.main>.main-left {
display: none;
}
-
-.node-main-login > .main > .main-right {
+.node-main-login>.main>.main-right {
width: 100%;
height: auto;
min-height: 100%;
}
-
-.node-main-login > .main #maincontent {
+.node-main-login>.main #maincontent {
position: absolute;
min-width: 492px;
width: 100%;
@@ -1824,31 +1861,27 @@ footer {
height: auto;
text-align: center;
}
-
-.node-main-login > .main .container {
+.node-main-login>.main .container {
padding: 0;
width: 30%;
max-width: 492px;
display: inline-block;
}
-
-.node-main-login > .main .logoImg a {
+.node-main-login>.main .logoImg a {
margin: 0 0 18px 0;
display: block;
font-size: 30px;
color: #fff;
text-decoration: none;
}
-.node-main-login > .main .logoImg img:first-child {
+.node-main-login>.main .logoImg img:first-child {
width: 72px;
}
-
.node-main-login .warning {
background-color: #3E4A62;
color: #fff;
}
-
-.node-main-login > .main form h2 {
+.node-main-login>.main form h2 {
margin: 17px 0;
padding: 0;
font-size: 24px;
@@ -1856,39 +1889,33 @@ footer {
font-weight: normal;
border: 0;
}
-
-.node-main-login > .main form .cbi-map-descr {
+.node-main-login>.main form .cbi-map-descr {
margin: 0 0 12px;
padding: 0;
font-size: 12px;
color: #B1B6BB;
}
-
-.node-main-login > .main form .cbi-section {
+.node-main-login>.main form .cbi-section {
margin: 0;
padding: 0;
background-color: transparent;
box-shadow: none;
}
-
-.node-main-login > .main form .cbi-value {
+.node-main-login>.main form .cbi-value {
display: block;
}
-
-.node-main-login > .main form .cbi-value-title {
+.node-main-login>.main form .cbi-value-title {
margin: 0;
padding: 0;
display: none;
}
-
-.node-main-login > .main form .cbi-value-field {
+.node-main-login>.main form .cbi-value-field {
margin-bottom: 16px;
display: block;
width: 100%;
position: relative;
}
-
-.node-main-login > .main form .cbi-value-field input {
+.node-main-login>.main form .cbi-value-field input {
padding-left: 48px;
width: 100%;
border: 1px solid #556270;
@@ -1897,7 +1924,6 @@ footer {
font-size: 20px;
color: #9c9fa1;
}
-
.node-main-login form .cbi-value-field .iconpwd,
.node-main-login form .cbi-value-field .iconuser,
.node-main-login form .cbi-value-field .iconeye {
@@ -1925,13 +1951,11 @@ footer {
.node-main-login form .cbi-value-field .opeye {
background-image: url(./op-eye.png);
}
-
.node-main-login form .cbi-page-actions {
padding: 0;
border: 0;
text-align: center;
}
-
.node-main-login form .cbi-page-actions input {
margin: 0 0 0 -4px;
padding: 9px 0;
@@ -1941,25 +1965,20 @@ footer {
width: 50%;
font-size: 18px;
}
-
.node-main-login form .cbi-page-actions .cbi-button-apply {
background-color: #F24C7C;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
}
-
.node-main-login form .cbi-page-actions .cbi-button-reset {
background-color: #8a4568;
color: #fff;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
}
-
.node-main-login input.cbi-input-text {
box-shadow: 0 0 0 1000px white inset;
}
-
-
/* Interface after login */
.logged-in {
background-color: #EBF1F6;
@@ -1997,7 +2016,6 @@ footer {
text-align: center;
text-decoration: none;
border-bottom: 2px solid #ffffff42;
-
/* Single line text omitted */
white-space: nowrap;
overflow: hidden;
@@ -2005,13 +2023,11 @@ footer {
-webkit-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
}
-
.logged-in .alert-message {
padding: 20px 2rem;
border: none;
background-color: #fff;
}
-
.logged-in .alert-message a {
padding: 8px 2rem;
width: auto;
@@ -2019,69 +2035,56 @@ footer {
background-color: #468EA4;
color: #fff;
}
-
@media screen and (max-width: 1600px) {
.main-left {
width: calc(0% + 13rem);
}
-
.btn,
.cbi-button {
padding: 0.3rem 0.6rem;
font-size: 0.8rem;
}
-
- header > .container > .pull-right > * {
+ header>.container>.pull-right>* {
top: 0.35rem;
}
-
.label {
padding: 0.2rem 0.6rem;
}
-
.cbi-value-title {
width: 15rem;
padding-right: 0.6rem;
}
-
.cbi-input-textarea {
font-size: small;
}
}
-
@media screen and (max-width: 1280px) {
-
- .node-main-login > .main .container {
+ .node-main-login>.main .container {
width: 50%;
}
-
- .cbi-tabmenu > li > a, .tabs > li > a {
+ .cbi-tabmenu>li>a,
+ .tabs>li>a {
padding: 0.2rem 0.5rem;
}
-
.panel-title {
font-size: 1.1rem;
padding-bottom: 1rem;
}
-
table {
font-size: 0.7rem !important;
width: 100% !important;
}
-
- .main > .main-left .nav > li,
- .main > .main-left .nav > li a,
- .main > .main-left .nav > .slide > .menu {
+ .main>.main-left .nav>li,
+ .main>.main-left .nav>li a,
+ .main>.main-left .nav>.slide>.menu {
font-size: 0.9rem;
}
-
- .main > .main-left .nav > .slide > .slide-menu > li > a {
+ .main>.main-left .nav>.slide>.slide-menu>li>a {
font-size: 0.7rem;
}
}
-
@media screen and (max-width: 992px) {
- header {
+ .logged-in header {
padding: 0 .8rem;
height: 45px;
}
@@ -2105,7 +2108,7 @@ footer {
min-width: 0;
overflow: hidden;
}
- .main > .main-left .nav > .slide > .slide-menu > li {
+ .main>.main-left .nav>.slide>.slide-menu>li {
width: 90%;
}
header .container {
@@ -2114,90 +2117,76 @@ footer {
.main-right {
width: 100%;
}
-
- .node-main-login > .main .container {
+ .node-main-login>.main .container {
width: 60%;
}
-
.showSide {
padding: 0.1rem;
display: inline-block;
vertical-align: middle;
}
-
.cbi-value-title {
width: 9rem;
padding-right: 1rem;
}
-
- #diag-rc-output > pre {
+ #diag-rc-output>pre {
font-size: 1rem;
}
-
.tr {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
-
- .th, .td {
+ .th,
+ .td {
flex: 2 2 25%;
align-self: flex-start;
text-overflow: ellipsis;
word-wrap: break-word;
display: inline-block;
}
-
.td select,
.td input[type="text"] {
word-wrap: normal;
width: 100%;
}
-
- .td [data-dynlist] > input,
+ .td [data-dynlist]>input,
.td input.cbi-input-password {
width: calc(100% - 1.5rem);
}
-
.td[data-type="button"],
.td[data-type="fvalue"] {
flex: 1 1 12.5%;
text-align: left;
}
-
.th.cbi-value-field,
.td.cbi-value-field,
.th.cbi-section-table-cell,
.td.cbi-section-table-cell {
flex-basis: auto;
}
-
.cbi-section-table-row {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
}
-
.td.cbi-value-field,
.cbi-section-table-cell {
text-align: center;
display: inline-block;
flex: 10 10 auto;
}
-
.td.cbi-section-actions {
text-align: right;
align-self: flex-end;
vertical-align: bottom;
}
-
.tr.table-titles,
.tr.cbi-section-table-titles,
.tr.cbi-section-table-descr {
display: none;
}
-
.tr[data-title]::before,
.tr.cbi-section-table-titles.named::before {
display: block;
@@ -2206,21 +2195,17 @@ footer {
font-size: .9rem;
border-bottom: 1px solid rgba(0, 0, 0, .26);
}
-
.td[data-title] {
text-align: left;
font-size: 12px;
}
-
.td[data-title]::before {
display: block;
}
-
.hide-sm,
.hide-xs {
display: none;
}
-
/* All styles of the login interface */
.node-main-login .showSide {
display: none !important;
@@ -2247,7 +2232,6 @@ footer {
.logged-in .alert-message {
padding: 8px .8rem;
}
-
.cbi-section {
margin: .8rem 0 0 0;
padding: .8rem;
@@ -2256,16 +2240,18 @@ footer {
font-size: 10px;
line-height: 0;
}
- .cbi-section > h3:first-child, .panel-title {
+ .cbi-section>h3:first-child,
+ .panel-title {
font-size: 1rem;
}
- .network-status-table .ifacebox-body > span {
+ .network-status-table .ifacebox-body>span {
font-size: 12px;
}
- .cbi-section .ifacebox-body .ifacebadge > span {
+ .cbi-section .ifacebox-body .ifacebadge>span {
font-size: 12px;
}
- .table .tr.cbi-rowstyle-1:nth-child(n), .table .tr:nth-child(n) {
+ .table .tr.cbi-rowstyle-1:nth-child(n),
+ .table .tr:nth-child(n) {
font-size: 12px;
}
.node-network-firewall .table .tr.cbi-rowstyle-1:nth-child(n),
@@ -2292,86 +2278,70 @@ footer {
select {
border-bottom: 1px solid rgba(0, 0, 0, .26);
}
-
.node-status-processes .table .tr.cbi-rowstyle-1:nth-child(n),
.node-status-processes .table .tr:nth-child(n) {
border-radius: 20px;
}
}
-
-
@media screen and (max-width: 768px) {
.node-main-login {
background: none;
}
-
- .node-main-login > .main .logoImg a {
+ .node-main-login>.main .logoImg a {
font-size: 30px;
margin: 12px 0 22px 0;
color: #354057;
}
-
- .node-main-login > .main #maincontent {
+ .node-main-login>.main #maincontent {
padding-top: 0;
padding-bottom: 1rem;
min-width: 100%;
top: 0;
transform: translateY(0) translateX(-50%);
}
-
.alert-message {
padding: 8px 15%;
}
-
- .alert-message > h4{
+ .alert-message>h4 {
font-size: 14px;
}
- .alert-message > p,
+ .alert-message>p,
.alert-message a {
font-size: 12px;
}
- .a
- lert-message > h4 {
+ .a lert-message>h4 {
padding: 8px 0 8px 36px;
}
-
.alert-message a {
padding: 8px 0;
margin-top: 8px;
}
-
.node-main-login .warning {
background-color: #F5F5F6;
color: #354057;
}
-
.alert-message a {
color: #f24c7c;
background: #fff;
}
-
- .node-main-login > .main form h2 {
+ .node-main-login>.main form h2 {
font-size: 16px;
margin: 20px 0 16px;
color: #354057;
}
-
- .node-main-login > .main form .cbi-value-field input {
+ .node-main-login>.main form .cbi-value-field input {
padding-left: 34px;
height: 36px;
background-size: 16px;
font-size: 16px;
}
-
- .node-main-login > .main form .cbi-value-field {
+ .node-main-login>.main form .cbi-value-field {
margin-bottom: 20px;
}
-
.node-main-login form .cbi-page-actions input {
padding: 6px 0;
font-size: 16px;
}
-
.node-main-login form .cbi-value-field .iconpwd,
.node-main-login form .cbi-value-field .iconuser,
.node-main-login form .cbi-value-field .iconeye {
@@ -2383,21 +2353,17 @@ footer {
left: auto;
right: 12px;
}
-
.mobile-hide {
display: none;
}
-
.PC-hide {
display: inline-block;
}
}
-
@media screen and (max-width: 480px) {
body {
font-size: 1rem;
}
-
.cbi-value-title {
width: 100%;
min-width: 0rem !important;
@@ -2406,51 +2372,43 @@ footer {
margin-bottom: 0.5rem;
text-align: left;
}
-
- .cbi-value-field, .cbi-value-description {
+ .cbi-value-field,
+ .cbi-value-description {
width: 100%;
}
-
- .cbi-value > .cbi-value-field {
+ .cbi-value>.cbi-value-field {
display: inline-block;
}
-
- .cbi-tabmenu > li, .tabs > li {
+ .cbi-tabmenu>li,
+ .tabs>li {
padding: 0.6rem 0rem;
}
-
- .cbi-tabmenu > li > a, .tabs > li > a {
+ .cbi-tabmenu>li>a,
+ .tabs>li>a {
padding: 0.2rem 0.3rem;
font-size: 0.9rem;
}
-
- .cbi-page-actions > div > input {
+ .cbi-page-actions>div>input {
display: none;
}
-
- .tabs > li > a {
+ .tabs>li>a {
font-size: 0.9rem;
}
-
select,
input {
font-size: 10px;
}
-
.panel-title {
font-size: 1.4rem;
padding-bottom: 1rem;
}
-
- .node-system-packages > .main .cbi-value.cbi-value-last > div {
+ .node-system-packages>.main .cbi-value.cbi-value-last>div {
width: 100% !important;
}
-
- .node-system-packages > .main .cbi-value .cbi-value-field input {
+ .node-system-packages>.main .cbi-value .cbi-value-field input {
width: 100%;
}
-
- .node-status-iptables > .main div > .cbi-map > form {
+ .node-status-iptables>.main div>.cbi-map>form {
position: static !important;
margin: 0 0 2rem 0;
padding: 2rem;
@@ -2464,82 +2422,66 @@ footer {
border-radius: 20px;
-webkit-overflow-scrolling: touch;
}
-
- .node-status-iptables > .main div > .cbi-map > form input[type="submit"] {
+ .node-status-iptables>.main div>.cbi-map>form input[type="submit"] {
width: 100% !important;
margin: 0;
}
-
- .node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] {
+ .node-status-iptables>.main div>.cbi-map>form input[type="submit"]+input[type="submit"] {
margin-top: 1rem;
}
-
- .node-main-login > .main .container {
+ .node-main-login>.main .container {
min-width: 90%;
}
-
- .th, .td {
+ .th,
+ .td {
flex-basis: 50%;
}
-
.td.cbi-value-field {
flex-basis: 100%;
}
-
.td.cbi-value-field[data-type="dvalue"] {
flex-basis: 50%;
}
-
.td.cbi-value-field[data-type="button"],
.td.cbi-value-field[data-type="fvalue"] {
flex-basis: 25%;
text-align: left;
}
-
.tr[data-title]::before,
.tr.cbi-section-table-titles.named::before {
font-size: 1rem;
}
-
.hide-xs {
display: none;
}
-
/* All styles of the login interface */
- .node-main-login > .main .cbi-value {
+ .node-main-login>.main .cbi-value {
padding: 0;
}
-
.alert-message {
padding: 8px 10%;
}
}
-
@media screen and (min-width: 992px) {
.cbi-value-field .cbi-input-select {
width: 20rem;
}
-
.cbi-value-field .cbi-dropdown {
min-width: 20rem;
}
}
-
@media screen and (min-width: 1280px) {
.cbi-value-field .cbi-input-select {
width: 22rem;
}
-
.cbi-value-field .cbi-dropdown {
min-width: 22rem;
}
}
-
@media screen and (min-width: 1600px) {
.cbi-value-field .cbi-input-select {
width: 25rem;
}
-
.cbi-value-field .cbi-dropdown {
min-width: 25rem;
}
diff --git a/themes/luci-theme-rosy/htdocs/luci-static/rosy/js/script.js b/themes/luci-theme-rosy/htdocs/luci-static/rosy/js/script.js
index 8985834eff..76ee383ccb 100755
--- a/themes/luci-theme-rosy/htdocs/luci-static/rosy/js/script.js
+++ b/themes/luci-theme-rosy/htdocs/luci-static/rosy/js/script.js
@@ -270,17 +270,22 @@
if( $(window).width() > 992 ){
$('.logged-in .main-right').outerWidth( $(window).width() - $('.logged-in .main-left').width() - 50 );
}
- var a = window.getComputedStyle($(".cbi-section .table .tr:first-child")[0], ':before').getPropertyValue('content');
- var b = window.getComputedStyle($('.cbi-section .table .tr:last-child')[0], ':before').getPropertyValue('content');
- console.log(typeof a);
-
- if( a != 'none' || b != 'none' ){
- $('.cbi-section .table .tr:first-child .td:first-child').css('border-top-left-radius', '0');
- $('.cbi-section .table .tr:last-child .td:first-child').css('border-bottom-left-radius', '0');
- $('.cbi-section .table .tr:first-child .th:first-child').css('border-top-left-radius', '0');
- console.log($('.cbi-section .table .tr:last-child .td:first-child'));
-
- }
+
+ $('.cbi-section .table').each(function(){
+ var thisTr = $(this).children('.tr').get(0);
+ var td = $(thisTr).children('.td').get(0);
+ var th = $(thisTr).children('.th').get(0)
+ var a = window.getComputedStyle(thisTr, ':before').getPropertyValue('content');
+ console.log(td, th);
+
+ if( th && a != 'none' ){
+ $(th).css('border-top-left-radius', '0');
+ }else if( td && a != 'none' ){
+ $(td).css('border-top-left-radius', '0');
+ }
+ });
});
+ $('.lang_enNetwork #cbi-samba-sambashare .table').wrap('<div class="table-container"></div>');
+
})(jQuery);