1/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, strict: true, newcap: true, immed: true, sloppy: true, browser: true */ 2/*global jQuery, DOKU_BASE, LANG, bind, DokuCookie, opener, confirm*/ 3 4/** 5 * JavaScript functionality for the media management popup 6 * 7 * @author Andreas Gohr <andi@splitbrain.org> 8 * @author Pierre Spring <pierre.spring@caillou.ch> 9 */ 10 11var dw_mediamanager = { 12 keepopen: false, 13 hide: false, 14 popup: false, 15 display: false, 16 ext: false, 17 $popup: null, 18 19 // Image insertion opts 20 align: false, 21 link: false, 22 size: false, 23 forbidden_opts: {}, 24 25 init: function () { 26 var $content, $tree; 27 $content = jQuery('#media__content'); 28 $tree = jQuery('#media__tree'); 29 30 dw_mediamanager.prepare_content($content); 31 32 dw_mediamanager.attachoptions(); 33 dw_mediamanager.initpopup(); 34 35 // add the action to autofill the "upload as" field 36 $content.delegate('#upload__file', 'change', dw_mediamanager.suggest) 37 // Attach the image selector action to all links 38 .delegate('a.select', 'click', dw_mediamanager.select) 39 // Attach deletion confirmation dialog to the delete buttons 40 .delegate('#media__content a.btn_media_delete', 'click', 41 dw_mediamanager.confirmattach); 42 43 $tree.dw_tree({toggle_selector: 'img', 44 load_data: function (show_sublist, $clicky) { 45 // get the enclosed link (is always the first one) 46 var $link = $clicky.parent().find('div.li a.idx_dir'); 47 48 jQuery.post( 49 DOKU_BASE + 'lib/exe/ajax.php', 50 $link[0].search.substr(1) + '&call=medians', 51 show_sublist, 52 'html' 53 ); 54 }, 55 56 toggle_display: function ($clicky, opening) { 57 $clicky.attr('src', 58 DOKU_BASE + 'lib/images/' + 59 (opening ? 'minus' : 'plus') + '.gif'); 60 }}); 61 $tree.delegate('a', 'click', dw_mediamanager.list); 62 63 jQuery('#mediamanager__layout_list').delegate('#mediamanager__tabs_files a', 'click', dw_mediamanager.list) 64 .delegate('#mediamanager__tabs_list a', 'click', dw_mediamanager.list_view) 65 .delegate('#mediamanager__file_list a', 'click', dw_mediamanager.details) 66 .delegate('#dw__mediasearch', 'submit', dw_mediamanager.list) 67 .delegate('#upload__file', 'change', dw_mediamanager.suggest); 68 69 jQuery('#mediamanager__layout_detail').delegate('#mediamanager__tabs_details a', 'click', dw_mediamanager.details) 70 .delegate('#mediamanager__btn_update', 'submit', dw_mediamanager.list) 71 .delegate('#page__revisions', 'submit', dw_mediamanager.details) 72 .delegate('#page__revisions a', 'click', dw_mediamanager.details) 73 .delegate('#mediamanager__save_meta', 'submit', dw_mediamanager.details) 74 .delegate('#mediamanager__btn_delete', 'submit', dw_mediamanager.details) 75 .delegate('#mediamanager__btn_restore', 'submit', dw_mediamanager.details); 76 77 }, 78 79 /** 80 * build the popup window 81 * 82 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 83 */ 84 initpopup: function () { 85 var opts, $insp, $insbtn; 86 87 dw_mediamanager.$popup = jQuery(document.createElement('div')) 88 .attr('id', 'media__popup_content') 89 .dialog({autoOpen: false, width: 280, modal: true, 90 draggable: true, title: LANG.mediatitle, 91 resizable: false}); 92 93 opts = [{id: 'link', label: LANG.mediatarget, 94 btns: ['lnk', 'direct', 'nolnk', 'displaylnk']}, 95 {id: 'align', label: LANG.mediaalign, 96 btns: ['noalign', 'left', 'center', 'right']}, 97 {id: 'size', label: LANG.mediasize, 98 btns: ['small', 'medium', 'large', 'original']} 99 ]; 100 101 jQuery.each(opts, function (_, opt) { 102 var $p, $l; 103 $p = jQuery(document.createElement('p')) 104 .attr('id', 'media__' + opt.id); 105 106 if (dw_mediamanager.display === "2") { 107 $p.hide(); 108 } 109 110 $l = jQuery(document.createElement('label')) 111 .text(opt.label); 112 $p.append($l); 113 114 jQuery.each(opt.btns, function (i, text) { 115 var $btn, $img; 116 $btn = jQuery(document.createElement('button')) 117 .addClass('button') 118 .attr('id', "media__" + opt.id + "btn" + (i + 1)) 119 .attr('title', LANG['media' + text]) 120 .click(bind(dw_mediamanager.setOpt, opt.id)); 121 122 $img = jQuery(document.createElement('img')) 123 .attr('src', DOKU_BASE + 'lib/images/media_' + 124 opt.id + '_' + text + '.png'); 125 126 $btn.append($img); 127 $p.append($btn); 128 }); 129 130 dw_mediamanager.$popup.append($p); 131 }); 132 133 // insert button 134 $insp = jQuery(document.createElement('p')) 135 .addClass('btnlbl'); 136 dw_mediamanager.$popup.append($insp); 137 138 $insbtn = jQuery(document.createElement('input')) 139 .attr('id', 'media__sendbtn') 140 .attr('type', 'button') 141 .addClass('button') 142 .val(LANG.mediainsert); 143 $insp.append($insbtn); 144 }, 145 146 /** 147 * Insert the clicked image into the opener's textarea 148 * 149 * @author Andreas Gohr <andi@splitbrain.org> 150 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 151 * @author Pierre Spring <pierre.spring@caillou.ch> 152 */ 153 insert: function () { 154 var opts, alignleft, alignright, edid, s; 155 156 // set syntax options 157 dw_mediamanager.$popup.dialog('close'); 158 159 opts = ''; 160 alignleft = ''; 161 alignright = ''; 162 163 if ({img: 1, swf: 1}[dw_mediamanager.ext] === 1) { 164 165 if (dw_mediamanager.link === '4') { 166 opts = '?linkonly'; 167 } else { 168 169 if (dw_mediamanager.link === "3" && dw_mediamanager.ext === 'img') { 170 opts = '?nolink'; 171 } else if (dw_mediamanager.link === "2" && dw_mediamanager.ext === 'img') { 172 opts = '?direct'; 173 } 174 175 s = parseInt(dw_mediamanager.size, 10); 176 177 if (s && s >= 1 && s < 4) { 178 opts += (opts.length)?'&':'?'; 179 opts += dw_mediamanager.size + '00'; 180 if (dw_mediamanager.ext === 'swf') { 181 switch (s) { 182 case 1: 183 opts += 'x62'; 184 break; 185 case 2: 186 opts += 'x123'; 187 break; 188 case 3: 189 opts += 'x185'; 190 break; 191 } 192 } 193 } 194 alignleft = dw_mediamanager.align === '2' ? '' : ' '; 195 alignright = dw_mediamanager.align === '4' ? '' : ' '; 196 } 197 } 198 edid = String.prototype.match.call(document.location, /&edid=([^&]+)/); 199 opener.insertTags(edid ? edid[1] : 'wiki__text', 200 '{{'+alignleft+id+opts+alignright+'|','}}',''); 201 202 if(!dw_mediamanager.keepopen) { 203 window.close(); 204 } 205 opener.focus(); 206 return false; 207 }, 208 209 /** 210 * Prefills the wikiname. 211 * 212 * @author Andreas Gohr <andi@splitbrain.org> 213 */ 214 suggest: function(){ 215 var $file, $name, text; 216 217 $file = jQuery(this); 218 $name = jQuery('#upload__name'); 219 220 if ($name.val() != '') return; 221 222 if(!$file.length || !$name.length) { 223 return; 224 } 225 226 text = $file.val(); 227 text = text.substr(text.lastIndexOf('/')+1); 228 text = text.substr(text.lastIndexOf('\\')+1); 229 $name.val(text); 230 }, 231 232 /** 233 * list the content of a namespace using AJAX 234 * 235 * @author Andreas Gohr <andi@splitbrain.org> 236 * @author Pierre Spring <pierre.spring@caillou.ch> 237 */ 238 list: function (event) { 239 var $link, $content, params; 240 $link = jQuery(this); 241 242 event.preventDefault(); 243 244 jQuery('div.success, div.info, div.error, div.notify').remove(); 245 246 if (document.getElementById('media__content')) { 247 //popup 248 $content = jQuery('#media__content'); 249 $content.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 250 251 } else { 252 //fullscreen media manager 253 $content = jQuery('#mediamanager__layout_list'); 254 255 if ($link.hasClass('idx_dir')) { 256 //changing namespace 257 jQuery('#mediamanager__layout_detail').empty(); 258 jQuery('#media__tree .selected').each(function(){ 259 jQuery(this).removeClass('selected'); 260 }); 261 $link.addClass('selected'); 262 } 263 264 jQuery('.scroll-container', $content).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 265 } 266 267 params = ''; 268 269 if ($link[0].search) { 270 params = $link[0].search.substr(1)+'&call=medialist'; 271 } else if ($link[0].action) { 272 params = dw_mediamanager.form_params($link)+'&call=medialist'; 273 } 274 275 // fetch the subtree 276 dw_mediamanager.update_content($content, params); 277 278 }, 279 280 /** 281 * Returns form parameters 282 * 283 * @author Kate Arzamastseva <pshns@ukr.net> 284 */ 285 form_params: function ($form) { 286 var elements = $form.serialize(); 287 var action = ''; 288 var i = $form[0].action.indexOf('?'); 289 if (i >= 0) action = $form[0].action.substr(i+1); 290 return elements+'&'+action; 291 }, 292 293 /** 294 * Changes view of media files list 295 * 296 * @author Kate Arzamastseva <pshns@ukr.net> 297 */ 298 list_view: function (event) { 299 var $link, $content; 300 $link = jQuery(this); 301 302 event.preventDefault(); 303 304 $content = jQuery('#mediamanager__file_list'); 305 306 if ($link[0].id == 'mediamanager__link_thumbs') { 307 $content.removeClass('mediamanager-list'); 308 $content.addClass('mediamanager-thumbs'); 309 310 } else if ($link[0].id == 'mediamanager__link_list') { 311 $content.removeClass('mediamanager-thumbs'); 312 $content.addClass('mediamanager-list'); 313 } 314 }, 315 316 /** 317 * Lists the content of the right column (image details) using AJAX 318 * 319 * @author Kate Arzamastseva <pshns@ukr.net> 320 */ 321 details: function (event) { 322 var $link, $content, params, update_list; 323 $link = jQuery(this); 324 325 event.preventDefault(); 326 327 jQuery('div.success, div.info, div.error, div.notify').remove(); 328 329 if ($link[0].id == 'mediamanager__btn_delete' && !confirm(LANG['del_confirm'])) return false; 330 if ($link[0].id == 'mediamanager__btn_restore' && !confirm(LANG['restore_confirm'])) return false; 331 332 $content = jQuery('#mediamanager__layout_detail'); 333 if (jQuery('.scroll-container', $content).length) { 334 jQuery('.scroll-container', $content).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 335 } else { 336 jQuery($content).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 337 } 338 339 params = ''; 340 341 if ($link[0].search) { 342 params = $link[0].search.substr(1)+'&call=mediadetails'; 343 } else { 344 params = dw_mediamanager.form_params($link)+'&call=mediadetails'; 345 } 346 347 dw_mediamanager.update_content($content, params); 348 349 update_list = ($link[0].id == 'mediamanager__btn_delete' || $link[0].id == 'mediamanager__btn_restore'); 350 if (update_list) { 351 var $link1, $content1, params1; 352 $link1 = jQuery('a.files'); 353 params1 = $link1[0].search.substr(1)+'&call=medialist'; 354 $content1 = jQuery('#mediamanager__layout_list'); 355 jQuery('.scroll-container', $content1).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 356 357 dw_mediamanager.update_content($content1, params1); 358 } 359 }, 360 361 update_content: function ($content, params) { 362 jQuery.post( 363 DOKU_BASE + 'lib/exe/ajax.php', 364 params, 365 function (data) { 366 jQuery('.ui-resizable').each(function(){ 367 jQuery(this).resizable('destroy'); 368 }); 369 370 $content.html(data); 371 dw_mediamanager.prepare_content($content); 372 dw_mediamanager.updatehide(); 373 dw_mediamanager.update_resizable(0); 374 dw_mediamanager.opacity_slider(); 375 dw_mediamanager.portions_slider(); 376 addInitEvent(revisionsForm); 377 }, 378 'html' 379 ); 380 }, 381 382 update_resizable: function (count_width) { 383 $resizable = jQuery("#mediamanager__layout .layout-resizable"); 384 385 $resizable.resizable({ handles: 'e' , 386 resize: function(event, ui){ 387 var w = 0; 388 $resizable.each(function() { 389 w += jQuery(this).width(); 390 }); 391 wSum = w + parseFloat(jQuery('#mediamanager__layout_detail').css("min-width")); 392 393 // max width of resizable column 394 var maxWidth = 0.95 * jQuery('#mediamanager__layout').width() - wSum + jQuery(this).width() - 30; 395 $resizable.resizable( "option", "maxWidth", maxWidth ); 396 397 // percentage width of the first two columns 398 var wLeft = ( 100*(w+30) / jQuery('#mediamanager__layout').width() ); 399 400 // width of the third column 401 var wRight = 95-wLeft; 402 wRight += "%"; 403 jQuery('#mediamanager__layout_detail').width(wRight); 404 } 405 }); 406 407 var windowHeight = jQuery(window).height(); 408 var height = windowHeight - 300; 409 jQuery('#mediamanager__layout .scroll-container').each(function (i) { 410 jQuery(this).height(height); 411 }); 412 $resizable.each(function() { 413 jQuery(this).height(height+100); 414 }); 415 }, 416 417 opacity_slider: function () { 418 var $slider = jQuery( "#mediamanager__opacity_slider" ); 419 $slider.slider(); 420 $slider.slider("option", "min", 0); 421 $slider.slider("option", "max", 0.999); 422 $slider.slider("option", "step", 0.001); 423 $slider.slider("option", "value", 0.5); 424 $slider.bind("slide", function(event, ui) { 425 jQuery('#mediamanager__diff_opacity_image2').css({ opacity: $slider.slider("option", "value")}); 426 }); 427 }, 428 429 portions_slider: function () { 430 var $slider = jQuery( "#mediamanager__portions_slider" ); 431 $slider.slider(); 432 $slider.slider("option", "min", 0); 433 $slider.slider("option", "max", 100); 434 $slider.slider("option", "step", 1); 435 $slider.slider("option", "value", 50); 436 $slider.bind("slide", function(event, ui) { 437 jQuery('#mediamanager__diff_portions_image2').css({ width: $slider.slider("option", "value")+'%'}); 438 }); 439 }, 440 441 prepare_content: function ($content) { 442 // hide syntax example 443 $content.find('div.example:visible').hide(); 444 dw_mediamanager.initFlashUpload(); 445 }, 446 447 /** 448 * shows the popup for a image link 449 */ 450 select: function(event){ 451 var $link, id, dot, ext; 452 453 event.preventDefault(); 454 455 $link = jQuery(this); 456 id = $link.attr('name').substr(2); 457 458 if(!opener){ 459 // if we don't run in popup display example 460 // the id's are a bit wierd and jQuery('#ex_wiki_dokuwiki-128.png') 461 // will not be found by Sizzle (the CSS Selector Engine 462 // used by jQuery), hence the document.getElementById() call 463 jQuery(document.getElementById('ex_'+id.replace(/:/g,'_').replace(/^_/,''))).dw_toggle(); 464 return; 465 } 466 467 dw_mediamanager.ext = false; 468 dot = id.lastIndexOf("."); 469 470 if (-1 === dot) { 471 dw_mediamanager.insert(id); 472 return; 473 } 474 475 ext = id.substr(dot); 476 477 if ({'.jpg':1, '.jpeg':1, '.png':1, '.gif':1, '.swf':1}[ext] !== 1) { 478 dw_mediamanager.insert(id); 479 return; 480 } 481 482 // remove old callback from the insert button and set the new one. 483 jQuery('#media__sendbtn').unbind().click(bind(dw_mediamanager.insert, id)); 484 485 dw_mediamanager.unforbid('ext'); 486 if (ext === '.swf') { 487 dw_mediamanager.ext = 'swf'; 488 dw_mediamanager.forbid('ext', {link: ['1', '2'], 489 size: ['4']}); 490 } else { 491 dw_mediamanager.ext = 'img'; 492 } 493 494 // Set to defaults 495 dw_mediamanager.setOpt('link'); 496 dw_mediamanager.setOpt('align'); 497 dw_mediamanager.setOpt('size'); 498 499 // toggle buttons for detail and linked image, original size 500 jQuery('#media__linkbtn1, #media__linkbtn2, #media__sizebtn4') 501 .toggle(dw_mediamanager.ext === 'img'); 502 503 dw_mediamanager.$popup.dialog('open'); 504 505 jQuery('#media__sendbtn').focus(); 506 }, 507 508 /** 509 * Deletion confirmation dialog to the delete buttons. 510 * 511 * @author Michael Klier <chi@chimeric.de> 512 * @author Pierre Spring <pierre.spring@caillou.ch> 513 */ 514 confirmattach: function(e){ 515 if(!confirm(LANG.del_confirm + "\n" + jQuery(this).attr('title'))) { 516 e.preventDefault(); 517 } 518 }, 519 520 /** 521 * Creates checkboxes for additional options 522 * 523 * @author Andreas Gohr <andi@splitbrain.org> 524 * @author Pierre Spring <pierre.spring@caillou.ch> 525 */ 526 attachoptions: function(){ 527 var $obj, opts; 528 529 $obj = jQuery('#media__opts'); 530 if($obj.length === 0) { 531 return; 532 } 533 534 opts = []; 535 // keep open 536 if(opener){ 537 opts.push(['keepopen', 'keepopen']); 538 } 539 opts.push(['hide', 'hidedetails']); 540 541 jQuery.each(opts, 542 function(_, opt) { 543 var $box, $lbl; 544 $box = jQuery(document.createElement('input')) 545 .attr('type', 'checkbox') 546 .attr('id', 'media__' + opt[0]) 547 .click(bind(dw_mediamanager.toggleOption, 548 opt[0])); 549 550 if(DokuCookie.getValue(opt[0])){ 551 $box.prop('checked', true); 552 dw_mediamanager[opt[0]] = true; 553 } 554 555 $lbl = jQuery(document.createElement('label')) 556 .attr('for', 'media__' + opt[0]) 557 .text(LANG[opt[1]]); 558 559 $obj.append($box, $lbl, document.createElement('br')); 560 }); 561 562 dw_mediamanager.updatehide(); 563 }, 564 565 /** 566 * Generalized toggler 567 * 568 * @author Pierre Spring <pierre.spring@caillou.ch> 569 */ 570 toggleOption: function (variable) { 571 if (jQuery(this).prop('checked')) { 572 DokuCookie.setValue(variable, 1); 573 dw_mediamanager[variable] = true; 574 } else { 575 DokuCookie.setValue(variable, ''); 576 dw_mediamanager[variable] = false; 577 } 578 if (variable === 'hide') { 579 dw_mediamanager.updatehide(); 580 } 581 }, 582 583 initFlashUpload: function () { 584 var $oform, $oflash; 585 if(!hasFlash(8)) { 586 return; 587 } 588 589 $oform = jQuery('#dw__upload'); 590 $oflash = jQuery('#dw__flashupload'); 591 592 if(!$oform.length || !$oflash.length) { 593 return; 594 } 595 596 jQuery(document.createElement('img')) 597 .attr('src', DOKU_BASE+'lib/images/multiupload.png') 598 .attr('title', LANG.mu_btn) 599 .attr('alt', LANG.mu_btn) 600 .css('cursor', 'pointer') 601 .click( 602 function () { 603 $oform.hide(); 604 $oflash.show(); 605 } 606 ) 607 .appendTo($oform); 608 }, 609 610 /** 611 * Sets the visibility of the image details accordingly to the 612 * chosen hide state 613 * 614 * @author Andreas Gohr <andi@splitbrain.org> 615 */ 616 updatehide: function(){ 617 jQuery('#media__content div.detail').dw_toggle(!dw_mediamanager.hide); 618 }, 619 620 /** 621 * set media insertion option 622 * 623 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 624 */ 625 setOpt: function(opt, e){ 626 var val, i; 627 if (typeof e !== 'undefined') { 628 val = this.id.substring(this.id.length - 1); 629 } else { 630 val = dw_mediamanager.getOpt(opt); 631 } 632 633 if (val === false) { 634 DokuCookie.setValue(opt,''); 635 dw_mediamanager[opt] = false; 636 return; 637 } 638 639 if (opt === 'link') { 640 if (val !== '4' && dw_mediamanager.link === '4') { 641 dw_mediamanager.unforbid('linkonly'); 642 dw_mediamanager.setOpt('align'); 643 dw_mediamanager.setOpt('size'); 644 } else if (val === '4') { 645 dw_mediamanager.forbid('linkonly', {align: false, size: false}); 646 } 647 648 jQuery("#media__size, #media__align").dw_toggle(val !== '4'); 649 } 650 651 DokuCookie.setValue(opt, val); 652 dw_mediamanager[opt] = val; 653 654 for (i = 1; i <= 4; i++) { 655 jQuery("#media__" + opt + "btn" + i).removeClass('selected'); 656 } 657 jQuery('#media__' + opt + 'btn' + val).addClass('selected'); 658 }, 659 660 unforbid: function (group) { 661 delete dw_mediamanager.forbidden_opts[group]; 662 }, 663 664 forbid: function (group, forbids) { 665 dw_mediamanager.forbidden_opts[group] = forbids; 666 }, 667 668 allowedOpt: function (opt, val) { 669 var ret = true; 670 jQuery.each(dw_mediamanager.forbidden_opts, 671 function (_, forbids) { 672 ret = forbids[opt] !== false && 673 jQuery.inArray(val, forbids[opt]) === -1; 674 return ret; 675 }); 676 return ret; 677 }, 678 679 getOpt: function (opt) { 680 var allowed = bind(dw_mediamanager.allowedOpt, opt); 681 682 // Current value 683 if (dw_mediamanager[opt] !== false && allowed(dw_mediamanager[opt])) { 684 return dw_mediamanager[opt]; 685 } 686 687 // From cookie 688 if (DokuCookie.getValue(opt) && allowed(DokuCookie.getValue(opt))) { 689 return DokuCookie.getValue(opt); 690 } 691 692 // size default 693 if (opt === 'size' && allowed('2')) { 694 return '2'; 695 } 696 697 // Whatever is allowed, and be it false 698 return jQuery.grep(['1', '2', '3', '4'], allowed)[0] || false; 699 } 700}; 701 702// moved from helpers.js temporarily here 703/** 704 * Very simplistic Flash plugin check, probably works for Flash 8 and higher only 705 * 706 */ 707function hasFlash(version){ 708 var ver = 0, axo; 709 try{ 710 if(navigator.plugins !== null && navigator.plugins.length > 0){ 711 ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0]; 712 }else{ 713 axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); 714 ver = axo.GetVariable("$version").split(' ')[1].split(',')[0]; 715 } 716 }catch(e){ } 717 718 return ver >= version; 719} 720 721jQuery(document).ready(function() { 722 dw_mediamanager.update_resizable(1); 723 dw_mediamanager.opacity_slider(); 724 dw_mediamanager.portions_slider(); 725 jQuery(window).resize(dw_mediamanager.update_resizable); 726}); 727 728jQuery(dw_mediamanager.init); 729