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