1 2// used to identify pickers 3var pickercounter=0; 4 5/** 6 * Create a toolbar 7 * 8 * @param string tbid ID of the element where to insert the toolbar 9 * @param string edid ID of the editor textarea 10 * @param array tb Associative array defining the buttons 11 * @author Andreas Gohr <andi@splitbrain.org> 12 */ 13function initToolbar(tbid,edid,tb){ 14 var toolbar = $(tbid); 15 if(!toolbar) return; 16 var edit = $(edid); 17 if(!edit) return; 18 if(edit.readonly) return; 19 20 //empty the toolbar area: 21 toolbar.innerHTML=''; 22 23 var cnt = tb.length; 24 for(var i=0; i<cnt; i++){ 25 var actionFunc; 26 27 // create new button 28 var btn = createToolButton(tb[i]['icon'], 29 tb[i]['title'], 30 tb[i]['key']); 31 32 33 // type is a tb function -> assign it as onclick 34 actionFunc = 'tb_'+tb[i]['type']; 35 if( isFunction(window[actionFunc]) ){ 36 addEvent(btn,'click', function(func,btn, props, edid){ 37 return function(){ 38 window[func](btn, props, edid); 39 return false; 40 } 41 }(actionFunc,btn,tb[i],edid) ); 42 //above fixes the scope problem as descried at http://www.mennovanslooten.nl/blog/post/62 43 toolbar.appendChild(btn); 44 continue; 45 } 46 47 // type is a init function -> execute it 48 actionFunc = 'addBtnAction'+tb[i]['type'].charAt(0).toUpperCase()+tb[i]['type'].substring(1); 49 if( isFunction(window[actionFunc]) ){ 50 if(window[actionFunc](btn, tb[i], edid)){ 51 toolbar.appendChild(btn); 52 } 53 continue; 54 } 55 56 alert('unknown toolbar type: '+tb[i]['type']+' '+actionFunc); 57 } // end for 58 59} 60 61/** 62 * Button action for format buttons 63 * 64 * @param DOMElement btn Button element to add the action to 65 * @param array props Associative array of button properties 66 * @param string edid ID of the editor textarea 67 * @author Gabriel Birke <birke@d-scribe.de> 68 * @author Andreas Gohr <andi@splitbrain.org> 69 */ 70function tb_format(btn, props, edid) { 71 var sample = props['title']; 72 if(props['sample']){ 73 sample = props['sample']; 74 } 75 insertTags(edid, 76 fixtxt(props['open']), 77 fixtxt(props['close']), 78 fixtxt(sample)); 79 pickerClose(); 80 return false; 81} 82 83/** 84 * Button action for format buttons 85 * 86 * This works exactly as tb_format() except that, if multiple lines 87 * are selected, each line will be formatted seperately 88 * 89 * @param DOMElement btn Button element to add the action to 90 * @param array props Associative array of button properties 91 * @param string edid ID of the editor textarea 92 * @author Gabriel Birke <birke@d-scribe.de> 93 * @author Andreas Gohr <andi@splitbrain.org> 94 */ 95function tb_formatln(btn, props, edid) { 96 var sample = props['title']; 97 if(props['sample']){ 98 sample = props['sample']; 99 } 100 sample = fixtxt(sample); 101 102 props['open'] = fixtxt(props['open']); 103 props['close'] = fixtxt(props['close']); 104 105 // is something selected? 106 var opts; 107 var selection = getSelection($(edid)); 108 if(selection.getLength()){ 109 sample = selection.getText(); 110 opts = {nosel: true}; 111 }else{ 112 opts = { 113 startofs: props['open'].length, 114 endofs: props['close'].length 115 }; 116 } 117 118 sample = sample.split("\n").join(props['close']+"\n"+props['open']); 119 sample = props['open']+sample+props['close']; 120 121 pasteText(selection,sample,opts); 122 123 pickerClose(); 124 return false; 125} 126 127/** 128 * Button action for insert buttons 129 * 130 * @param DOMElement btn Button element to add the action to 131 * @param array props Associative array of button properties 132 * @param string edid ID of the editor textarea 133 * @author Gabriel Birke <birke@d-scribe.de> 134 * @author Andreas Gohr <andi@splitbrain.org> 135 */ 136function tb_insert(btn, props, edid) { 137 insertAtCarret(edid,fixtxt(props['insert'])); 138 pickerClose(); 139} 140 141 142/** 143 * Add button action for picker buttons and create picker element 144 * 145 * @param DOMElement btn Button element to add the action to 146 * @param array props Associative array of button properties 147 * @param string edid ID of the editor textarea 148 * @return boolean If button should be appended 149 * @author Gabriel Birke <birke@d-scribe.de> 150 */ 151function addBtnActionPicker(btn, props, edid) { 152 var pickerid = 'picker'+(pickercounter++); 153 createPicker(pickerid, props, edid); 154 addEvent(btn,'click',function(){ 155 pickerToggle(pickerid,btn); 156 return false; 157 }); 158 return true; 159} 160 161function addBtnActionLinkwiz(btn, props, edid) { 162 linkwiz.init($(edid)); 163 addEvent(btn,'click',function(){ 164 linkwiz.toggle(); 165 return false; 166 }); 167 return true; 168} 169 170 171/** 172 * Show/Hide a previosly created picker window 173 * 174 * @author Andreas Gohr <andi@splitbrain.org> 175 */ 176function pickerToggle(pickerid,btn){ 177 var picker = $(pickerid); 178 if(picker.style.display == 'none'){ 179 var x = findPosX(btn); 180 var y = findPosY(btn); 181 picker.style.display = 'block'; 182 picker.style.left = (x+3)+'px'; 183 picker.style.top = (y+btn.offsetHeight+3)+'px'; 184 }else{ 185 picker.style.display = 'none'; 186 } 187} 188 189/** 190 * Close all open pickers 191 * 192 * @author Andreas Gohr <andi@splitbrain.org> 193 */ 194function pickerClose(){ 195 var pobjs = getElementsByClass('picker'); 196 for(var i=0; i<pobjs.length; i++){ 197 pobjs[i].style.display = 'none'; 198 } 199} 200 201 202/** 203 * Replaces \n with linebreaks 204 */ 205function fixtxt(str){ 206 return str.replace(/\\n/g,"\n"); 207} 208 209