1/** 2 * Page behaviours 3 * 4 * This class adds various behaviours to the rendered page 5 */ 6dw_page = { 7 /** 8 * initialize page behaviours 9 */ 10 init: function(){ 11 dw_page.sectionHighlight(); 12 jQuery('a.fn_top').mouseover(dw_page.footnoteDisplay); 13 dw_page.makeToggle('#dw__toc h3','#dw__toc > div'); 14 }, 15 16 /** 17 * Highlight the section when hovering over the appropriate section edit button 18 * 19 * @author Andreas Gohr <andi@splitbrain.org> 20 */ 21 sectionHighlight: function() { 22 jQuery('form.btn_secedit') 23 .mouseover(function(){ 24 var $tgt = jQuery(this).parent(), 25 nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2]; 26 27 // Walk the DOM tree up (first previous siblings, then parents) 28 // until boundary element 29 while($tgt.length > 0 && !$tgt.hasClass('sectionedit' + nr)) { 30 // $.last gives the DOM-ordered last element: 31 // prev if present, else parent. 32 $tgt = $tgt.prev().add($tgt.parent()).last(); 33 $tgt.addClass('section_highlight'); 34 } 35 }) 36 .mouseout(function(){ 37 jQuery('.section_highlight').removeClass('section_highlight'); 38 }); 39 }, 40 41 /** 42 * Create/get a insitu popup used by the footnotes 43 * 44 * @param target - the DOM element at which the popup should be aligned at 45 * @param popup_id - the ID of the (new) DOM popup 46 * @return the Popup jQuery object 47 */ 48 insituPopup: function(target, popup_id) { 49 // get or create the popup div 50 var $fndiv = jQuery('#' + popup_id); 51 52 // popup doesn't exist, yet -> create it 53 if($fndiv.length === 0){ 54 $fndiv = jQuery(document.createElement('div')) 55 .attr('id', popup_id) 56 .addClass('insitu-footnote JSpopup') 57 .mouseleave(function () {jQuery(this).hide();}); 58 jQuery('.dokuwiki:first').append($fndiv); 59 } 60 61 // position() does not support hidden elements 62 $fndiv.show().position({ 63 my: 'left top', 64 at: 'left center', 65 of: target 66 }).hide(); 67 68 return $fndiv; 69 }, 70 71 /** 72 * Display an insitu footnote popup 73 * 74 * @author Andreas Gohr <andi@splitbrain.org> 75 * @author Chris Smith <chris@jalakai.co.uk> 76 */ 77 footnoteDisplay: function () { 78 var content = jQuery(jQuery(this).attr('href')) // Footnote text anchor 79 .closest('div.fn').html(); 80 81 if (content === null){ 82 return; 83 } 84 85 // strip the leading content anchors and their comma separators 86 content = content.replace(/((^|\s*,\s*)<sup>.*?<\/sup>)+\s*/gi, ''); 87 88 // prefix ids on any elements with "insitu__" to ensure they remain unique 89 content = content.replace(/\bid=(['"])([^"']+)\1/gi,'id="insitu__$2'); 90 91 // now put the content into the wrapper 92 dw_page.insituPopup(this, 'insitu__fn').html(content).show(); 93 }, 94 95 /** 96 * Makes an element foldable by clicking its handle 97 * 98 * This is used for the TOC toggling, but can be used for other elements 99 * as well. A state indicator is inserted into the handle and can be styled 100 * by CSS. 101 * 102 * @param selector handle What should be clicked to toggle 103 * @param selector content This element will be toggled 104 */ 105 makeToggle: function(handle, content, state){ 106 var $handle, $content, $clicky, $child, setClicky; 107 $handle = jQuery(handle); 108 if(!$handle.length) return; 109 $content = jQuery(content); 110 if(!$content.length) return; 111 112 // we animate the children 113 $child = $content.children(); 114 115 // class/display toggling 116 setClicky = function(hiding){ 117 if(hiding){ 118 $clicky.html('<span>+</span>'); 119 $handle.addClass('closed'); 120 $handle.removeClass('open'); 121 }else{ 122 $clicky.html('<span>−</span>'); 123 $handle.addClass('open'); 124 $handle.removeClass('closed'); 125 } 126 }; 127 128 $handle[0].setState = function(state){ 129 var hidden; 130 if(!state) state = 1; 131 132 // Assert that content instantly takes the whole space 133 $content.css('min-height', $content.height()).show(); 134 135 // stop any running animation 136 $child.stop(true, true); 137 138 // was a state given or do we toggle? 139 if(state === -1) { 140 hidden = false; 141 } else if(state === 1) { 142 hidden = true; 143 } else { 144 hidden = $child.is(':hidden'); 145 } 146 147 // update the state 148 setClicky(!hidden); 149 150 // Start animation and assure that $toc is hidden/visible 151 $child.dw_toggle(hidden, function () { 152 $content.toggle(hidden); 153 }); 154 }; 155 156 // the state indicator 157 $clicky = jQuery(document.createElement('strong')); 158 159 // click function 160 $handle.css('cursor','pointer') 161 .click($handle[0].setState) 162 .prepend($clicky); 163 164 // initial state 165 $handle[0].setState(state); 166 } 167}; 168 169jQuery(dw_page.init); 170