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