1/** 2 * Sets up the sidebar behaviour 3 */ 4jQuery(function () { 5 const $nav = jQuery('#dokuwiki__aside'); 6 if (!$nav.length) return; 7 8 /** 9 * closes sidebar 10 */ 11 const setWideContent = function () { 12 $nav.find('div.nav-panel').hide(); // close all panels 13 jQuery('body').addClass('wide-content'); 14 }; 15 16 /** 17 * opens the sidebar 18 */ 19 const setDefaultContent = function () { 20 jQuery('body').removeClass('wide-content'); 21 22 }; 23 24 /** 25 * Accessibility helper, focuses the first link witih the given element 26 * 27 * @param {jQuery} $elem 28 */ 29 const focusFirstSubLink = function ($elem) { 30 $elem.find('a').first().focus(); 31 }; 32 33 /** 34 * Toggle a navigation panel 35 * 36 * @param {jQuery} $toggler The h6 toggler 37 */ 38 const toggleNav = function ($toggler) { 39 const $panel = $toggler.next('div.nav-panel'); 40 const isOpen = $panel.is(':visible'); 41 // open sidebar on interaction 42 setDefaultContent(); 43 // toggle the panel, focus first link after opening 44 $panel.dw_toggle(!isOpen, function () { 45 if (!isOpen) { 46 focusFirstSubLink($panel); 47 } 48 }); 49 }; 50 51 /** 52 * Initialize the content navigation 53 * 54 * It mangles the sidebar content and handles inline Icon configuration 55 */ 56 const initContentNav = function () { 57 const $main = $nav.find('nav.nav-main'); 58 if (!$main.length) return; 59 60 const ELEMENT = 'h1,h2,h3,h4,h5'; // FIXME move to config 61 const $elements = $main.find(ELEMENT); 62 $elements.each(function () { 63 const $me = jQuery(this); 64 65 // prepare text and the optional icon 66 const data = $me.text().split('@', 2); 67 const text = data[0].trim(); 68 const $icon = jQuery('<span class="ico">') 69 .text(text.substr(0, 1).toUpperCase() + text.substr(1, 1).toLowerCase()) 70 .wrapInner('<strong>'); 71 if (data[1]) { 72 const src = data[1].trim(); 73 $icon.load(DOKU_BASE + 'lib/tpl/sprintdoc/svg.php?svg=' + src + '&e=1'); // directly embed 74 } 75 76 // make the new toggler 77 const $toggler = jQuery('<h6>') 78 .attr('role', 'heading') 79 .attr('aria-level', '2') 80 .text(text) 81 .wrapInner('<span class="lbl">') 82 .prepend($icon) 83 ; 84 85 // wrap all following siblings til the next element in a wrapper 86 const $wrap = jQuery('<div>') 87 .addClass('nav-panel'); 88 const $sibs = $me.nextAll(); 89 for (let i = 0; i < $sibs.length; i++) { 90 const $sib = jQuery($sibs[i]); 91 if ($sib.is(ELEMENT)) break; 92 $sib.detach().appendTo($wrap); 93 } 94 $wrap.insertAfter($me); 95 96 // replace element with toggler 97 $me.replaceWith($toggler); 98 }); 99 }; 100 101 /** 102 * Initialize the open/close toggling of menu entries 103 */ 104 const initMenuHandling = function () { 105 $nav.on('click', 'h6', function () { 106 toggleNav(jQuery(this)); 107 }); 108 }; 109 110 /** 111 * Make sure the content area is always as high as the sidebar 112 */ 113 const initContentMinHeight = function () { 114 const $sidebar = jQuery('.page-wrapper').find('> .tools').find('.col-xs-12'); 115 if ($sidebar.length == 1) { 116 const num = parseFloat($sidebar.height()); 117 if (!isNaN(num)) { 118 jQuery('#dokuwiki__content').css('minHeight', num + 100); 119 } 120 } 121 }; 122 123 /** 124 * Initialize the sidebar handle behaviour 125 */ 126 const initSidebarToggling = function () { 127 const $toggler = jQuery('.togglelink.page_main-content').find('a'); 128 $toggler.click(function (e) { 129 e.preventDefault(); 130 if (jQuery('body').hasClass('wide-content')) { 131 setDefaultContent(); 132 } else { 133 setWideContent(); 134 } 135 }); 136 }; 137 138 /** 139 * Show sidebar when accessing the search 140 */ 141 const initSearchToggling = function () { 142 jQuery('.toggleSearch').find('a').click(function (e) { 143 setDefaultContent(); 144 e.preventDefault(); 145 jQuery('#qsearch__in').focus(); 146 }); 147 148 }; 149 150 // main 151 initContentNav(); 152 initSidebarToggling(); 153 initMenuHandling(); 154 initContentMinHeight(); 155 initSearchToggling(); 156}); 157 158