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