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