1/** 2 * selection prototype 3 * 4 * Object that capsulates the selection in a textarea. Returned by getSelection. 5 */ 6function selection_class(){ 7 this.start = 0; 8 this.end = 0; 9 this.obj = null; 10 this.rangeCopy = null; 11 12 this.getLength = function(){ 13 return this.end - this.start; 14 }; 15 16 this.getText = function(){ 17 if(!this.obj) return ''; 18 return this.obj.value.substring(this.start,this.end); 19 } 20} 21 22/** 23 * Get current selection/cursor position in a given textArea 24 * 25 * @link http://groups.drupal.org/node/1210 26 * @returns object - a selection object 27 */ 28function getSelection(textArea) { 29 var sel = new selection_class(); 30 31 sel.obj = textArea; 32 sel.start = textArea.value.length; 33 sel.end = textArea.value.length; 34 35 textArea.focus(); 36 if(document.getSelection) { // Mozilla et al. 37 sel.start = textArea.selectionStart; 38 sel.end = textArea.selectionEnd; 39 } else if(document.selection) { // MSIE 40 // The current selection 41 var range = document.selection.createRange(); 42 sel.rangeCopy = range.duplicate(); 43 // Select all text 44 sel.rangeCopy.moveToElementText(textArea); 45 // Now move 'dummy' end point to end point of original range 46 sel.rangeCopy.setEndPoint( 'EndToEnd', range ); 47 // Now we can calculate start and end points 48 sel.start = sel.rangeCopy.text.length - range.text.length; 49 sel.end = sel.start + range.text.length; 50 } 51 return sel; 52} 53 54/** 55 * Set the selection 56 * 57 * You need to get a selection object via getSelection() first, then modify the 58 * start and end properties and pass it back to this function. 59 * 60 * @link http://groups.drupal.org/node/1210 61 * @param object selection - a selection object as returned by getSelection() 62 */ 63function setSelection(selection){ 64 if(document.getSelection){ // FF 65 // what a pleasure in FF ;) 66 selection.obj.setSelectionRange(selection.start,selection.end); 67 } else if(document.selection) { // IE 68 // count number of newlines in str to work around stupid IE selection bug 69 var countNL = function(str) { 70 var m = str.split("\n"); 71 if (!m || !m.length) return 0; 72 return m.length-1; 73 }; 74 var fix = countNL(selection.obj.value.substring(0,selection.start)); 75 76 selection.rangeCopy.collapse(true); 77 selection.rangeCopy.moveStart('character',selection.start - fix); 78 selection.rangeCopy.moveEnd('character',selection.end - selection.start); 79 selection.rangeCopy.select(); 80 } 81} 82 83/** 84 * Inserts the given text at the current cursor position or replaces the current 85 * selection 86 * 87 * @author Andreas Gohr <andi@splitbrain.org> 88 * @param string text - the new text to be pasted 89 * @param objct selecttion - selection object returned by getSelection 90 * @param int opts.startofs - number of charcters at the start to skip from new selection 91 * @param int opts.endofs - number of charcters at the end to skip from new selection 92 * @param bool opts.ofs - set tru if new text should not be selected 93 */ 94function pasteText(selection,text,opts){ 95 if(!opts) opts = {}; 96 // replace the content 97 selection.obj.value = 98 selection.obj.value.substring(0, selection.start) + text + 99 selection.obj.value.substring(selection.end, selection.obj.value.length); 100 101 // set new selection 102 selection.end = selection.start + text.length; 103 104 // modify the new selection if wanted 105 if(opts.startofs) selection.start += opts.startofs; 106 if(opts.endofs) selection.end -= opts.endofs; 107 108 // no selection wanted? set cursor to end position 109 if(opts.nosel) selection.start = selection.end; 110 111 setSelection(selection); 112} 113 114 115/** 116 * Format selection 117 * 118 * Apply tagOpen/tagClose to selection in textarea, use sampleText instead 119 * of selection if there is none. 120 * 121 * @author Andreas Gohr <andi@splitbrain.org> 122 */ 123function insertTags(textAreaID, tagOpen, tagClose, sampleText){ 124 var txtarea = document.getElementById(textAreaID); 125 126 var selection = getSelection(txtarea); 127 var text = selection.getText(); 128 129 // don't include trailing space in selection 130 if(text.charAt(text.length - 1) == ' '){ 131 selection.end--; 132 text = selection.getText(); 133 } 134 135 // nothing selected, use the sample text 136 if(!text) text = sampleText; 137 138 // surround with tags 139 text = tagOpen + text + tagClose; 140 141 // prepare options 142 var opts = { 143 startofs: tagOpen.length, 144 endofs: tagClose.length 145 }; 146 147 // do it 148 pasteText(selection,text,opts); 149} 150 151/** 152 * Wraps around pasteText() for backward compatibility 153 * 154 * @author Andreas Gohr <andi@splitbrain.org> 155 */ 156function insertAtCarret(textAreaID, text){ 157 var txtarea = document.getElementById(textAreaID); 158 var selection = getSelection(txtarea); 159 pasteText(selection,text,{nosel: true}); 160} 161 162