You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

336 lines
12 KiB

  1. /**
  2. * Sets up the sidebar behaviour
  3. *
  4. * @author Andreas Gohr <gohr@cosmocode.de>
  5. * @author Michael Große <gohr@cosmocode.de>
  6. * @author Jana Deutschlaender <deutschlaender@cosmocode.de>
  7. */
  8. jQuery(function () {
  9. var $nav = jQuery('#dokuwiki__aside');
  10. if (!$nav.length) return;
  11. // id of the current sidebar, used to differentiate states
  12. var sidebarId = '';
  13. var divId = jQuery('#sidebarId');
  14. if (typeof divId !== 'undefined') {
  15. sidebarId = divId.attr('class').split(' ')[0];
  16. }
  17. /**
  18. * closes sidebar
  19. */
  20. var setWideContent = function () {
  21. $nav.find('div.nav-panel').hide(); // close all panels
  22. jQuery('body').addClass('wide-content');
  23. removeToggleStorage();
  24. window.sessionStorage.setItem('wide-content', true);
  25. },
  26. /**
  27. * removes information about the toggle-state
  28. */
  29. removeToggleStorage = function () {
  30. for (var index=0; index <= window.sessionStorage.length; index += 1) {
  31. var item = window.sessionStorage.getItem('sidebar-section-' + sidebarId + '-' + index + '-open');
  32. if (!item) {
  33. continue;
  34. }
  35. window.sessionStorage.setItem('sidebar-section-' + sidebarId + '-' + index + '-open', 'false');
  36. }
  37. },
  38. /**
  39. * opens the sidebar
  40. */
  41. setDefaultContent = function () {
  42. jQuery('body').removeClass('wide-content');
  43. window.sessionStorage.setItem('wide-content', false);
  44. },
  45. /**
  46. * Accessibility helper, focuses the first link witih the given element
  47. *
  48. * @param {jQuery} $elem
  49. */
  50. focusFirstSubLink = function ($elem) {
  51. $elem.find('a').first().focus();
  52. },
  53. removeOpenStates = function() {
  54. $nav.find('.is-open').removeClass('is-open');
  55. },
  56. /**
  57. * Toggle a navigation panel
  58. *
  59. * @param {jQuery} $toggler The a toggler
  60. */
  61. toggleNav = function ($toggler) {
  62. var $panel = $toggler.parent().next('div.nav-panel');
  63. var isOpen = $panel.is(':visible');
  64. // open sidebar on interaction
  65. setDefaultContent();
  66. // toggle the panel, focus first link after opening
  67. $panel.dw_toggle(!isOpen, function () {
  68. if (!isOpen) {
  69. focusFirstSubLink($panel);
  70. $toggler.addClass('is-open');
  71. } else {
  72. $toggler.removeClass('is-open');
  73. }
  74. });
  75. window.sessionStorage.setItem('sidebar-section-' + sidebarId + '-' + $toggler.data('index') + '-open', !isOpen);
  76. },
  77. /**
  78. * Initialize the content navigation
  79. *
  80. * It mangles the sidebar content and handles inline Icon configuration
  81. */
  82. initContentNav = function () {
  83. var $main = $nav.find('nav.nav-main');
  84. if (!$main.length) return;
  85. if(jQuery('body').hasClass('wide-content')) {
  86. removeToggleStorage();
  87. }
  88. var ELEMENT = JSINFO.template.sprintdoc.sidebar_toggle_elements;
  89. var $elements = $main.find(ELEMENT);
  90. $elements.each(function (index) {
  91. var $me = jQuery(this),
  92. // prepare text and the optional icon
  93. data = $me.text().split('@', 2),
  94. text = data[0].trim();
  95. var $icon = jQuery('<span class="ico">')
  96. .text(text.substr(0, 1).toUpperCase() + text.substr(1, 1).toLowerCase())
  97. .wrapInner('<strong>');
  98. if (data[1]) {
  99. var src = data[1].trim();
  100. $icon.load(DOKU_BASE + 'lib/tpl/sprintdoc/svg.php?svg=' + src + '&e=1'); // directly embed
  101. }
  102. // make the new toggler
  103. var $toggler = jQuery('<a>')
  104. .attr('href', '#')
  105. .attr('role', 'heading')
  106. .attr('aria-level', '2')
  107. .text(text)
  108. .wrapInner('<span class="lbl">')
  109. .prepend($icon)
  110. .data('index', index)
  111. ;
  112. $toggler = jQuery('<div class="nav">').prepend($toggler);
  113. // wrap all following siblings til the next element in a wrapper
  114. var $wrap = jQuery('<div>')
  115. .addClass('nav-panel');
  116. var $sibs = $me.nextAll();
  117. for (var i = 0; i < $sibs.length; i++) {
  118. var $sib = jQuery($sibs[i]);
  119. if ($sib.is(ELEMENT)) break;
  120. $sib.detach().appendTo($wrap);
  121. addContentMenuCurrentStates($sib, $toggler);
  122. }
  123. /*
  124. * if there is only one subitem with a link, disable toggling
  125. * and use a direct link.
  126. */
  127. var $links = jQuery($wrap[0]).find('a');
  128. if ($links.length === 1 && $links.first().attr('href') !== '#') {
  129. $toggler.children().first().attr('href', jQuery($links[0]).attr('href'));
  130. } else {
  131. $wrap.insertAfter($me);
  132. if ($toggler.parent('li').length) {
  133. $toggler.parent('li').addClass('toggler');
  134. }
  135. if (window.sessionStorage.getItem('sidebar-section-' + sidebarId + '-' + index + '-open') === 'true') {
  136. $wrap.css('display', 'block');
  137. setTogglerClass($toggler,'is-open');
  138. }
  139. }
  140. // replace element with toggler
  141. $me.replaceWith($toggler);
  142. });
  143. // fade in the navigation (was hidden until now
  144. $main.css({opacity: 0, visibility: "visible"}).animate({opacity: 1}, 200);
  145. },
  146. /**
  147. * Initialize the open/close toggling of menu entries
  148. */
  149. initMenuHandling = function () {
  150. $nav.on('click', 'div.nav a', function (e) {
  151. if (jQuery(this).attr('href').startsWith('#')) {
  152. toggleNav(jQuery(this));
  153. e.preventDefault();
  154. }
  155. });
  156. },
  157. /**
  158. * adds a given class to the toggler link
  159. * @param $toggler link or parent of link to whom the class is added
  160. * @param classVal class to be added
  161. */
  162. setTogglerClass = function ($toggler, classVal) {
  163. if($toggler.is('a')) {
  164. $toggler.addClass(classVal);
  165. } else {
  166. $toggler.find('a').addClass(classVal);
  167. }
  168. },
  169. /**
  170. * marks a $toggler link as active if the following menu has an active state
  171. * @param $menuObj jQuery Object of the menu / container
  172. * @param $toggler
  173. */
  174. addContentMenuCurrentStates = function ($menuObj, $toggler) {
  175. if($menuObj[0] && String($menuObj[0].innerHTML).indexOf('curid') > 0) {
  176. setTogglerClass($toggler,'is-active');
  177. }
  178. },
  179. /**
  180. * Make sure the content area is always as high as the sidebar
  181. */
  182. initContentMinHeight = function () {
  183. var $sidebar = jQuery('.page-wrapper').find('> .tools').find('.col-xs-12');
  184. if ($sidebar.length == 1) {
  185. var num = parseFloat($sidebar.height());
  186. if (!isNaN(num)) {
  187. jQuery('#dokuwiki__content').css('minHeight', num + 100);
  188. }
  189. }
  190. },
  191. /**
  192. * Initialize the sidebar handle behaviour
  193. */
  194. initSidebarToggling = function () {
  195. var $toggler = jQuery('.togglelink.page_main-content').find('a');
  196. $toggler.click(function (e) {
  197. e.preventDefault();
  198. if (jQuery('body').hasClass('wide-content')) {
  199. setDefaultContent();
  200. } else {
  201. setWideContent();
  202. removeOpenStates();
  203. }
  204. });
  205. if (window.sessionStorage.getItem('wide-content') === 'true') {
  206. setWideContent();
  207. }
  208. },
  209. /**
  210. * Show sidebar when accessing the search
  211. */
  212. initSearchToggling = function () {
  213. jQuery('.toggleSearch').find('a').click(function (e) {
  214. setDefaultContent();
  215. e.preventDefault();
  216. jQuery('#qsearch__in').focus();
  217. });
  218. },
  219. /**
  220. * Open and close the sidebar in mobile view
  221. */
  222. initMobileToggling = function () {
  223. jQuery('.menu-togglelink').find('a').click(function (e) {
  224. e.preventDefault();
  225. var $body = jQuery('body');
  226. $body.toggleClass('show-mobile-sidebar');
  227. });
  228. },
  229. /**
  230. * set is-active class if body has at least one of the given selectors
  231. * @param selectorArray Array of selectors
  232. * @param $nav container in which the $toggler is situated
  233. */
  234. setActive = function(selectorArray, $nav) {
  235. for(var i=0; i< selectorArray.length; i++) {
  236. var mode = selectorArray[i];
  237. if(jQuery('body').is('.do-'+mode)){
  238. setTogglerClass($nav.find('.nav'),'is-active');
  239. $nav.find('a[href*="do='+mode+'"]').wrapAll('<span class="curid"></span>');
  240. }
  241. }
  242. },
  243. /**
  244. * sets active states in site tool menu and user tool menu for certain modes
  245. * adds sessionStorage behaviour equivalent approach to content menus
  246. *
  247. */
  248. initTemplateMenues = function () {
  249. var $body = jQuery('body'),
  250. $siteTools = $nav.find('> .nav-sitetools'),
  251. $userTools = $nav.find('> .nav-usermenu'),
  252. $templateMenus = $nav.find('> nav:not(.nav-main)'),
  253. stModes = ['recent', 'media', 'index'],
  254. utModes = ['profile','admin'],
  255. isWideContent = false;
  256. /* set active states for site tool menu and user tool menu */
  257. setActive(stModes,$siteTools);
  258. setActive(utModes,$userTools);
  259. if($body.is('.do-show') && $body.is('.wide-content')) {
  260. window.sessionStorage.setItem('wide-content', true);
  261. isWideContent = true;
  262. }
  263. /* set data attributes for sessionStorage and check onload if one of the template menus should be opened */
  264. $templateMenus.each(function( index ) {
  265. var $t = jQuery(this).find('.nav'),
  266. y = $nav.find('.nav-main').find('.nav').length,
  267. $toggler = ($t.is('a')) ? $t : $t.find('a:last'),
  268. tIndex = y + index;
  269. $toggler.data('index', tIndex);
  270. var item = window.sessionStorage.getItem('sidebar-section-' + sidebarId + '-' + tIndex + '-open');
  271. if (item) {
  272. if(isWideContent) {
  273. window.sessionStorage.setItem('sidebar-section-' + sidebarId + '-' + tIndex + '-open', 'false');
  274. } else {
  275. if (item === 'true') {
  276. jQuery(this).find('.nav-panel').css('display', 'block');
  277. setTogglerClass($toggler, 'is-open');
  278. }
  279. }
  280. }
  281. //console.log(window.sessionStorage);
  282. });
  283. };
  284. // main
  285. initContentNav();
  286. initSidebarToggling();
  287. initTemplateMenues();
  288. initMenuHandling();
  289. initContentMinHeight();
  290. initSearchToggling();
  291. initMobileToggling();
  292. });