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 .attr('tabindex', '0') 81 .text(text) 82 .wrapInner('<span class="lbl">') 83 .prepend($icon) 84 ; 85 86 // wrap all following siblings til the next element in a wrapper 87 const $wrap = jQuery('<div>') 88 .addClass('nav-panel'); 89 const $sibs = $me.nextAll(); 90 for (let i = 0; i < $sibs.length; i++) { 91 const $sib = jQuery($sibs[i]); 92 if ($sib.is(ELEMENT)) break; 93 $sib.detach().appendTo($wrap); 94 } 95 $wrap.insertAfter($me); 96 97 // replace element with toggler 98 $me.replaceWith($toggler); 99 }); 100 }; 101 102 /** 103 * Initialize the open/close toggling of menu entries 104 */ 105 const initMenuHandling = function () { 106 $nav.on('click keypress', 'h6', function () { 107 toggleNav(jQuery(this)); 108 }); 109 }; 110 111 /** 112 * Make sure the content area is always as high as the sidebar 113 */ 114 const initContentMinHeight = function () { 115 const $sidebar = jQuery('.page-wrapper').find('> .tools').find('.col-xs-12'); 116 if ($sidebar.length == 1) { 117 const num = parseFloat($sidebar.height()); 118 if (!isNaN(num)) { 119 jQuery('#dokuwiki__content').css('minHeight', num + 100); 120 } 121 } 122 }; 123 124 /** 125 * Initialize the sidebar handle behaviour 126 */ 127 const initSidebarToggling = function () { 128 const $toggler = jQuery('.togglelink.page_main-content').find('a'); 129 $toggler.click(function (e) { 130 e.preventDefault(); 131 if (jQuery('body').hasClass('wide-content')) { 132 setDefaultContent(); 133 } else { 134 setWideContent(); 135 } 136 }); 137 }; 138 139 /** 140 * Show sidebar when accessing the search 141 */ 142 const initSearchToggling = function () { 143 jQuery('.toggleSearch').find('a').click(function (e) { 144 setDefaultContent(); 145 e.preventDefault(); 146 jQuery('#qsearch__in').focus(); 147 }); 148 149 }; 150 151 // main 152 initContentNav(); 153 initSidebarToggling(); 154 initMenuHandling(); 155 initContentMinHeight(); 156 initSearchToggling(); 157}); 158 159