From 6c61749bf2a1268695f9fe689d24c6c675880110 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 16 Feb 2017 14:40:25 +0100 Subject: [PATCH] complete refactor of the sidebar behaviour javascript RES-754 Now all toggling of the sidebar and the related menus is done through the same click handler. HTML has been unified. All sidebar related content is now in a single include file instead of several. Icons for the site tools user tools and trace have been added. The CSS for the whole sidebar still has to be refactored. --- css/area_main-sidebar.less | 127 +++++++++++++-------------- img/account-settings.svg | 1 + img/apple-safari.svg | 1 + img/sitemap.svg | 1 + js/sidebar-menu.js | 153 --------------------------------- js/sidebar.js | 171 ++++++++++++++++++++++++++++--------- main.php | 53 +----------- script.js | 3 - tpl/main-sidebar-nav.php | 71 +++++++++++++++ tpl/nav-main.php | 12 --- tpl/nav-sitetools.php | 14 --- tpl/nav-trace.php | 11 --- tpl/nav-usermenu.php | 23 ----- 13 files changed, 273 insertions(+), 368 deletions(-) create mode 100644 img/account-settings.svg create mode 100644 img/apple-safari.svg create mode 100644 img/sitemap.svg delete mode 100755 js/sidebar-menu.js create mode 100644 tpl/main-sidebar-nav.php delete mode 100755 tpl/nav-main.php delete mode 100755 tpl/nav-sitetools.php delete mode 100755 tpl/nav-trace.php delete mode 100755 tpl/nav-usermenu.php diff --git a/css/area_main-sidebar.less b/css/area_main-sidebar.less index 1b65553..107f76a 100755 --- a/css/area_main-sidebar.less +++ b/css/area_main-sidebar.less @@ -4,88 +4,91 @@ * @author Jana Deutschlaender */ -#dokuwiki__aside.main-sidebar { - .nav-main { - @icon-size: @font-size-big; - @menu-margin: @icon-size + @margin-small*2; // FIXME this is still wrong +#dokuwiki__aside { + @icon-size: @font-size-big; + @menu-margin: @icon-size + @margin-small*2; // FIXME this is still wrong - margin-left: @menu-margin; // moves *all* sidebar content to the right + margin-left: @menu-margin; // moves *all* sidebar content to the right - .navi-toggle { - cursor: pointer; + // the toggle element + h6 { + cursor: pointer; + height: @line-height-big; + line-height: @line-height-big; + font-weight: normal; + margin-left: (@menu-margin * -1); // moves the toggles back to the left + + color: @color-nav; + border: 1px solid transparent; + border-radius: @fix_border-radius; + // margin-bottom: -.3rem; FIXME + // padding: .7em 0 .7em (@margin-big + 1); FIXME WTF? + transition: @transition color, @transition background-color, @transition border-color; + + span { + display: inline-block; + width: @menu-margin; height: @line-height-big; - line-height: @line-height-big; - font-weight: normal; - margin-left: (@menu-margin * -1); // moves the toggles back to the left - + border-right: 1px solid @color-border; + text-align: center; + margin-right: @margin-small; color: @color-nav; - border: 1px solid transparent; - border-radius: @fix_border-radius; - // margin-bottom: -.3rem; FIXME - // padding: .7em 0 .7em (@margin-big + 1); FIXME WTF? - transition: @transition color, @transition background-color, @transition border-color; - span { + // simple fake icon + strong { display: inline-block; - width: @menu-margin; - height: @line-height-big; - border-right: 1px solid @color-border; + font-size: @icon-size * 0.5; + width: @icon-size * 0.9; + height: @icon-size * 0.9; + line-height: @icon-size * 0.9; + margin: @icon-size * 0.05; + vertical-align: baseline; text-align: center; - margin-right: @margin-small; color: @color-nav; + border: 2px solid @color-nav; + border-top-right-radius: 50%; + border-bottom-left-radius: 50%; - // simple fake icon - strong { - display: inline-block; - font-size: @icon-size * 0.5; - width: @icon-size * 0.9; - height: @icon-size * 0.9; - line-height: @icon-size * 0.9; - margin: @icon-size * 0.05; - vertical-align: baseline; - text-align: center; - color: @color-nav; - border: 1px solid @color-nav; - border-top-left-radius: 50%; - border-bottom-right-radius: 50%; - - } - - // real icon - svg { - width: @icon-size; - height: @icon-size; - path { - fill: @color-nav; - } - } } - &:hover, - &:focus, - &:active { - background-color: @button_color; - border-color: @button_background; - color: @button_background; - text-decoration: none; - - span strong { - color: @button_background; - border-color: @button_background; - } - - span svg path { - fill: @button_background; + // real icon + svg { + width: @icon-size; + height: @icon-size; + path { + fill: @color-nav; } } } + + &:hover, + &:focus, + &:active { + background-color: @button_color; + border-color: @button_background; + color: @button_background; + text-decoration: none; + + span strong { + color: @button_background; + border-color: @button_background; + } + + span svg path { + fill: @button_background; + } + } + } + + // the panel (hidden by default) + div.nav-panel { + display: none; } } // FIXME check if the stuff below is still relevant - /* + + + + + + + + + + + + + + + + + + + + + + + + + + */ /* min-width: 1440px */ diff --git a/img/account-settings.svg b/img/account-settings.svg new file mode 100644 index 0000000..a7223e9 --- /dev/null +++ b/img/account-settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/apple-safari.svg b/img/apple-safari.svg new file mode 100644 index 0000000..5edc4f4 --- /dev/null +++ b/img/apple-safari.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/sitemap.svg b/img/sitemap.svg new file mode 100644 index 0000000..1afc9f7 --- /dev/null +++ b/img/sitemap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/sidebar-menu.js b/js/sidebar-menu.js deleted file mode 100755 index 471bc47..0000000 --- a/js/sidebar-menu.js +++ /dev/null @@ -1,153 +0,0 @@ -( function( $, spc ) { - - var addToggleLink = function($elem){ - $elem.wrapInner(''); - }, - - setContentMinHeight = function(){ - var $sidebar = $('.page-wrapper').find('> .tools').find('.col-xs-12'); - - if($sidebar.length == 1){ - var h = $sidebar.height(), - num = parseFloat(h); - if(!isNaN(num)){ - $('#dokuwiki__content').css('minHeight',num + 100); - } - - } - - }, - setWideContent = function(){ - var $openTogglers = $('.main-sidebar').find('.opened').find('.toggler'); - $openTogglers.trigger( "click" ); - $('body').addClass('wide-content'); - }, - setDefaultContent= function(){ - $('body').removeClass('wide-content'); - - }, - toggleState = function($toggler){ - $toggler.toggleClass('closed'); - $toggler.toggleClass('opened'); - }, - focusFirstSubLink = function($elem, is2nd){ - - var $foc = (is2nd) ? $elem.find('a')[1] : $elem.find('a')[0]; - - if($foc){ - $foc.focus(); - } - return $foc; - }, - focusLastSubLink = function($elem){ - - var $foc = $elem.find('a:last-child'), - height = $elem.find('p').scrollHeight; - - if($foc){ - $foc.focus(); - } - $elem.scrollTop(height); - return $foc; - }, - - mainMenu = function(){ - var $menu = $('.nav-main').find('> ul'); - - try{ - if($menu.length > 0){ - var $toggler = $menu.find('> li.level1 > .li'), - $submenu = $menu.find('> li.level1 > ul'); - - if($toggler.length > 0 && $submenu.length > 0){ - - $toggler.addClass('closed'); - addToggleLink($toggler); - $toggler.each(function( index ) { - $(this).on( "click", function(e) { - e.preventDefault(); - var $this = $(this); - toggleState($this); - if($this.hasClass('opened')){ - var $foc = focusFirstSubLink($this.closest('li.level1'), true); - } - if($('body').hasClass('wide-content')){ - setDefaultContent(); - } - - }); - }); - - - //FIXME: store current nav state with local storage - } - - - } - - }catch(err){ - - } - }, - toggleMainContent = function(){ - var $toggler = $('.togglelink.page_main-content').find('a'); - $toggler.on("click", function (e) { - e.preventDefault(); - var $link = $(this); - - if($('body').hasClass('wide-content')){ - setDefaultContent(); - }else{ - setWideContent(); - } - - }); - }, - sideMenu = function(){ - var $menus = $('.tools').find('.toggle-menu'); - - - try{ - $menus.each(function( ) { - var $menu = $(this); - if($menu.length > 0){ - var $toggler = $menu.find('h6'), - $submenu = $menu.find('nav > ul, nav > div'); - if($toggler.length > 0 && $submenu.length > 0) { - - $toggler.addClass('closed'); - addToggleLink($toggler); - $toggler.each(function (index) { - $(this).on("click", function (e) { - e.preventDefault(); - var $this = $(this); - toggleState($this); - if ($this.hasClass('opened')) { - var $elem = ($submenu.is('div')) ? focusLastSubLink($submenu): focusFirstSubLink($submenu,false); - } - if($('body').hasClass('wide-content')){ - setDefaultContent(); - } - }); - }); - - //FIXME: store current nav state with local storage - } - } - }); - - - }catch(err){ - //console.log('err'); - } - }; - - $(function(){ - mainMenu(); - sideMenu(); - toggleMainContent(); - setContentMinHeight(); - }); - -} )( jQuery, spc ); - diff --git a/js/sidebar.js b/js/sidebar.js index 52b7521..fd13efb 100644 --- a/js/sidebar.js +++ b/js/sidebar.js @@ -1,54 +1,143 @@ /** - * Initialize the sidebar to have a toggleable menu system with icon support + * Sets up the sidebar behaviour */ jQuery(function () { - const $nav = jQuery('#dokuwiki__aside').find('nav.nav-main'); + const $nav = jQuery('#dokuwiki__aside'); if (!$nav.length) return; - const ELEMENT = 'h1,h2,h3,h4,h5'; // FIXME move to config - const $elements = $nav.find(ELEMENT); - $elements.each(function () { - const $me = jQuery(this); + /** + * closes sidebar + */ + const setWideContent = function () { + $nav.find('div.nav-panel').hide(); // close all panels + jQuery('body').addClass('wide-content'); + }; - // prepare text and the optional icon - const data = $me.text().split('@', 2); - const text = data[0].trim(); - const $icon = jQuery('') - .text(text.substr(0, 1).toUpperCase() + text.substr(1, 1).toLowerCase()) - .wrapInner(''); - if (data[1]) { - const src = data[1].trim(); - $icon.load(DOKU_BASE + 'lib/tpl/sprintdoc/svg.php?svg=' + src + '&e=1'); // directly embed - } + /** + * opens the sidebar + */ + const setDefaultContent = function () { + jQuery('body').removeClass('wide-content'); - // make the new toggler - const $toggler = jQuery('
') - .addClass('navi-toggle') - .text(text) - .prepend($icon) - ; + }; - // wrap all following sibling til the next element in a wrapper - const $wrap = jQuery('
').addClass('navi-pane'); - const $sibs = $me.nextAll(); - for (let i = 0; i < $sibs.length; i++) { - const $sib = jQuery($sibs[i]); - if($sib.is(ELEMENT)) break; - $sib.detach().appendTo($wrap); - } - $wrap.hide(); - $wrap.insertAfter($me); + /** + * Accessibility helper, focuses the first link witih the given element + * + * @param {jQuery} $elem + */ + const focusFirstSubLink = function ($elem) { + $elem.find('a').first().focus(); + }; - // replace element with toggler - $me.replaceWith($toggler); - - // add toggling the wrapper - $toggler.click(function () { - $wrap.dw_toggle(undefined, function () { - $me.toggleClass('open'); - }); + /** + * Toggle a navigation panel + * + * @param {jQuery} $toggler The h6 toggler + */ + const toggleNav = function ($toggler) { + const $panel = $toggler.next('div.nav-panel'); + const isOpen = $panel.is(':visible'); + // open sidebar on interaction + setDefaultContent(); + // toggle the panel, focus first link after opening + $panel.dw_toggle(!isOpen, function () { + if (!isOpen) { + focusFirstSubLink($panel); + } }); + }; - }); + /** + * Initialize the content navigation + * + * It mangles the sidebar content and handles inline Icon configuration + */ + const initContentNav = function () { + const $main = $nav.find('nav.nav-main'); + if (!$main.length) return; + const ELEMENT = 'h1,h2,h3,h4,h5'; // FIXME move to config + const $elements = $main.find(ELEMENT); + $elements.each(function () { + const $me = jQuery(this); + + // prepare text and the optional icon + const data = $me.text().split('@', 2); + const text = data[0].trim(); + const $icon = jQuery('') + .text(text.substr(0, 1).toUpperCase() + text.substr(1, 1).toLowerCase()) + .wrapInner(''); + if (data[1]) { + const src = data[1].trim(); + $icon.load(DOKU_BASE + 'lib/tpl/sprintdoc/svg.php?svg=' + src + '&e=1'); // directly embed + } + + // make the new toggler + const $toggler = jQuery('
') + .attr('role', 'heading') + .attr('aria-level', '2') + .text(text) + .prepend($icon) + ; + + // wrap all following siblings til the next element in a wrapper + const $wrap = jQuery('
') + .addClass('nav-panel'); + const $sibs = $me.nextAll(); + for (let i = 0; i < $sibs.length; i++) { + const $sib = jQuery($sibs[i]); + if ($sib.is(ELEMENT)) break; + $sib.detach().appendTo($wrap); + } + $wrap.insertAfter($me); + + // replace element with toggler + $me.replaceWith($toggler); + }); + }; + + /** + * Initialize the open/close toggling of menu entries + */ + const initMenuHandling = function () { + $nav.on('click', 'h6', function () { + toggleNav(jQuery(this)); + }); + }; + + /** + * Make sure the content area is always as high as the sidebar + */ + const initContentMinHeight = function () { + const $sidebar = jQuery('.page-wrapper').find('> .tools').find('.col-xs-12'); + if ($sidebar.length == 1) { + const num = parseFloat($sidebar.height()); + if (!isNaN(num)) { + jQuery('#dokuwiki__content').css('minHeight', num + 100); + } + } + }; + + /** + * Initialize the sidebar handle behaviour + */ + const initSidebarToggling = function () { + const $toggler = jQuery('.togglelink.page_main-content').find('a'); + $toggler.click(function (e) { + e.preventDefault(); + if (jQuery('body').hasClass('wide-content')) { + setDefaultContent(); + } else { + setWideContent(); + } + }); + }; + + // main + initContentNav(); + initSidebarToggling(); + initMenuHandling(); + initContentMinHeight(); }); + diff --git a/main.php b/main.php index 4527e46..941f24b 100755 --- a/main.php +++ b/main.php @@ -168,59 +168,14 @@ $classWideContent = ($ACT === "show") ? "": "wide-content "; ?>
-
diff --git a/script.js b/script.js index af31b5a..2b8a288 100755 --- a/script.js +++ b/script.js @@ -3,8 +3,5 @@ /* DOKUWIKI:include js/plugins/do_tasks.js */ -/* DOKUWIKI:include js/sidebar-menu.js */ /* DOKUWIKI:include js/meta-box.js */ - - /* DOKUWIKI:include js/sidebar.js */ diff --git a/tpl/main-sidebar-nav.php b/tpl/main-sidebar-nav.php new file mode 100644 index 0000000..81a985c --- /dev/null +++ b/tpl/main-sidebar-nav.php @@ -0,0 +1,71 @@ + + + + + + + + + + + + diff --git a/tpl/nav-main.php b/tpl/nav-main.php deleted file mode 100755 index 4349a58..0000000 --- a/tpl/nav-main.php +++ /dev/null @@ -1,12 +0,0 @@ -"; - echo "
".tpl_getLang('head_menu_main')."
"; - echo PHP_EOL; - tpl_include_page($conf['sidebar'], 1, 1); - echo PHP_EOL; - echo ""; - - endif ?> diff --git a/tpl/nav-sitetools.php b/tpl/nav-sitetools.php deleted file mode 100755 index cb57c7e..0000000 --- a/tpl/nav-sitetools.php +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/tpl/nav-trace.php b/tpl/nav-trace.php deleted file mode 100755 index 52ade4f..0000000 --- a/tpl/nav-trace.php +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/tpl/nav-usermenu.php b/tpl/nav-usermenu.php deleted file mode 100755 index f6fe3fe..0000000 --- a/tpl/nav-usermenu.php +++ /dev/null @@ -1,23 +0,0 @@ - - - - -