1/** 2 * Some of these scripts were taken from wikipedia.org and were modified for DokuWiki 3 */ 4 5/** 6 * Some browser detection 7 */ 8var clientPC = navigator.userAgent.toLowerCase(); // Get client info 9var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1) 10 && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1)); 11var is_safari = ((clientPC.indexOf('AppleWebKit')!=-1) && (clientPC.indexOf('spoofer')==-1)); 12var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled )); 13if (clientPC.indexOf('opera')!=-1) { 14 var is_opera = true; 15 var is_opera_preseven = (window.opera && !document.childNodes); 16 var is_opera_seven = (window.opera && document.childNodes); 17} 18 19 20/** 21 * This function escapes some special chars 22 */ 23function escapeQuotes(text) { 24 var re=new RegExp("'","g"); 25 text=text.replace(re,"\\'"); 26 re=new RegExp('"',"g"); 27 text=text.replace(re,'"'); 28 re=new RegExp("\\n","g"); 29 text=text.replace(re,"\\n"); 30 return text; 31} 32 33/** 34 * Prints a animated gif to show the search is performed 35 * 36 * @author Andreas Gohr <andi@splitbrain.org> 37 */ 38function showLoadBar(){ 39 if(document.getElementById){ 40 document.write('<img src="'+DOKU_BASE+'lib/images/loading.gif" '+ 41 'width="150" height="12" id="loading" />'); 42 } 43} 44 45/** 46 * Disables the animated gif to show the search is done 47 * 48 * @author Andreas Gohr <andi@splitbrain.org> 49 */ 50function hideLoadBar(){ 51 if(document.getElementById){ 52 document.getElementById('loading').style.display="none"; 53 } 54} 55 56/** 57 * Checks if a summary was entered - if not the style is changed 58 * 59 * @author Andreas Gohr <andi@splitbrain.org> 60 */ 61function summaryCheck(){ 62 if(document.getElementById){ 63 var sum = document.getElementById('summary'); 64 if(sum.value == ''){ 65 sum.className='missing'; 66 }else{ 67 sum.className='edit'; 68 } 69 } 70} 71 72/** 73 * This function generates the actual toolbar buttons with localized text 74 * we use it to avoid creating the toolbar where javascript is not enabled 75 */ 76function formatButton(imageFile, speedTip, tagOpen, tagClose, sampleText, accessKey) { 77 speedTip=escapeQuotes(speedTip); 78 tagOpen=escapeQuotes(tagOpen); 79 tagClose=escapeQuotes(tagClose); 80 sampleText=escapeQuotes(sampleText); 81 82 document.write("<a "); 83 if(accessKey){ 84 document.write("accesskey=\""+accessKey+"\" "); 85 speedTip = speedTip+' [ALT+'+accessKey.toUpperCase()+']'; 86 } 87 document.write("href=\"javascript:insertTags"); 88 document.write("('"+tagOpen+"','"+tagClose+"','"+sampleText+"');\">"); 89 90 document.write("<img width=\"24\" height=\"24\" src=\""+ 91 DOKU_BASE+'lib/images/toolbar/'+imageFile+"\" border=\"0\" alt=\""+ 92 speedTip+"\" title=\""+speedTip+"\">"); 93 document.write("</a>"); 94 return; 95} 96 97/** 98 * This function generates the actual toolbar buttons with localized text 99 * we use it to avoid creating the toolbar where javascript is not enabled 100 */ 101function insertButton(imageFile, speedTip, value, accessKey) { 102 speedTip=escapeQuotes(speedTip); 103 value=escapeQuotes(value); 104 105 document.write("<a "); 106 if(accessKey){ 107 document.write("accesskey=\""+accessKey+"\" "); 108 speedTip = speedTip+' [ALT+'+accessKey.toUpperCase()+']'; 109 } 110 document.write("href=\"javascript:insertAtCarret"); 111 document.write("(document.editform.wikitext,'"+value+"');\">"); 112 113 document.write("<img width=\"24\" height=\"24\" src=\""+ 114 DOKU_BASE+'lib/images/toolbar/'+imageFile+"\" border=\"0\" alt=\""+ 115 speedTip+"\" title=\""+speedTip+"\">"); 116 document.write("</a>"); 117 return; 118} 119 120/** 121 * This adds a button for the MediaSelection Popup 122 */ 123function mediaButton(imageFile, speedTip, accessKey, namespace) { 124 speedTip=escapeQuotes(speedTip); 125 document.write("<a "); 126 if(accessKey){ 127 document.write("accesskey=\""+accessKey+"\" "); 128 } 129 document.write("href=\"javascript:void(window.open('"+DOKU_BASE+"lib/exe/media.php?ns="+ 130 namespace+"','mediaselect','width=600,height=320,left=70,top=50,scrollbars=yes,resizable=yes'));\">"); 131 document.write("<img width=\"24\" height=\"24\" src=\""+ 132 DOKU_BASE+'lib/images/toolbar/'+imageFile+"\" border=\"0\" alt=\""+ 133 speedTip+"\" title=\""+speedTip+"\">"); 134 document.write("</a>"); 135 return; 136} 137 138/** 139 * apply tagOpen/tagClose to selection in textarea, use sampleText instead 140 * of selection if there is none copied and adapted from phpBB 141 * 142 * @author phpBB development team 143 * @author MediaWiki development team 144 * @author Andreas Gohr <andi@splitbrain.org> 145 * @author Jim Raynor <jim_raynor@web.de> 146 */ 147function insertTags(tagOpen, tagClose, sampleText) { 148 var txtarea = document.editform.wikitext; 149 // IE 150 if(document.selection && !is_gecko) { 151 var theSelection = document.selection.createRange().text; 152 var replaced = true; 153 if(!theSelection){ 154 replaced = false; 155 theSelection=sampleText; 156 } 157 txtarea.focus(); 158 159 // This has change 160 text = theSelection; 161 if(theSelection.charAt(theSelection.length - 1) == " "){// exclude ending space char, if any 162 theSelection = theSelection.substring(0, theSelection.length - 1); 163 r = document.selection.createRange(); 164 r.text = tagOpen + theSelection + tagClose + " "; 165 } else { 166 r = document.selection.createRange(); 167 r.text = tagOpen + theSelection + tagClose; 168 } 169 if(!replaced){ 170 r.moveStart('character',-text.length-tagClose.length); 171 r.moveEnd('character',-tagClose.length); 172 } 173 r.select(); 174 // Mozilla 175 } else if(txtarea.selectionStart || txtarea.selectionStart == '0') { 176 var replaced = false; 177 var startPos = txtarea.selectionStart; 178 var endPos = txtarea.selectionEnd; 179 if(endPos - startPos) replaced = true; 180 var scrollTop=txtarea.scrollTop; 181 var myText = (txtarea.value).substring(startPos, endPos); 182 if(!myText) { myText=sampleText;} 183 if(myText.charAt(myText.length - 1) == " "){ // exclude ending space char, if any 184 subst = tagOpen + myText.substring(0, (myText.length - 1)) + tagClose + " "; 185 } else { 186 subst = tagOpen + myText + tagClose; 187 } 188 txtarea.value = txtarea.value.substring(0, startPos) + subst + 189 txtarea.value.substring(endPos, txtarea.value.length); 190 txtarea.focus(); 191 192 //set new selection 193 if(replaced){ 194 var cPos=startPos+(tagOpen.length+myText.length+tagClose.length); 195 txtarea.selectionStart=cPos; 196 txtarea.selectionEnd=cPos; 197 }else{ 198 txtarea.selectionStart=startPos+tagOpen.length; 199 txtarea.selectionEnd=startPos+tagOpen.length+myText.length; 200 } 201 txtarea.scrollTop=scrollTop; 202 // All others 203 } else { 204 var copy_alertText=alertText; 205 var re1=new RegExp("\\$1","g"); 206 var re2=new RegExp("\\$2","g"); 207 copy_alertText=copy_alertText.replace(re1,sampleText); 208 copy_alertText=copy_alertText.replace(re2,tagOpen+sampleText+tagClose); 209 var text; 210 if (sampleText) { 211 text=prompt(copy_alertText); 212 } else { 213 text=""; 214 } 215 if(!text) { text=sampleText;} 216 text=tagOpen+text+tagClose; 217 //append to the end 218 txtarea.value += "\n"+text; 219 220 // in Safari this causes scrolling 221 if(!is_safari) { 222 txtarea.focus(); 223 } 224 225 } 226 // reposition cursor if possible 227 if (txtarea.createTextRange) txtarea.caretPos = document.selection.createRange().duplicate(); 228} 229 230 231/* 232 * Insert the selected filename and close the window 233 * 234 * @see http://www.alexking.org/index.php?content=software/javascript/content.php 235 */ 236function mediaSelect(file){ 237 insertAtCarret(opener.document.editform.wikitext,'{{'+file+'}}'); 238 window.close(); 239} 240 241/* 242 * Insert the given value at the current cursor position 243 * 244 * @see http://www.alexking.org/index.php?content=software/javascript/content.php 245 */ 246function insertAtCarret(field,value){ 247 //IE support 248 if (document.selection) { 249 field.focus(); 250 if(opener == null){ 251 sel = document.selection.createRange(); 252 }else{ 253 sel = opener.document.selection.createRange(); 254 } 255 sel.text = value; 256 //MOZILLA/NETSCAPE support 257 }else if (field.selectionStart || field.selectionStart == '0') { 258 var startPos = field.selectionStart; 259 var endPos = field.selectionEnd; 260 var scrollTop = field.scrollTop; 261 field.value = field.value.substring(0, startPos) 262 + value 263 + field.value.substring(endPos, field.value.length); 264 265 field.focus(); 266 var cPos=startPos+(value.length); 267 field.selectionStart=cPos; 268 field.selectionEnd=cPos; 269 field.scrollTop=scrollTop; 270 } else { 271 field.value += "\n"+value; 272 } 273 // reposition cursor if possible 274 if (field.createTextRange) field.caretPos = document.selection.createRange().duplicate(); 275} 276 277/** 278 * For the upload Dialog. Prefills the wikiname. 279 */ 280function suggestWikiname(){ 281 var file = document.upload.upload.value; 282 283 file = file.substr(file.lastIndexOf('/')+1); 284 file = file.substr(file.lastIndexOf('\\')+1); 285 286 document.upload.id.value = file; 287} 288 289/** 290 * This prints the switch to toggle the Table of Contents 291 */ 292function showTocToggle(showtxt,hidetxt) { 293 if(document.getElementById) { 294 show = '<img src="'+DOKU_BASE+'lib/images/arrow_down.gif" alt="'+showtxt+'">'; 295 hide = '<img src="'+DOKU_BASE+'lib/images/arrow_up.gif" alt="'+hidetxt+'">'; 296 297 document.writeln('<div class=\'toctoggle\'><a href="javascript:toggleToc()" class="toc">' + 298 '<span id="showlink" style="display:none;">' + show + '</span>' + 299 '<span id="hidelink">' + hide + '</span>' 300 + '</a></div>'); 301 } 302} 303 304/** 305 * This toggles the visibility of the Table of Contents 306 */ 307function toggleToc() { 308 var toc = document.getElementById('tocinside'); 309 var showlink=document.getElementById('showlink'); 310 var hidelink=document.getElementById('hidelink'); 311 if(toc.style.display == 'none') { 312 toc.style.display = tocWas; 313 hidelink.style.display=''; 314 showlink.style.display='none'; 315 } else { 316 tocWas = toc.style.display; 317 toc.style.display = 'none'; 318 hidelink.style.display='none'; 319 showlink.style.display=''; 320 321 } 322} 323 324/** 325 * Sizecontrol inspired by TikiWiki. This displays the buttons. 326 */ 327function showSizeCtl(){ 328 if(document.getElementById) { 329 var textarea = document.getElementById('wikitext'); 330 var hgt = getCookie('DokuWikisizeCtl'); 331 if(hgt == null){ 332 textarea.style.height = '300px'; 333 }else{ 334 textarea.style.height = hgt; 335 } 336 document.writeln('<a href="javascript:sizeCtl(100)"><img src="'+DOKU_BASE+'lib/images/larger.gif" width="20" height="20" border="0"></a>'); 337 document.writeln('<a href="javascript:sizeCtl(-100)"><img src="'+DOKU_BASE+'lib/images/smaller.gif" width="20" height="20" border="0"></a>'); 338 } 339} 340 341/** 342 * This sets the vertical size of the editbox 343 */ 344function sizeCtl(val){ 345 var textarea = document.getElementById('wikitext'); 346 var height = parseInt(textarea.style.height.substr(0,textarea.style.height.length-2)); 347 height += val; 348 textarea.style.height = height+'px'; 349 350 var now = new Date(); 351 fixDate(now); 352 now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); //expire in a year 353 setCookie('DokuWikisizeCtl',textarea.style.height,now); 354} 355 356 357/** 358 * global var used for not saved yet warning 359 */ 360var textChanged = false; 361 362function svchk(){ 363 if(textChanged){ 364 return confirm(notSavedYet); 365 }else{ 366 return true; 367 } 368} 369 370/** 371 * global variable for the locktimer 372 */ 373var locktimerID; 374 375/** 376 * This starts a timer to remind the user of an expiring lock 377 * Accepts the delay in seconds and a text to display. 378 */ 379function init_locktimer(delay,txt){ 380 txt = escapeQuotes(txt); 381 locktimerID = self.setTimeout("locktimer('"+txt+"')", delay*1000); 382} 383 384/** 385 * This stops the timer and displays a message about the expiring lock 386 */ 387function locktimer(txt){ 388 clearTimeout(locktimerID); 389 alert(txt); 390} 391 392/* 393 * This sets a cookie by JavaScript 394 * 395 * @see http://www.webreference.com/js/column8/functions.html 396 */ 397function setCookie(name, value, expires, path, domain, secure) { 398 var curCookie = name + "=" + escape(value) + 399 ((expires) ? "; expires=" + expires.toGMTString() : "") + 400 ((path) ? "; path=" + path : "") + 401 ((domain) ? "; domain=" + domain : "") + 402 ((secure) ? "; secure" : ""); 403 document.cookie = curCookie; 404} 405 406/* 407 * This reads a cookie by JavaScript 408 * 409 * @see http://www.webreference.com/js/column8/functions.html 410 */ 411function getCookie(name) { 412 var dc = document.cookie; 413 var prefix = name + "="; 414 var begin = dc.indexOf("; " + prefix); 415 if (begin == -1) { 416 begin = dc.indexOf(prefix); 417 if (begin != 0) return null; 418 } else 419 begin += 2; 420 var end = document.cookie.indexOf(";", begin); 421 if (end == -1) 422 end = dc.length; 423 return unescape(dc.substring(begin + prefix.length, end)); 424} 425 426/* 427 * This is needed for the cookie functions 428 * 429 * @see http://www.webreference.com/js/column8/functions.html 430 */ 431function fixDate(date) { 432 var base = new Date(0); 433 var skew = base.getTime(); 434 if (skew > 0) 435 date.setTime(date.getTime() - skew); 436} 437 438/* 439 * This enables/disables checkboxes for acl-administration 440 * 441 * @author Frank Schubert <frank@schokilade.de> 442 */ 443function checkAclLevel(){ 444 if(document.getElementById) { 445 var scope = document.getElementById('acl_scope').value; 446 447 //check for namespace 448 if( (scope.indexOf(":*") > 0) || (scope == "*") ){ 449 document.getElementsByName('acl_checkbox[4]')[0].disabled=false; 450 document.getElementsByName('acl_checkbox[8]')[0].disabled=false; 451 }else{ 452 document.getElementsByName('acl_checkbox[4]')[0].checked=false; 453 document.getElementsByName('acl_checkbox[8]')[0].checked=false; 454 455 document.getElementsByName('acl_checkbox[4]')[0].disabled=true; 456 document.getElementsByName('acl_checkbox[8]')[0].disabled=true; 457 } 458 } 459} 460