diff options
author | Jo-Philipp Wich <jo@mein.io> | 2019-12-01 20:11:37 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2019-12-16 18:07:17 +0100 |
commit | 5db4463acec5a672c4e4fcb7c91fb93af8e43387 (patch) | |
tree | 15b37d495e55ce947bd154321b834f1beaea7be5 /themes | |
parent | 97f27e0d54fd1a1534b99421aa0e930fbe274db8 (diff) |
luci-theme-bootstrap: render menu on client side
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'themes')
3 files changed, 126 insertions, 131 deletions
diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm index e0a41e1bc..ec6895f06 100644 --- a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm +++ b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm @@ -5,25 +5,12 @@ Licensed to the public under the Apache License 2.0. -%> -<% - local ver = require "luci.version" - local disp = require "luci.dispatcher" - local request = disp.context.path - local category = request[1] - local tree = disp.node() - local categories = disp.node_childs(tree) -%> +<% local ver = require "luci.version" %> + <footer> <a href="https://github.com/openwrt/luci">Powered by <%= ver.luciname %> (<%= ver.luciversion %>)</a> / <%= ver.distversion %> - <% if #categories > 1 then %> - <ul class="breadcrumb pull-right" id="modemenu"> - <% for i, r in ipairs(categories) do %> - <li<% if request[1] == r then %> class="active"<%end%>><a href="<%=controller%>/<%=r%>/"><%=striptags(translate(tree.nodes[r].title))%></a> <span class="divider">|</span></li> - <% end %> - </ul> - <% end %> + <ul class="breadcrumb pull-right" id="modemenu" style="display:none"></ul> </footer> - </div> </div> </body> </html> diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm index de1fd73f0..56a1b230e 100644 --- a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm +++ b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm @@ -13,123 +13,10 @@ local boardinfo = util.ubus("system", "board") - local request = disp.context.path - local request2 = disp.context.request - - local category = request[1] - local cattree = category and disp.node(category) - - local leaf = request2[#request2] - - local tree = disp.node() local node = disp.context.dispatched - local categories = disp.node_childs(tree) - - local c = tree - local i, r - - -- tag all nodes leading to this page - for i, r in ipairs(request) do - if c.nodes and c.nodes[r] then - c = c.nodes[r] - c._menu_selected = true - end - end - -- send as HTML5 http.prepare_content("text/html") - - local function nodeurl(prefix, name, query) - local u = url(prefix, name) - if query then - u = u .. http.build_querystring(query) - end - return pcdata(u) - end - - local function render_tabmenu(prefix, node, level) - if not level then - level = 1 - end - - local childs = disp.node_childs(node) - if #childs > 0 then - if level > 2 then - write('<ul class="tabs">') - end - - local selected_node - local selected_name - local i, v - - for i, v in ipairs(childs) do - local nnode = node.nodes[v] - if nnode._menu_selected then - selected_node = nnode - selected_name = v - end - - if level > 2 then - write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{ - v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'active' or '', - nodeurl(prefix, v, nnode.query), - striptags(translate(nnode.title)) - }) - end - end - - if level > 2 then - write('</ul>') - end - - if selected_node then - render_tabmenu(prefix .. "/" .. selected_name, selected_node, level + 1) - end - end - end - - local function render_submenu(prefix, node) - local childs = disp.node_childs(node) - if #childs > 0 then - write('<ul class="dropdown-menu">') - - for i, r in ipairs(childs) do - local nnode = node.nodes[r] - write('<li><a href="%s">%s</a></li>' %{ - nodeurl(prefix, r, nnode.query), - striptags(translate(nnode.title)) - }) - end - - write('</ul>') - end - end - - local function render_topmenu() - local childs = disp.node_childs(cattree) - if #childs > 0 then - write('<ul class="nav">') - - for i, r in ipairs(childs) do - local nnode = cattree.nodes[r] - local grandchildren = disp.node_childs(nnode) - - if #grandchildren > 0 then - write('<li class="dropdown"><a class="menu" href="#">%s</a>' % striptags(translate(nnode.title))) - render_submenu(category .. "/" .. r, nnode) - write('</li>') - else - write('<li><a href="%s">%s</a></li>' %{ - nodeurl(category, r, nnode.query), - striptags(translate(nnode.title)) - }) - end - end - - write('</ul>') - end - end -%> <!DOCTYPE html> <html lang="<%=luci.i18n.context.lang%>"> @@ -149,6 +36,8 @@ <script src="<%=url('admin/translations', luci.i18n.context.lang)%><%# ?v=PKG_VERSION %>"></script> <script src="<%=resource%>/cbi.js"></script> <script src="<%=resource%>/xhr.js"></script> + + <% include("themes/bootstrap/json-menu") %> </head> <body class="lang_<%=luci.i18n.context.lang%> <% if node then %><%= striptags( node.title ) %><%- end %>" data-page="<%= table.concat(disp.context.requestpath, "-") %>"> @@ -156,7 +45,7 @@ <div class="fill"> <div class="container"> <a class="brand" href="#"><%=boardinfo.hostname or "?"%></a> - <% render_topmenu() %> + <ul class="nav" id="topmenu" style="display:none"></ul> <div class="pull-right"> <span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()"> <span class="label success" id="xhr_poll_status_on"><%:Auto Refresh%> <%:on%></span> @@ -185,4 +74,4 @@ </div> </noscript> - <% if category then render_tabmenu(category, cattree) end %> + <div id="tabmenu" style="display:none"></div> diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/json-menu.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/json-menu.htm new file mode 100644 index 000000000..b38406f65 --- /dev/null +++ b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/json-menu.htm @@ -0,0 +1,119 @@ +<script type="text/javascript"> + (function() { + function get_children(node) { + var children = []; + + for (var k in node.children) { + if (!node.children.hasOwnProperty(k)) + continue; + + if (!node.children[k].satisfied) + continue; + + if (!node.children[k].hasOwnProperty('title')) + continue; + + children.push(Object.assign(node.children[k], { name: k })); + } + + return children.sort(function(a, b) { + return ((a.order || 1000) - (b.order || 1000)); + }); + } + + function render_tabmenu(tree, url, level) { + var container = document.querySelector('#tabmenu'), + ul = E('ul', { 'class': 'tabs' }), + children = get_children(tree), + activeNode = null; + + for (var i = 0; i < children.length; i++) { + var isActive = (L.env.dispatchpath[3 + (level || 0)] == children[i].name), + activeClass = isActive ? ' active' : '', + 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]; + } + + if (ul.children.length == 0) + return E([]); + + container.appendChild(ul); + container.style.display = ''; + + if (activeNode) + render_tabmenu(activeNode, url + '/' + activeNode.name, (level || 0) + 1); + + return ul; + } + + function render_mainmenu(tree, url, level) { + var ul = level ? E('ul', { 'class': 'dropdown-menu' }) : document.querySelector('#topmenu'), + children = get_children(tree); + + if (children.length == 0 || level > 1) + return E([]); + + for (var i = 0; i < children.length; i++) { + var submenu = render_mainmenu(children[i], url + '/' + children[i].name, (level || 0) + 1), + subclass = (!level && submenu.firstElementChild) ? 'dropdown' : null, + linkclass = (!level && submenu.firstElementChild) ? 'menu' : null, + linkurl = submenu.firstElementChild ? '#' : L.url(url, children[i].name); + + var li = E('li', { 'class': subclass }, [ + E('a', { 'class': linkclass, 'href': linkurl }, [ _(children[i].title) ]), + submenu + ]); + + ul.appendChild(li); + } + + ul.style.display = ''; + + return ul; + } + + function render_modemenu(tree) { + var ul = document.querySelector('#modemenu'), + children = get_children(tree); + + for (var i = 0; i < children.length; i++) { + var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0); + + ul.appendChild(E('li', { 'class': isActive ? 'active' : null }, [ + E('a', { 'href': L.url(children[i].name) }, [ _(children[i].title) ]), + ' ', + E('span', { 'class': 'divider' }, [ '|' ]) + ])); + + if (isActive) + render_mainmenu(children[i], children[i].name); + } + + if (ul.children.length > 1) + ul.style.display = ''; + } + + document.addEventListener('luci-loaded', function(ev) { + var tree = <%= luci.http.write_json(luci.dispatcher.context.authsession and luci.dispatcher.menu_json() or {}) %>, + node = tree, + url = ''; + + render_modemenu(tree); + + 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) + render_tabmenu(node, url); + } + }); + })(); +</script> |