xref: /template/sprintdoc/js/sidebar.js (revision 577d0c1e94d028aa86996f7a2f6a48e31a5b85ed)
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            removeToggleStorage();
15            window.sessionStorage.setItem('wide-content', true);
16        },
17
18        /**
19         * removes information about the toggle-state
20         */
21        removeToggleStorage = function () {
22            for (var index=0; index <= window.sessionStorage.length; index += 1) {
23                var item = window.sessionStorage.getItem('sidebar-section-' + index + '-open');
24                if (!item) {
25                    continue;
26                }
27                window.sessionStorage.removeItem('sidebar-section-' + index + '-open');
28            }
29        },
30
31        /**
32         * opens the sidebar
33         */
34        setDefaultContent = function () {
35            jQuery('body').removeClass('wide-content');
36            window.sessionStorage.setItem('wide-content', false);
37        },
38
39        /**
40         * Accessibility helper, focuses the first link witih the given element
41         *
42         * @param {jQuery} $elem
43         */
44        focusFirstSubLink = function ($elem) {
45            $elem.find('a').first().focus();
46        },
47
48        /**
49         * Toggle a navigation panel
50         *
51         * @param {jQuery} $toggler The a toggler
52         */
53         toggleNav = function ($toggler) {
54            var $panel = $toggler.parent().next('div.nav-panel');
55            var isOpen = $panel.is(':visible');
56            // open sidebar on interaction
57            setDefaultContent();
58            // toggle the panel, focus first link after opening
59            $panel.dw_toggle(!isOpen, function () {
60                if (!isOpen) {
61                    focusFirstSubLink($panel);
62                }
63            });
64            window.sessionStorage.setItem('sidebar-section-' + $toggler.data('index') + '-open', !isOpen);
65        },
66
67        /**
68         * Initialize the content navigation
69         *
70         * It mangles the sidebar content and handles inline Icon configuration
71         */
72        initContentNav = function () {
73            var $main = $nav.find('nav.nav-main');
74            if (!$main.length) return;
75
76            if(jQuery('body').hasClass('wide-content')) {
77                removeToggleStorage();
78            }
79
80            var ELEMENT = JSINFO.template.sprintdoc.sidebar_toggle_elements;
81            var $elements = $main.find(ELEMENT);
82            $elements.each(function (index) {
83                var $me = jQuery(this),
84
85                // prepare text and the optional icon
86                    data = $me.text().split('@', 2),
87                    text = data[0].trim();
88
89                var $icon = jQuery('<span class="ico">')
90                    .text(text.substr(0, 1).toUpperCase() + text.substr(1, 1).toLowerCase())
91                    .wrapInner('<strong>');
92                if (data[1]) {
93                    var src = data[1].trim();
94                    $icon.load(DOKU_BASE + 'lib/tpl/sprintdoc/svg.php?svg=' + src + '&e=1'); // directly embed
95                }
96
97                // make the new toggler
98                var $toggler = jQuery('<a>')
99                        .attr('href', '#')
100                        .attr('role', 'heading')
101                        .attr('aria-level', '2')
102                        .text(text)
103                        .wrapInner('<span class="lbl">')
104                        .prepend($icon)
105                        .data('index', index)
106                    ;
107                $toggler = jQuery('<div class="nav">').prepend($toggler);
108
109                // wrap all following siblings til the next element in a wrapper
110                var $wrap = jQuery('<div>')
111                    .addClass('nav-panel');
112                var $sibs = $me.nextAll();
113                for (var i = 0; i < $sibs.length; i++) {
114                    var $sib = jQuery($sibs[i]);
115                    if ($sib.is(ELEMENT)) break;
116                    $sib.detach().appendTo($wrap);
117                }
118                $wrap.insertAfter($me);
119
120                // replace element with toggler
121                $me.replaceWith($toggler);
122
123                if ($toggler.parent('li').length) {
124                    $toggler.parent('li').addClass('toggler');
125                }
126
127                if (window.sessionStorage.getItem('sidebar-section-' + index + '-open') === 'true') {
128                    $wrap.css('display', 'block');
129                }
130
131            });
132        },
133
134        /**
135         * Initialize the open/close toggling of menu entries
136         */
137        initMenuHandling = function () {
138            $nav.on('click', 'div.nav a', function (e) {
139                toggleNav(jQuery(this));
140                e.preventDefault();
141            });
142        },
143
144        /**
145         * Make sure the content area is always as high as the sidebar
146         */
147        initContentMinHeight = function () {
148            var $sidebar = jQuery('.page-wrapper').find('> .tools').find('.col-xs-12');
149            if ($sidebar.length == 1) {
150                var num = parseFloat($sidebar.height());
151                if (!isNaN(num)) {
152                    jQuery('#dokuwiki__content').css('minHeight', num + 100);
153                }
154            }
155        },
156
157        /**
158         * Initialize the sidebar handle behaviour
159         */
160        initSidebarToggling = function () {
161            var $toggler = jQuery('.togglelink.page_main-content').find('a');
162            $toggler.click(function (e) {
163                e.preventDefault();
164                if (jQuery('body').hasClass('wide-content')) {
165                    setDefaultContent();
166                } else {
167                    setWideContent();
168                }
169            });
170
171            if (window.sessionStorage.getItem('wide-content') === 'true') {
172                setWideContent();
173            }
174        },
175
176        /**
177         * Show sidebar when accessing the search
178         */
179        initSearchToggling = function () {
180            jQuery('.toggleSearch').find('a').click(function (e) {
181                setDefaultContent();
182                e.preventDefault();
183                jQuery('#qsearch__in').focus();
184            });
185
186        },
187
188        /**
189         * Open and close the sidebar in mobile view
190         */
191        initMobileToggling = function () {
192            jQuery('.menu-togglelink').find('a').click(function (e) {
193                e.preventDefault();
194                var $body = jQuery('body');
195                $body.toggleClass('show-mobile-sidebar');
196            });
197        };
198
199    // main
200    initContentNav();
201    initSidebarToggling();
202    initMenuHandling();
203    initContentMinHeight();
204    initSearchToggling();
205    initMobileToggling();
206});
207
208