1// used to identify pickers 2var pickercounter=0; 3 4/** 5 * Create a toolbar 6 * 7 * @param string tbid ID of the element where to insert the toolbar 8 * @param string edid ID of the editor textarea 9 * @param array tb Associative array defining the buttons 10 * @param bool allowblock Allow buttons creating multiline content 11 * @author Andreas Gohr <andi@splitbrain.org> 12 */ 13function initToolbar(tbid,edid,tb, allowblock){ 14 var $toolbar, $edit; 15 if (typeof tbid == 'string') { 16 $toolbar = jQuery('#' + tbid); 17 } else { 18 $toolbar = jQuery(tbid); 19 } 20 21 $edit = jQuery('#' + edid); 22 23 if ($toolbar.length == 0 || $edit.length == 0 || $edit.attr('readOnly')) { 24 return; 25 } 26 27 if (typeof allowblock === 'undefined') { 28 allowblock = true; 29 } 30 31 //empty the toolbar area: 32 $toolbar.html(''); 33 34 jQuery.each(tb, function (k, val) { 35 if (!tb.hasOwnProperty(k) || (!allowblock && val.block === true)) { 36 return; 37 } 38 var actionFunc, $btn; 39 40 // create new button (jQuery object) 41 $btn = jQuery(createToolButton(val.icon, val.title, val.key, val.id, 42 val['class'])); 43 44 // type is a tb function -> assign it as onclick 45 actionFunc = 'tb_'+val.type; 46 if( jQuery.isFunction(window[actionFunc]) ){ 47 $btn.on('click', bind(window[actionFunc],$btn,val,edid) ); 48 $toolbar.append($btn); 49 return; 50 } 51 52 // type is a init function -> execute it 53 actionFunc = 'addBtnAction'+val.type.charAt(0).toUpperCase()+val.type.substring(1); 54 if( jQuery.isFunction(window[actionFunc]) ){ 55 var pickerid = window[actionFunc]($btn, val, edid); 56 if(pickerid !== ''){ 57 $toolbar.append($btn); 58 $toolbar.append(jQuery('#'+pickerid)); 59 $btn.attr('aria-controls', pickerid); 60 if (actionFunc === 'addBtnActionPicker') { 61 $btn.attr('aria-haspopup', 'true'); 62 } 63 } 64 return; 65 } 66 67 alert('unknown toolbar type: '+val.type+' '+actionFunc); 68 }); 69} 70 71/** 72 * Button action for format buttons 73 * 74 * @param DOMElement btn Button element to add the action to 75 * @param array props Associative array of button properties 76 * @param string edid ID of the editor textarea 77 * @author Gabriel Birke <birke@d-scribe.de> 78 * @author Andreas Gohr <andi@splitbrain.org> 79 */ 80function tb_format(btn, props, edid) { 81 var sample = props.sample || props.title; 82 insertTags(edid, 83 fixtxt(props.open), 84 fixtxt(props.close), 85 fixtxt(sample)); 86 pickerClose(); 87 return false; 88} 89 90/** 91 * Button action for format buttons 92 * 93 * This works exactly as tb_format() except that, if multiple lines 94 * are selected, each line will be formatted seperately 95 * 96 * @param DOMElement btn Button element to add the action to 97 * @param array props Associative array of button properties 98 * @param string edid ID of the editor textarea 99 * @author Gabriel Birke <birke@d-scribe.de> 100 * @author Andreas Gohr <andi@splitbrain.org> 101 */ 102function tb_formatln(btn, props, edid) { 103 var sample = props.sample || props.title, 104 opts, 105 selection = DWgetSelection(jQuery('#'+edid)[0]); 106 107 sample = fixtxt(sample); 108 props.open = fixtxt(props.open); 109 props.close = fixtxt(props.close); 110 111 // is something selected? 112 if(selection.getLength()){ 113 sample = selection.getText(); 114 opts = {nosel: true}; 115 }else{ 116 opts = { 117 startofs: props.open.length, 118 endofs: props.close.length 119 }; 120 } 121 122 sample = sample.split("\n").join(props.close+"\n"+props.open); 123 sample = props.open+sample+props.close; 124 125 pasteText(selection,sample,opts); 126 127 pickerClose(); 128 return false; 129} 130 131/** 132 * Button action for insert buttons 133 * 134 * @param DOMElement btn Button element to add the action to 135 * @param array props Associative array of button properties 136 * @param string edid ID of the editor textarea 137 * @author Gabriel Birke <birke@d-scribe.de> 138 * @author Andreas Gohr <andi@splitbrain.org> 139 */ 140function tb_insert(btn, props, edid) { 141 insertAtCarret(edid,fixtxt(props.insert)); 142 pickerClose(); 143 return false; 144} 145 146/** 147 * Button action for the media popup 148 * 149 * @param DOMElement btn Button element to add the action to 150 * @param array props Associative array of button properties 151 * @param string edid ID of the editor textarea 152 * @author Andreas Gohr <andi@splitbrain.org> 153 */ 154function tb_mediapopup(btn, props, edid) { 155 window.open( 156 DOKU_BASE+props.url+encodeURIComponent(NS)+'&edid='+encodeURIComponent(edid), 157 props.name, 158 props.options); 159 return false; 160} 161 162/** 163 * Button action for automatic headlines 164 * 165 * Insert a new headline based on the current section level 166 * 167 * @param DOMElement btn Button element to add the action to 168 * @param array props Associative array of button properties 169 * @param string edid ID of the editor textarea 170 * @author Andreas Gohr <andi@splitbrain.org> 171 */ 172function tb_autohead(btn, props, edid){ 173 var lvl = currentHeadlineLevel(edid), 174 tags; 175 176 // determine new level 177 lvl += props.mod; 178 if(lvl < 1) lvl = 1; 179 if(lvl > 5) lvl = 5; 180 181 tags = (new Array(8 - lvl)).join('='); 182 insertTags(edid, tags+' ', ' '+tags+"\n", props.text); 183 pickerClose(); 184 return false; 185} 186 187 188/** 189 * Add button action for picker buttons and create picker element 190 * 191 * @param jQuery btn Button element to add the action to 192 * @param array props Associative array of button properties 193 * @param string edid ID of the editor textarea 194 * @return boolean If button should be appended 195 * @author Gabriel Birke <birke@d-scribe.de> 196 */ 197function addBtnActionPicker($btn, props, edid) { 198 var pickerid = 'picker'+(pickercounter++); 199 var picker = createPicker(pickerid, props, edid); 200 jQuery(picker).attr('aria-hidden', 'true'); 201 202 $btn.click( 203 function(e) { 204 pickerToggle(pickerid,$btn); 205 e.preventDefault(); 206 return ''; 207 } 208 ); 209 210 return pickerid; 211} 212 213/** 214 * Add button action for the link wizard button 215 * 216 * @param DOMElement btn Button element to add the action to 217 * @param array props Associative array of button properties 218 * @param string edid ID of the editor textarea 219 * @return boolean If button should be appended 220 * @author Andreas Gohr <gohr@cosmocode.de> 221 */ 222function addBtnActionLinkwiz($btn, props, edid) { 223 dw_linkwiz.init(jQuery('#'+edid)); 224 jQuery($btn).click(function(e){ 225 dw_linkwiz.val = props; 226 dw_linkwiz.toggle(); 227 e.preventDefault(); 228 return ''; 229 }); 230 return 'link__wiz'; 231} 232 233 234/** 235 * Show/Hide a previously created picker window 236 * 237 * @author Andreas Gohr <andi@splitbrain.org> 238 */ 239function pickerToggle(pickerid,$btn){ 240 var $picker = jQuery('#' + pickerid), 241 pos = $btn.offset(); 242 if ($picker.hasClass('a11y')) { 243 $picker.removeClass('a11y').attr('aria-hidden', 'false'); 244 } else { 245 $picker.addClass('a11y').attr('aria-hidden', 'true'); 246 } 247 var picker_left = pos.left + 3, 248 picker_width = $picker.width(), 249 window_width = jQuery(window).width(); 250 if (picker_width > 300) { 251 $picker.css("max-width", "300"); 252 picker_width = 300; 253 } 254 if ((picker_left + picker_width + 40) > window_width) { 255 picker_left = window_width - picker_width - 40; 256 } 257 if (picker_left < 0) { 258 picker_left = 0; 259 } 260 $picker.offset({left: picker_left, top: pos.top+$btn[0].offsetHeight+3}); 261} 262 263/** 264 * Close all open pickers 265 * 266 * @author Andreas Gohr <andi@splitbrain.org> 267 */ 268function pickerClose(){ 269 jQuery('.picker').addClass('a11y').attr('aria-hidden', 'true'); 270} 271 272 273/** 274 * Replaces \n with linebreaks 275 */ 276function fixtxt(str){ 277 return str.replace(/\\n/g,"\n"); 278} 279 280jQuery(function () { 281 initToolbar('tool__bar','wiki__text',toolbar); 282 jQuery('#tool__bar').attr('role', 'toolbar'); 283}); 284