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