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