[ 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              var $btn = jQuery(document.createElement('button'))
  61                  .attr('type', 'button')
  62                  .attr('title', LANG['size_' + img[0]])
  63                  .on('click', img[1])
  64                  .appendTo($ctl);
  65              jQuery(document.createElement('img'))
  66                  .attr('src', DOKU_BASE+'lib/images/' + img[0] + '.svg')
  67                  .attr('alt', LANG['size_' + img[0]])
  68                  .appendTo($btn);
  69          });
  70      },
  71  
  72      /**
  73       * This sets the vertical size of the editbox and adjusts the cookie
  74       *
  75       * @param selector editor  the textarea to control
  76       * @param int val          the relative value to resize in pixel
  77       */
  78      sizeCtl: function(editor,val){
  79          var $textarea = jQuery(editor),
  80              height = parseInt($textarea.css('height')) + val;
  81          $textarea.css('height', height+'px');
  82          DokuCookie.setValue('sizeCtl',$textarea.css('height'));
  83      },
  84  
  85      /**
  86       * Toggle the wrapping mode of the editor textarea and adjusts the
  87       * cookie
  88       *
  89       * @param selector editor  the textarea to control
  90       */
  91      toggleWrap: function(editor){
  92          var $textarea = jQuery(editor),
  93              wrap = $textarea.attr('wrap');
  94          dw_editor.setWrap($textarea[0],
  95                            (wrap && wrap.toLowerCase() == 'off') ? 'soft' : 'off');
  96          DokuCookie.setValue('wrapCtl',$textarea.attr('wrap'));
  97      },
  98  
  99      /**
 100       * Set the wrapping mode of a textarea
 101       *
 102       * @author Fluffy Convict <fluffyconvict@hotmail.com>
 103       * @author <shutdown@flashmail.com>
 104       * @link   http://news.hping.org/comp.lang.javascript.archive/12265.html
 105       * @link   https://bugzilla.mozilla.org/show_bug.cgi?id=41464
 106       * @param  DomObject textarea
 107       * @param  string wrapAttrValue
 108       */
 109      setWrap: function(textarea, wrapAttrValue){
 110          textarea.setAttribute('wrap', wrapAttrValue);
 111  
 112          // Fix display for mozilla
 113          var parNod = textarea.parentNode;
 114          var nxtSib = textarea.nextSibling;
 115          parNod.removeChild(textarea);
 116          parNod.insertBefore(textarea, nxtSib);
 117      },
 118  
 119      /**
 120       * Make intended formattings easier to handle
 121       *
 122       * Listens to all key inputs and handle indentions
 123       * of lists and code blocks
 124       *
 125       * Currently handles space, backspace, enter and
 126       * ctrl-enter presses
 127       *
 128       * @author Andreas Gohr <andi@splitbrain.org>
 129       * @fixme handle tabs
 130       * @param event e - the key press event object
 131       */
 132      keyHandler: function(e){
 133          if(jQuery.inArray(e.keyCode,[8, 10, 13, 32]) === -1) {
 134              return;
 135          }
 136          var selection = DWgetSelection(this);
 137          if(selection.getLength() > 0) {
 138              return; //there was text selected, keep standard behavior
 139          }
 140          var search    = "\n"+this.value.substr(0,selection.start);
 141          var linestart = Math.max(search.lastIndexOf("\n"),
 142                                   search.lastIndexOf("\r")); //IE workaround
 143          search = search.substr(linestart);
 144  
 145          if((e.keyCode == 13 || e.keyCode == 10) && e.ctrlKey) { // Ctrl-Enter (With Chrome workaround)
 146              // Submit current edit
 147              jQuery('#edbtn__save').trigger('click');
 148              e.preventDefault(); // prevent enter key
 149              return false;
 150          }else if(e.keyCode == 13){ // Enter
 151              // keep current indention for lists and code
 152              var match = search.match(/(\n  +([\*-] ?)?)/);
 153              if(match){
 154                  var scroll = this.scrollHeight;
 155                  var match2 = search.match(/^\n  +[\*-]\s*$/);
 156                  // Cancel list if the last item is empty (i. e. two times enter)
 157                  if (match2 && this.value.substr(selection.start).match(/^($|\r?\n)/)) {
 158                      this.value = this.value.substr(0, linestart) + "\n" +
 159                                   this.value.substr(selection.start);
 160                      selection.start = linestart + 1;
 161                      selection.end = linestart + 1;
 162                      DWsetSelection(selection);
 163                  } else {
 164                      insertAtCarret(this.id,match[1]);
 165                  }
 166                  this.scrollTop += (this.scrollHeight - scroll);
 167                  e.preventDefault(); // prevent enter key
 168                  return false;
 169              }
 170          }else if(e.keyCode == 8){ // Backspace
 171              // unindent lists
 172              var match = search.match(/(\n  +)([*-] ?)$/);
 173              if(match){
 174                  var spaces = match[1].length-1;
 175  
 176                  if(spaces > 3){ // unindent one level
 177                      this.value = this.value.substr(0,linestart)+
 178                                   this.value.substr(linestart+2);
 179                      selection.start = selection.start - 2;
 180                      selection.end   = selection.start;
 181                  }else{ // delete list point
 182                      this.value = this.value.substr(0,linestart)+
 183                                   this.value.substr(selection.start);
 184                      selection.start = linestart;
 185                      selection.end   = linestart;
 186                  }
 187                  DWsetSelection(selection);
 188                  e.preventDefault(); // prevent backspace
 189                  return false;
 190              }
 191          }else if(e.keyCode == 32){ // Space
 192              // intend list item
 193              var match = search.match(/(\n  +)([*-] )$/);
 194              if(match){
 195                  this.value = this.value.substr(0,linestart)+'  '+
 196                               this.value.substr(linestart);
 197                  selection.start = selection.start + 2;
 198                  selection.end   = selection.start;
 199                  DWsetSelection(selection);
 200                  e.preventDefault(); // prevent space
 201                  return false;
 202              }
 203          }
 204      }
 205  
 206  
 207  };
 208  
 209  jQuery(dw_editor.init);