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