1/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, strict: true, newcap: true, immed: true */ 2/*global jQuery, window, DOKU_BASE*/ 3"use strict"; 4 5// * refactor once the jQuery port is over ;) 6 7/** 8 * JavaScript functionality for the media management popup 9 * 10 * @author Andreas Gohr <andi@splitbrain.org> 11 * @author Pierre Spring <pierre.spring@caillou.ch> 12 */ 13(function ($) { 14 var toggle, list, prepare_content, insert, confirmattach, attachoptions, initpopup, updatehide, setalign, setsize, inSet, outSet, media_manager; 15 16 var media_manager = { 17 keepopen: false, 18 hide: false, 19 align: false, 20 popup: false, 21 display: false, 22 link: false, 23 size: false, 24 ext: false, 25 }; 26 27 28 29 30 /** 31 * build the popup window 32 * 33 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 34 */ 35 initpopup = function() { 36 var popup; 37 38 popup = document.createElement('div'); 39 popup.setAttribute('id','media__popup'); 40 popup.style.display = "none"; 41 42 var root = document.getElementById('media__manager'); 43 if (root === null) return; 44 root.appendChild(popup); 45 46 var headline = document.createElement('h1'); 47 headline.innerHTML = LANG.mediatitle; 48 var headlineimg = document.createElement('img'); 49 headlineimg.src = DOKU_BASE + 'lib/images/close.png'; 50 headlineimg.id = 'media__closeimg'; 51 $(headlineimg).click(function () {$(popup).hide()}); 52 headline.insertBefore(headlineimg, headline.firstChild); 53 popup.appendChild(headline); 54 $(popup).draggable({handle: headline}); 55 56 // link 57 var linkp = document.createElement('p'); 58 59 linkp.id = "media__linkstyle"; 60 if (media_manager.display == "2") { 61 linkp.style.display = "none"; 62 } 63 64 var linkl = document.createElement('label'); 65 linkl.innerHTML = LANG.mediatarget; 66 linkp.appendChild(linkl); 67 68 var linkbtns = ['lnk', 'direct', 'nolnk', 'displaylnk']; 69 for (var i = 0 ; i < linkbtns.length ; ++i) { 70 var linkbtn = document.createElement('button'); 71 linkbtn.className = 'button'; 72 linkbtn.id = "media__linkbtn" + (i+1); 73 linkbtn.title = LANG['media' + linkbtns[i]]; 74 linkbtn.style.borderStyle = 'outset'; 75 $(linkbtn).click(function (event) { return setlink(event,this); }); 76 77 var linkimg = document.createElement('img'); 78 linkimg.src = DOKU_BASE + 'lib/images/media_link_' + linkbtns[i] + '.png'; 79 80 linkbtn.appendChild(linkimg); 81 linkp.appendChild(linkbtn); 82 } 83 84 popup.appendChild(linkp); 85 86 // align 87 88 var alignp = document.createElement('p'); 89 var alignl = document.createElement('label'); 90 91 alignp.appendChild(alignl); 92 alignp.id = 'media__align'; 93 if (media_manager.display == "2") { 94 alignp.style.display = "none"; 95 } 96 alignl.innerHTML = LANG['mediaalign']; 97 98 var alignbtns = ['noalign', 'left', 'center', 'right']; 99 for (var n = 0 ; n < alignbtns.length ; ++n) { 100 var alignbtn = document.createElement('button'); 101 var alignimg = document.createElement('img'); 102 alignimg.src = DOKU_BASE + 'lib/images/media_align_' + alignbtns[n] + '.png'; 103 104 alignbtn.id = "media__alignbtn" + (n+1); 105 alignbtn.title = LANG['media' + alignbtns[n]]; 106 alignbtn.className = 'button'; 107 alignbtn.appendChild(alignimg); 108 alignbtn.style.borderStyle = 'outset'; 109 $(alignbtn).click(function (event) { return setalign(event,this); }); 110 111 alignp.appendChild(alignbtn); 112 } 113 114 popup.appendChild(alignp); 115 116 // size 117 118 var sizep = document.createElement('p'); 119 var sizel = document.createElement('label'); 120 121 sizep.id = 'media__size'; 122 if (media_manager.display == "2") { 123 sizep.style.display = "none"; 124 } 125 sizep.appendChild(sizel); 126 sizel.innerHTML = LANG['mediasize']; 127 128 var sizebtns = ['small', 'medium', 'large', 'original']; 129 for (var size = 0 ; size < sizebtns.length ; ++size) { 130 var sizebtn = document.createElement('button'); 131 var sizeimg = document.createElement('img'); 132 133 sizep.appendChild(sizebtn); 134 sizeimg.src = DOKU_BASE + 'lib/images/media_size_' + sizebtns[size] + '.png'; 135 136 sizebtn.className = 'button'; 137 sizebtn.appendChild(sizeimg); 138 sizebtn.id = 'media__sizebtn' + (size + 1); 139 sizebtn.title = LANG['media' + sizebtns[size]]; 140 sizebtn.style.borderStyle = 'outset'; 141 $(sizebtn).click(function (event) { return setsize(event,this); }); 142 } 143 144 popup.appendChild(sizep); 145 146 // send and close button 147 148 var btnp = document.createElement('p'); 149 popup.appendChild(btnp); 150 btnp.setAttribute('class','btnlbl'); 151 152 var btn = document.createElement('input'); 153 btn.type = 'button'; 154 btn.id = 'media__sendbtn'; 155 btn.setAttribute('class','button'); 156 btn.value = LANG['mediainsert']; 157 btnp.appendChild(btn); 158 }; 159 160 /** 161 * Insert the clicked image into the opener's textarea 162 * 163 * @author Andreas Gohr <andi@splitbrain.org> 164 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 165 * @author Pierre Spring <pierre.spring@caillou.ch> 166 */ 167 insert = function (id) { 168 var opts, optsstart, alignleft, alignright; 169 170 // set syntax options 171 $('#media__popup').hide(); 172 173 opts = ''; 174 optsstart = ''; 175 alignleft = ''; 176 alignright = ''; 177 178 if (media_manager.ext == 'img' || media_manager.ext == 'swf') { 179 180 if (media_manager.link == '4') { 181 opts = '?linkonly'; 182 } else { 183 184 if (media_manager.link == "3" && media_manager.ext == 'img') { 185 opts = '?nolink'; 186 optsstart = true; 187 } else if (media_manager.link == "2" && media_manager.ext == 'img') { 188 opts = '?direct'; 189 optsstart = true; 190 } 191 192 var s = parseInt(media_manager.size, 10); 193 194 if (s && s >= 1) { 195 opts += (optsstart)?'&':'?'; 196 if (s=="1") { 197 opts += '100'; 198 if (media_manager.ext == 'swf') { 199 opts += 'x62'; 200 } 201 } else if (s=="2") { 202 opts += '200'; 203 if (media_manager.ext == 'swf') { 204 opts += 'x123'; 205 } 206 } else if (s=="3"){ 207 opts += '300'; 208 if (media_manager.ext == 'swf') { 209 opts += 'x185'; 210 } 211 } 212 } 213 if (media_manager.align == '2') { 214 alignleft = ''; 215 alignright = ' '; 216 } 217 if (media_manager.align == '3') { 218 alignleft = ' '; 219 alignright = ' '; 220 } 221 if (media_manager.align == '4') { 222 alignleft = ' '; 223 alignright = ''; 224 } 225 } 226 } 227 var edid = String.prototype.match.call(document.location, /&edid=([^&]+)/); 228 edid = edid ? edid[1] : 'wiki__text'; 229 opener.insertTags(edid,'{{'+alignleft+id+opts+alignright+'|','}}',''); 230 231 if(!media_manager.keepopen) window.close(); 232 opener.focus(); 233 return false; 234 }; 235 236 /** 237 * Prefills the wikiname. 238 * 239 * @author Andreas Gohr <andi@splitbrain.org> 240 */ 241 suggest = function(){ 242 var file, name, text; 243 244 file = $(this); 245 name = $('#upload__name'); 246 if(!file.size() || !name.size()) return; 247 248 text = file.val(); 249 text = text.substr(text.lastIndexOf('/')+1); 250 text = text.substr(text.lastIndexOf('\\')+1); 251 name.val(text); 252 }; 253 254 /** 255 * Open or close a subtree using AJAX 256 * 257 * @author Andreas Gohr <andi@splitbrain.org> 258 * @author Pierre Spring <pierre.spring@caillou.ch> 259 */ 260 toggle = function (event) { 261 var clicky, listitem, sublist, link, ul; 262 263 event.preventDefault(); // TODO: really here? 264 265 var clicky = $(this); 266 var listitem = clicky.parent(); 267 268 // if already open, close by removing the sublist 269 sublist = listitem.find('ul').first(); 270 if(sublist.size()){ 271 sublist.remove(); // TODO: really? we could just hide it, right? 272 clicky.attr('src', DOKU_BASE + 'lib/images/plus.gif'); 273 return; 274 } 275 276 // get the enclosed link (is always the first one) 277 link = listitem.find('a').first(); 278 279 //prepare the new ul 280 ul = $('<ul/>'); 281 282 //fixme add classname here 283 284 $.post( 285 DOKU_BASE + 'lib/exe/ajax.php', 286 link.attr('search').substr(1) + '&call=medians', 287 function (data) { 288 ul.html(data); 289 listitem.append(ul); 290 }, 291 'html' 292 ); 293 294 clicky.attr('src', DOKU_BASE + 'lib/images/minus.gif'); 295 }; 296 297 /** 298 * list the content of a namespace using AJAX 299 * 300 * @author Andreas Gohr <andi@splitbrain.org> 301 * @author Pierre Spring <pierre.spring@caillou.ch> 302 */ 303 list = function (event) { 304 var link, content; 305 link = $(this); 306 307 event.preventDefault(); 308 309 cleanMsgArea(); 310 content = $('#media__content'); 311 content.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 312 313 // fetch the subtree 314 $.post( 315 DOKU_BASE + 'lib/exe/ajax.php', 316 link.attr('search').substr(1)+'&call=medialist', 317 function (data) { 318 content.html(data); 319 prepare_content(content); 320 updatehide(); 321 }, 322 'html' 323 ); 324 325 }; 326 327 prepare_content = function (content) { 328 // hide syntax example 329 content.find('div.example:visible').hide(); 330 initFlashUpload(); 331 }; 332 333 /** 334 * shows the popup for a image link 335 */ 336 select = function(event){ 337 var link, id, dot, ext; 338 339 event.preventDefault(); 340 341 link = $(this); 342 id = link.attr('name').substr(2); 343 344 if(!opener){ 345 // if we don't run in popup display example 346 // the id's are a bit wired and $('#ex_wiki_dokuwiki-128.png') will not be found 347 // by Sizzle (the CSS Selector Engine used by jQuery), 348 // hence the document.getElementById() call 349 $(document.getElementById('ex_'+id.replace(/:/g,'_').replace(/^_/,''))).toggle(); 350 return; 351 } 352 353 link = link[0]; 354 355 media_manager.ext = false; 356 dot = id.lastIndexOf("."); 357 358 if (-1 === dot) { 359 insert(id); 360 return; 361 } 362 363 ext = id.substr(dot); 364 365 if (ext != '.jpg' && ext != '.jpeg' && ext != '.png' && ext != '.gif' && ext != '.swf') { 366 insert(id); 367 return; 368 } 369 370 // remove old callback from the insert button and set the new one. 371 $('#media__sendbtn').unbind().click(function () {insert(id)}); 372 373 $('#media__popup').show() 374 .css('left', event.pageX + 'px') 375 .css('top', event.pageY + 'px'); 376 377 $('#media__popup button.button').each(function (index, element) { outSet(element) } ); 378 379 380 if (ext == '.swf') { 381 media_manager.ext = 'swf'; 382 383 // disable display buttons for detail and linked image 384 $('#media__linkbtn1').hide(); 385 $('#media__linkbtn2').hide(); 386 387 // set the link button to default 388 if (media_manager.link != false) { 389 if ( media_manager.link == '2' || media_manager.link == '1') { 390 inSet('media__linkbtn3'); 391 media_manager.link = '3'; 392 DokuCookie.setValue('link','3'); 393 } else { 394 inSet('media__linkbtn'+media_manager.link); 395 } 396 } else if (DokuCookie.getValue('link')) { 397 if ( DokuCookie.getValue('link') == '2' || DokuCookie.getValue('link') == '1') { 398 // this options are not availible 399 inSet('media__linkbtn3'); 400 media_manager.link = '3'; 401 DokuCookie.setValue('link','3'); 402 } else { 403 inSet('media__linkbtn'+DokuCookie.getValue('link')); 404 media_manager.link = DokuCookie.getValue('link'); 405 } 406 } else { 407 // default case 408 media_manager.link = '3'; 409 inSet('media__linkbtn3'); 410 DokuCookie.setValue('link','3'); 411 } 412 413 // disable button for original size 414 $('#media__sizebtn4').hide(); 415 416 } else { 417 media_manager.ext = 'img'; 418 419 // ensure that the display buttons are there 420 $('#media__linkbtn1').show(); 421 $('#media__linkbtn2').show(); 422 $('#media__sizebtn4').show(); 423 424 // set the link button to default 425 if (DokuCookie.getValue('link')) { 426 media_manager.link = DokuCookie.getValue('link'); 427 } 428 if (media_manager.link == false) { 429 // default case 430 media_manager.link = '1'; 431 DokuCookie.setValue('link','1'); 432 } 433 inSet('media__linkbtn'+media_manager.link); 434 } 435 436 if (media_manager.link == '4') { 437 media_manager.align = false; 438 media_manager.size = false; 439 $('#media__align').hide(); 440 $('#media__size').hide(); 441 } else { 442 $('#media__align').show(); 443 $('#media__size').show(); 444 445 // set the align button to default 446 if (media_manager.align != false) { 447 inSet('media__alignbtn'+media_manager.align); 448 } else if (DokuCookie.getValue('align')) { 449 inSet('media__alignbtn'+DokuCookie.getValue('align')); 450 media_manager.align = DokuCookie.getValue('align'); 451 } else { 452 // default case 453 media_manager.align = '0'; 454 inSet('media__alignbtn0'); 455 DokuCookie.setValue('align','0'); 456 } 457 458 // set the size button to default 459 if (DokuCookie.getValue('size')) { 460 media_manager.size = DokuCookie.getValue('size'); 461 } 462 if (media_manager.size == false || (media_manager.size === '4' && ext === '.swf')) { 463 // default case 464 media_manager.size = '2'; 465 DokuCookie.setValue('size','2'); 466 } 467 inSet('media__sizebtn'+media_manager.size); 468 469 $('#media__sendbtn').focus(); 470 } 471 472 return; 473 }; 474 475 /** 476 * Deletion confirmation dialog to the delete buttons. 477 * 478 * @author Michael Klier <chi@chimeric.de> 479 * @author Pierre Spring <pierre.spring@caillou.ch> 480 */ 481 confirmattach = function(e){ 482 if(!confirm(LANG['del_confirm'] + "\n" + jQuery(this).attr('title'))) { 483 e.preventDefault(); 484 } 485 }; 486 487 /** 488 * Creates checkboxes for additional options 489 * 490 * @author Andreas Gohr <andi@splitbrain.org> 491 * @author Pierre Spring <pierre.spring@caillou.ch> 492 */ 493 attachoptions = function(){ 494 obj = $('#media__opts')[0]; 495 if(!obj) return; 496 497 // keep open 498 if(opener){ 499 var kobox = document.createElement('input'); 500 kobox.type = 'checkbox'; 501 kobox.id = 'media__keepopen'; 502 if(DokuCookie.getValue('keepopen')){ 503 kobox.checked = true; 504 kobox.defaultChecked = true; //IE wants this 505 media_manager.keepopen = true; 506 } 507 508 $(kobox).click( 509 function () { 510 toggleOption(this, 'keepopen'); 511 } 512 ); 513 514 var kolbl = document.createElement('label'); 515 kolbl.htmlFor = 'media__keepopen'; 516 kolbl.innerHTML = LANG['keepopen']; 517 518 var kobr = document.createElement('br'); 519 520 obj.appendChild(kobox); 521 obj.appendChild(kolbl); 522 obj.appendChild(kobr); 523 } 524 525 // hide details 526 var hdbox = document.createElement('input'); 527 hdbox.type = 'checkbox'; 528 hdbox.id = 'media__hide'; 529 if(DokuCookie.getValue('hide')){ 530 hdbox.checked = true; 531 hdbox.defaultChecked = true; //IE wants this 532 media_manager.hide = true; 533 } 534 $(hdbox).click( 535 function () { 536 toggleOption(this, 'hide'); 537 updatehide(); 538 } 539 ); 540 541 var hdlbl = document.createElement('label'); 542 hdlbl.htmlFor = 'media__hide'; 543 hdlbl.innerHTML = LANG['hidedetails']; 544 545 var hdbr = document.createElement('br'); 546 547 obj.appendChild(hdbox); 548 obj.appendChild(hdlbl); 549 obj.appendChild(hdbr); 550 updatehide(); 551 }; 552 553 /** 554 * Generalized toggler 555 * 556 * @author Pierre Spring <pierre.spring@caillou.ch> 557 */ 558 toggleOption = function (checkbox, variable) { 559 if (checkbox.checked) { 560 DokuCookie.setValue(variable, 1); 561 media_manager[variable] = true; 562 } else { 563 DokuCookie.setValue(variable, ''); 564 media_manager[variable] = false; 565 } 566 }; 567 568 initFlashUpload = function () { 569 var oform, oflash, title; 570 if(!hasFlash(8)) return; 571 572 oform = $('#dw__upload'); 573 oflash = $('#dw__flashupload'); 574 575 if(!oform.size() || !oflash.size()) return; 576 577 title = LANG['mu_btn']; 578 579 $('<img/>').attr('src', DOKU_BASE+'lib/images/multiupload.png') 580 .attr('title', title) 581 .attr('alt', title) 582 .css('cursor', 'pointer') 583 .click( 584 function () { 585 oform.hide(); 586 oflash.show(); 587 } 588 ) 589 .appendTo(oform); 590 }; 591 592 /** 593 * Sets the visibility of the image details accordingly to the 594 * chosen hide state 595 * 596 * @author Andreas Gohr <andi@splitbrain.org> 597 */ 598 updatehide = function(){ 599 var content = $('#media__content'); 600 if(0 === content.size()) { 601 return; 602 } 603 content.find('div.detail').each( 604 function (index, element) { 605 if(media_manager.hide){ 606 element.style.display = 'none'; 607 }else{ 608 element.style.display = ''; 609 } 610 } 611 612 ); 613 }; 614 615 /** 616 * set the align 617 * 618 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 619 */ 620 setalign = function(event,cb){ 621 622 var id = cb.id.substring(cb.id.length -1); 623 if(id){ 624 DokuCookie.setValue('align',id); 625 media_manager.align = id; 626 for (var i = 1; i<=4; i++) { 627 outSet("media__alignbtn" + i); 628 } 629 inSet("media__alignbtn"+id); 630 }else{ 631 DokuCookie.setValue('align',''); 632 media_manager.align = false; 633 } 634 }; 635 636 /** 637 * set the link type 638 * 639 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 640 */ 641 setlink = function(event,cb){ 642 var id = cb.id.substring(cb.id.length -1); 643 if(id){ 644 DokuCookie.setValue('link',id); 645 for (var i = 1; i<=4; i++) { 646 outSet("media__linkbtn"+i); 647 } 648 inSet("media__linkbtn"+id); 649 650 var size = $("#media__size"); 651 var align = $("#media__align"); 652 if (id != '4') { 653 size.show(); 654 align.show(); 655 if (media_manager.link == '4') { 656 media_manager.align = '1'; 657 DokuCookie.setValue('align', '1'); 658 inSet('media__alignbtn1'); 659 660 media_manager.size = '2'; 661 DokuCookie.setValue('size', '2'); 662 inSet('media__sizebtn2'); 663 } 664 665 } else { 666 size.hide(); 667 align.hide(); 668 } 669 media_manager.link = id; 670 }else{ 671 DokuCookie.setValue('link',''); 672 media_manager.link = false; 673 } 674 }; 675 676 /** 677 * set the image size 678 * 679 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 680 */ 681 setsize = function(event,cb){ 682 var id = cb.id.substring(cb.id.length -1); 683 if (id) { 684 DokuCookie.setValue('size',id); 685 media_manager.size = id; 686 for (var i = 1 ; i <=4 ; ++i) { 687 outSet("media__sizebtn" + i); 688 } 689 inSet("media__sizebtn"+id); 690 } else { 691 DokuCookie.setValue('size',''); 692 media_manager.width = false; 693 } 694 }; 695 696 /** 697 * sets the border to inset 698 */ 699 inSet = function(id) { 700 var ele = $('#' + id).css('border-style', 'inset'); 701 }; 702 703 /** 704 * sets the border to outset 705 */ 706 outSet = function(element) { 707 if ('string' === typeof element) { 708 element = '#' + element; 709 } 710 $(element).css('border-style', 'outset'); 711 }; 712 713 $(function () { 714 var content = $('#media__content'); 715 prepare_content(content); 716 717 attachoptions(); 718 initpopup(); 719 720 // add the action to autofill the "upload as" field 721 content.delegate('#upload__file', 'change', suggest) 722 // Attach the image selector action to all links 723 .delegate('a.select', 'click', select) 724 // Attach deletion confirmation dialog to the delete buttons 725 .delegate('#media__content a.btn_media_delete', 'click', confirmattach); 726 727 728 $('#media__tree').delegate('img', 'click', toggle) 729 .delegate('a', 'click', list); 730 }); 731}(jQuery));