[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/scripts/ -> page.js (source)

   1  /**
   2   * Page behaviours
   3   *
   4   * This class adds various behaviours to the rendered page
   5   */
   6  dw_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                      $highlight = jQuery(),                                             // holder for elements in the section to be highlighted
  27                      $highlightWrap = jQuery('<div class="section_highlight"></div>');  // section highlight wrapper
  28  
  29                  // Walk the dom tree in reverse to find the sibling which is or contains the section edit marker
  30                  while($tgt.length > 0 && !($tgt.hasClass('sectionedit' + nr) || $tgt.find('.sectionedit' + nr).length)) {
  31                      $tgt = $tgt.prev();
  32                      $highlight = $highlight.add($tgt);
  33                  }
  34                // insert the section highlight wrapper before the last element added to $highlight
  35                $highlight.filter(':last').before($highlightWrap);
  36                // and move the elements to be highlighted inside the section highlight wrapper
  37                $highlight.detach().appendTo($highlightWrap);
  38              })
  39              .mouseout(function(){
  40                  // find the section highlight wrapper...
  41                  var $highlightWrap = jQuery('.section_highlight');
  42                  // ...move its children in front of it (as siblings)...
  43                  $highlightWrap.before($highlightWrap.children().detach());
  44                  // ...and remove the section highlight wrapper
  45                  $highlightWrap.detach();
  46              });
  47      },
  48  
  49      /**
  50       * Create/get a insitu popup used by the footnotes
  51       *
  52       * @param target - the DOM element at which the popup should be aligned at
  53       * @param popup_id - the ID of the (new) DOM popup
  54       * @return the Popup jQuery object
  55       */
  56      insituPopup: function(target, popup_id) {
  57          // get or create the popup div
  58          var $fndiv = jQuery('#' + popup_id);
  59  
  60          // popup doesn't exist, yet -> create it
  61          if($fndiv.length === 0){
  62              $fndiv = jQuery(document.createElement('div'))
  63                  .attr('id', popup_id)
  64                  .addClass('insitu-footnote JSpopup')
  65                  .attr('aria-hidden', 'true')
  66                  .mouseleave(function () {jQuery(this).hide().attr('aria-hidden', 'true');})
  67                  .attr('role', 'tooltip');
  68              jQuery('.dokuwiki:first').append($fndiv);
  69          }
  70  
  71          // position() does not support hidden elements
  72          $fndiv.show().position({
  73              my: 'left top',
  74              at: 'left center',
  75              of: target
  76          }).hide();
  77  
  78          return $fndiv;
  79      },
  80  
  81      /**
  82       * Display an insitu footnote popup
  83       *
  84       * @author Andreas Gohr <andi@splitbrain.org>
  85       * @author Chris Smith <chris@jalakai.co.uk>
  86       * @author Anika Henke <anika@selfthinker.org>
  87       */
  88      footnoteDisplay: function () {
  89          var $content = jQuery(jQuery(this).attr('href')) // Footnote text anchor
  90                        .parent().siblings('.content').clone();
  91  
  92          if (!$content.length) {
  93              return;
  94          }
  95  
  96          // prefix ids on any elements with "insitu__" to ensure they remain unique
  97          jQuery('[id]', $content).each(function(){
  98              var id = jQuery(this).attr('id');
  99              jQuery(this).attr('id', 'insitu__' + id);
 100          });
 101  
 102          var content = $content.html().trim();
 103          // now put the content into the wrapper
 104          dw_page.insituPopup(this, 'insitu__fn').html(content)
 105          .show().attr('aria-hidden', 'false');
 106      },
 107  
 108      /**
 109       * Makes an element foldable by clicking its handle
 110       *
 111       * This is used for the TOC toggling, but can be used for other elements
 112       * as well. A state indicator is inserted into the handle and can be styled
 113       * by CSS.
 114       *
 115       * To properly reserve space for the expanded element, the sliding animation is
 116       * done on the children of the content. To make that look good and to make sure aria
 117       * attributes are assigned correctly, it's recommended to make sure that the content
 118       * element contains a single child element only.
 119       *
 120       * @param {selector} handle What should be clicked to toggle
 121       * @param {selector} content This element will be toggled
 122       * @param {int} state initial state (-1 = open, 1 = closed)
 123       */
 124      makeToggle: function(handle, content, state){
 125          var $handle, $content, $clicky, $child, setClicky;
 126          $handle = jQuery(handle);
 127          if(!$handle.length) return;
 128          $content = jQuery(content);
 129          if(!$content.length) return;
 130  
 131          // we animate the children
 132          $child = $content.children();
 133  
 134          // class/display toggling
 135          setClicky = function(hiding){
 136              if(hiding){
 137                  $clicky.html('<span>+</span>');
 138                  $handle.addClass('closed');
 139                  $handle.removeClass('open');
 140              }else{
 141                  $clicky.html('<span>−</span>');
 142                  $handle.addClass('open');
 143                  $handle.removeClass('closed');
 144              }
 145          };
 146  
 147          $handle[0].setState = function(state){
 148              var hidden;
 149              if(!state) state = 1;
 150  
 151              // Assert that content instantly takes the whole space
 152              $content.css('min-height', $content.height()).show();
 153  
 154              // stop any running animation
 155              $child.stop(true, true);
 156  
 157              // was a state given or do we toggle?
 158              if(state === -1) {
 159                  hidden = false;
 160              } else if(state === 1) {
 161                  hidden = true;
 162              } else {
 163                  hidden = $child.is(':hidden');
 164              }
 165  
 166              // update the state
 167              setClicky(!hidden);
 168  
 169              // Start animation and assure that $toc is hidden/visible
 170              $child.dw_toggle(hidden, function () {
 171                  $content.toggle(hidden);
 172                  $content.attr('aria-expanded', hidden);
 173                  $content.css('min-height',''); // remove min-height again
 174              }, true);
 175          };
 176  
 177          // the state indicator
 178          $clicky = jQuery(document.createElement('strong'));
 179  
 180          // click function
 181          $handle.css('cursor','pointer')
 182                 .click($handle[0].setState)
 183                 .prepend($clicky);
 184  
 185          // initial state
 186          $handle[0].setState(state);
 187      }
 188  };
 189  
 190  jQuery(dw_page.init);