xref: /template/sprintdoc/js/sidebar.js (revision 0503402fda960f02a8581495d5f0cd36e47fd6b8)
1/**
2 * Sets up the sidebar behaviour
3 */
4jQuery(function () {
5    var $nav = jQuery('#dokuwiki__aside');
6    if (!$nav.length) return;
7
8        /**
9         * closes sidebar
10         */
11    var 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        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        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         toggleNav = function ($toggler) {
39            var $panel = $toggler.next('div.nav-panel');
40            var 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        initContentNav = function () {
57            var $main = $nav.find('nav.nav-main');
58            if (!$main.length) return;
59
60            var ELEMENT = 'h1,h2,h3,h4,h5'; // FIXME move to config
61            var $elements = $main.find(ELEMENT);
62            $elements.each(function () {
63                var $me = jQuery(this),
64
65                // prepare text and the optional icon
66                    data = $me.text().split('@', 2),
67                    text = data[0].trim();
68
69                var $icon = jQuery('<span class="ico">')
70                    .text(text.substr(0, 1).toUpperCase() + text.substr(1, 1).toLowerCase())
71                    .wrapInner('<strong>');
72                if (data[1]) {
73                    var src = data[1].trim();
74                    $icon.load(DOKU_BASE + 'lib/tpl/sprintdoc/svg.php?svg=' + src + '&e=1'); // directly embed
75                }
76
77                // make the new toggler
78                var $toggler = jQuery('<a>')
79                        .addClass('nav')
80                        .attr('href', '#')
81                        .attr('role', 'heading')
82                        .attr('aria-level', '2')
83                        .text(text)
84                        .wrapInner('<span class="lbl">')
85                        .prepend($icon)
86                    ;
87
88                // wrap all following siblings til the next element in a wrapper
89                var $wrap = jQuery('<div>')
90                    .addClass('nav-panel');
91                var $sibs = $me.nextAll();
92                for (var i = 0; i < $sibs.length; i++) {
93                    var $sib = jQuery($sibs[i]);
94                    if ($sib.is(ELEMENT)) break;
95                    $sib.detach().appendTo($wrap);
96                }
97                $wrap.insertAfter($me);
98
99                // replace element with toggler
100                $me.replaceWith($toggler);
101            });
102        },
103
104        /**
105         * Initialize the open/close toggling of menu entries
106         */
107        initMenuHandling = function () {
108            $nav.on('click', 'a.nav', function (e) {
109                toggleNav(jQuery(this));
110                e.preventDefault();
111            });
112        },
113
114        /**
115         * Make sure the content area is always as high as the sidebar
116         */
117        initContentMinHeight = function () {
118            var $sidebar = jQuery('.page-wrapper').find('> .tools').find('.col-xs-12');
119            if ($sidebar.length == 1) {
120                var num = parseFloat($sidebar.height());
121                if (!isNaN(num)) {
122                    jQuery('#dokuwiki__content').css('minHeight', num + 100);
123                }
124            }
125        },
126
127        /**
128         * Initialize the sidebar handle behaviour
129         */
130        initSidebarToggling = function () {
131            var $toggler = jQuery('.togglelink.page_main-content').find('a');
132            $toggler.click(function (e) {
133                e.preventDefault();
134                if (jQuery('body').hasClass('wide-content')) {
135                    setDefaultContent();
136                } else {
137                    setWideContent();
138                }
139            });
140        },
141
142        /**
143         * Show sidebar when accessing the search
144         */
145        initSearchToggling = function () {
146            jQuery('.toggleSearch').find('a').click(function (e) {
147                setDefaultContent();
148                e.preventDefault();
149                jQuery('#qsearch__in').focus();
150            });
151
152        },
153
154        /**
155         * Open and close the sidebar in mobile view
156         */
157        initMobileToggling = function () {
158            jQuery('.menu-togglelink').find('a').click(function (e) {
159                e.preventDefault();
160                var $body = jQuery('body');
161                $body.toggleClass('show-mobile-sidebar');
162            });
163        };
164
165    // main
166    initContentNav();
167    initSidebarToggling();
168    initMenuHandling();
169    initContentMinHeight();
170    initSearchToggling();
171    initMobileToggling();
172});
173
174