From a1aa0af102cb522613d376d843b0d066a1639926 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 15 Apr 2020 22:35:38 +0200 Subject: [PATCH] luci-theme-openwrt-2020: rework menu rendering Utilize the LuCI.ui.menu class to load, traverse and cache the menu tree in the local session store. Signed-off-by: Jo-Philipp Wich --- .../luci-static/resources/menu-openwrt2020.js | 147 +++++++++++++++ .../luasrc/view/themes/openwrt2020/footer.htm | 3 +- .../luasrc/view/themes/openwrt2020/header.htm | 169 +----------------- 3 files changed, 150 insertions(+), 169 deletions(-) create mode 100644 themes/luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js diff --git a/themes/luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js b/themes/luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js new file mode 100644 index 0000000000..b6fbfd4c2f --- /dev/null +++ b/themes/luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js @@ -0,0 +1,147 @@ +'use strict'; +'require baseclass'; +'require ui'; + +return baseclass.extend({ + __init__: function() { + ui.menu.load().then(L.bind(this.render, this)); + }, + + render: function(tree) { + var node = tree, + url = ''; + + this.renderModeMenu(node); + + if (L.env.dispatchpath.length >= 3) { + for (var i = 0; i < 3 && node; i++) { + node = node.children[L.env.dispatchpath[i]]; + url = url + (url ? '/' : '') + L.env.dispatchpath[i]; + } + + if (node) + this.renderTabMenu(node, url); + } + + document.querySelector('#menubar > .navigation') + .addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle')); + }, + + handleMenuExpand: function(ev) { + var a = ev.target, ul1 = a.parentNode.parentNode, ul2 = a.nextElementSibling; + + document.querySelectorAll('ul.mainmenu.l1 > li.active').forEach(function(li) { + if (li !== a.parentNode) + li.classList.remove('active'); + }); + + if (!ul2) + return; + + if (ul2.parentNode.offsetLeft + ul2.offsetWidth <= ul1.offsetLeft + ul1.offsetWidth) + ul2.classList.add('align-left'); + + ul1.classList.add('active'); + a.parentNode.classList.add('active'); + a.blur(); + + ev.preventDefault(); + ev.stopPropagation(); + }, + + renderMainMenu: function(tree, url, level) { + var l = (level || 0) + 1, + ul = E('ul', { 'class': 'mainmenu l%d'.format(l) }), + children = ui.menu.getChildren(tree); + + if (children.length == 0 || l > 2) + return E([]); + + for (var i = 0; i < children.length; i++) { + var isActive = (L.env.dispatchpath[l] == children[i].name), + isReadonly = children[i].readonly, + activeClass = 'mainmenu-item-%s%s'.format(children[i].name, isActive ? ' selected' : ''); + + ul.appendChild(E('li', { 'class': activeClass }, [ + E('a', { + 'href': L.url(url, children[i].name), + 'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null + }, [ _(children[i].title) ]), + this.renderMainMenu(children[i], url + '/' + children[i].name, l) + ])); + } + + if (l == 1) + document.querySelector('#mainmenu').appendChild(E('div', [ ul ])); + + return ul; + }, + + renderModeMenu: function(tree) { + var menu = document.querySelector('#modemenu'), + children = ui.menu.getChildren(tree); + + for (var i = 0; i < children.length; i++) { + var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0); + + if (i > 0) + menu.appendChild(E([], ['\u00a0|\u00a0'])); + + menu.appendChild(E('div', { 'class': isActive ? 'active' : null }, [ + E('a', { 'href': L.url(children[i].name) }, [ _(children[i].title) ]) + ])); + + if (isActive) + this.renderMainMenu(children[i], children[i].name); + } + + if (menu.children.length > 1) + menu.style.display = ''; + }, + + renderTabMenu: function(tree, url, level) { + var container = document.querySelector('#tabmenu'), + l = (level || 0) + 1, + ul = E('ul', { 'class': 'cbi-tabmenu' }), + children = ui.menu.getChildren(tree), + activeNode = null; + + if (children.length == 0) + return E([]); + + for (var i = 0; i < children.length; i++) { + var isActive = (L.env.dispatchpath[l + 2] == children[i].name), + activeClass = isActive ? ' cbi-tab' : '', + className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass); + + ul.appendChild(E('li', { 'class': className }, [ + E('a', { 'href': L.url(url, children[i].name) }, [ _(children[i].title) ] ) + ])); + + if (isActive) + activeNode = children[i]; + } + + container.appendChild(ul); + container.style.display = ''; + + if (activeNode) + container.appendChild(this.renderTabMenu(activeNode, url + '/' + activeNode.name, l)); + + return ul; + }, + + handleSidebarToggle: function(ev) { + var btn = ev.currentTarget, + bar = document.querySelector('#mainmenu'); + + if (btn.classList.contains('active')) { + btn.classList.remove('active'); + bar.classList.remove('active'); + } + else { + btn.classList.add('active'); + bar.classList.add('active'); + } + } +}); diff --git a/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm b/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm index 07be0d65a3..e9122f0b5c 100644 --- a/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm +++ b/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm @@ -3,7 +3,6 @@ Licensed to the public under the Apache License 2.0. -%> -
@@ -12,5 +11,7 @@ Powered by <%= ver.luciname %> (<%= ver.luciversion %>)

+ + diff --git a/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm b/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm index 0ebd6a9a9e..2025b67ed0 100644 --- a/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm +++ b/themes/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm @@ -27,171 +27,6 @@ - <%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI @@ -212,9 +47,7 @@
- +
<%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") and category ~= "failsafe" and path ~= "admin-system-admin-password" then -%> -- 2.30.2