[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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

   1  /**
   2   * The DokuWiki editor features
   3   *
   4   * These are the advanced features of the editor. It does NOT contain any
   5   * code for the toolbar buttons and it functions. See toolbar.js for that.
   6   */
   7  
   8  var dw_editor = {
   9  
  10      /**
  11       * initialize the default editor functionality
  12       *
  13       * All other functions can also be called separately for non-default
  14       * textareas
  15       */
  16      init: function(){
  17          var $editor = jQuery('#wiki__text');
  18          if($editor.length === 0) {
  19              return;
  20          }
  21  
  22          dw_editor.initSizeCtl('#size__ctl',$editor);
  23  
  24          if($editor.attr('readOnly')) {
  25              return;
  26          }
  27  
  28          $editor.keydown(dw_editor.keyHandler);
  29  
  30      },
  31  
  32      /**
  33       * Add the edit window size and wrap controls
  34       *
  35       * Initial values are read from cookie if it exists
  36       *
  37       * @param selector ctlarea the div to place the controls
  38       * @param selector editor  the textarea to control
  39       */
  40      initSizeCtl: function(ctlarea,editor){
  41          var $ctl      = jQuery(ctlarea),
  42              $textarea = jQuery(editor);
  43  
  44          if($ctl.length === 0 || $textarea.length === 0) {
  45              return;
  46          }
  47  
  48          $textarea.css('height', DokuCookie.getValue('sizeCtl') || '300px');
  49  
  50          var wrp = DokuCookie.getValue('wrapCtl');
  51          if(wrp){
  52              dw_editor.setWrap($textarea[0], wrp);
  53          } // else use default value
  54  
  55          jQuery.each([
  56              ['larger', function(){dw_editor.sizeCtl(editor,100);}],
  57              ['smaller', function(){dw_editor.sizeCtl(editor,-100);}],
  58              ['wrap', function(){dw_editor.toggleWrap(editor);}]
  59          ], function (_, img) {
  60              jQuery(document.createElement('img'))
  61                  .attr('src', DOKU_BASE+'lib/images/' + img[0] + '.gif')
  62                  .attr('alt', '')
  63                  .on('click', img[1])
  64                  .appendTo($ctl);
  65          });
  66      },
  67  
  68      /**
  69       * This sets the vertical size of the editbox and adjusts the cookie
  70       *
  71       * @param selector editor  the textarea to control
  72       * @param int val          the relative value to resize in pixel
  73       */
  74      sizeCtl: function(editor,val){
  75          var $textarea = jQuery(editor),
  76              height = parseInt($textarea.css('height')) + val;
  77          $textarea.css('height', height+'px');
  78          DokuCookie.setValue('sizeCtl',$textarea.css('height'));
  79      },
  80  
  81      /**
  82       * Toggle the wrapping mode of the editor textarea and adjusts the
  83       * cookie
  84       *
  85       * @param selector editor  the textarea to control
  86       */
  87      toggleWrap: function(editor){
  88          var $textarea = jQuery(editor),
  89              wrap = $textarea.attr('wrap');
  90          dw_editor.setWrap($textarea[0],
  91                            (wrap && wrap.toLowerCase() == 'off') ? 'soft' : 'off');
  92          DokuCookie.setValue('wrapCtl',$textarea.attr('wrap'));
  93      },
  94  
  95      /**
  96       * Set the wrapping mode of a textarea
  97       *
  98       * @author Fluffy Convict <fluffyconvict@hotmail.com>
  99       * @author <shutdown@flashmail.com>
 100       * @link   http://news.hping.org/comp.lang.javascript.archive/12265.html
 101       * @link   https://bugzilla.mozilla.org/show_bug.cgi?id=41464
 102       * @param  DomObject textarea
 103       * @param  string wrapAttrValue
 104       */
 105      setWrap: function(textarea, wrapAttrValue){
 106          textarea.setAttribute('wrap', wrapAttrValue);
 107  
 108          // Fix display for mozilla
 109          var parNod = textarea.parentNode;
 110          var nxtSib = textarea.nextSibling;
 111          parNod.removeChild(textarea);
 112          parNod.insertBefore(textarea, nxtSib);
 113      },
 114  
 115      /**
 116       * Make intended formattings easier to handle
 117       *
 118       * Listens to all key inputs and handle indentions
 119       * of lists and code blocks
 120       *
 121       * Currently handles space, backspace, enter and
 122       * ctrl-enter presses
 123       *
 124       * @author Andreas Gohr <andi@splitbrain.org>
 125       * @fixme handle tabs
 126       * @param event e - the key press event object
 127       */
 128      keyHandler: function(e){
 129          if(jQuery.inArray(e.keyCode,[8, 10, 13, 32]) === -1) {
 130              return;
 131          }
 132          var selection = DWgetSelection(this);
 133          if(selection.getLength() > 0) {
 134              return; //there was text selected, keep standard behavior
 135          }
 136          var search    = "\n"+this.value.substr(0,selection.start);
 137          var linestart = Math.max(search.lastIndexOf("\n"),
 138                                   search.lastIndexOf("\r")); //IE workaround
 139          search = search.substr(linestart);
 140  
 141          if((e.keyCode == 13 || e.keyCode == 10) && e.ctrlKey) { // Ctrl-Enter (With Chrome workaround)
 142              // Submit current edit
 143              jQuery('#edbtn__save').trigger('click');
 144              e.preventDefault(); // prevent enter key
 145              return false;
 146          }else if(e.keyCode == 13){ // Enter
 147              // keep current indention for lists and code
 148              var match = search.match(/(\n  +([\*-] ?)?)/);
 149              if(match){
 150                  var scroll = this.scrollHeight;
 151                  var match2 = search.match(/^\n  +[\*-]\s*$/);
 152                  // Cancel list if the last item is empty (i. e. two times enter)
 153                  if (match2 && this.value.substr(selection.start).match(/^($|\r?\n)/)) {
 154                      this.value = this.value.substr(0, linestart) + "\n" +
 155                                   this.value.substr(selection.start);
 156                      selection.start = linestart + 1;
 157                      selection.end = linestart + 1;
 158                      DWsetSelection(selection);
 159                  } else {
 160                      insertAtCarret(this.id,match[1]);
 161                  }
 162                  this.scrollTop += (this.scrollHeight - scroll);
 163                  e.preventDefault(); // prevent enter key
 164                  return false;
 165              }
 166          }else if(e.keyCode == 8){ // Backspace
 167              // unindent lists
 168              var match = search.match(/(\n  +)([*-] ?)$/);
 169              if(match){
 170                  var spaces = match[1].length-1;
 171  
 172                  if(spaces > 3){ // unindent one level
 173                      this.value = this.value.substr(0,linestart)+
 174                                   this.value.substr(linestart+2);
 175                      selection.start = selection.start - 2;
 176                      selection.end   = selection.start;
 177                  }else{ // delete list point
 178                      this.value = this.value.substr(0,linestart)+
 179                                   this.value.substr(selection.start);
 180                      selection.start = linestart;
 181                      selection.end   = linestart;
 182                  }
 183                  DWsetSelection(selection);
 184                  e.preventDefault(); // prevent backspace
 185                  return false;
 186              }
 187          }else if(e.keyCode == 32){ // Space
 188              // intend list item
 189              var match = search.match(/(\n  +)([*-] )$/);
 190              if(match){
 191                  this.value = this.value.substr(0,linestart)+'  '+
 192                               this.value.substr(linestart);
 193                  selection.start = selection.start + 2;
 194                  selection.end   = selection.start;
 195                  DWsetSelection(selection);
 196                  e.preventDefault(); // prevent space
 197                  return false;
 198              }
 199          }
 200      }
 201  
 202  
 203  };
 204  
 205  jQuery(dw_editor.init);