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