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.siblings('a').first(); 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 $clicky.attr('src', DOKU_BASE + 'lib/images/minus.gif'); 56 }, 57 58 close: function ($clicky) { 59 $clicky.attr('src', 60 DOKU_BASE + 'lib/images/plus.gif'); 61 }}); 62 $tree.delegate('a', 'click', dw_mediamanager.list); 63 64 jQuery('#mediamanager__layout_list').delegate('#mediamanager__tabs_files a', 'click', dw_mediamanager.list) 65 .delegate('#mediamanager__tabs_list a', 'click', dw_mediamanager.list_view) 66 .delegate('#mediamanager__file_list a', 'click', dw_mediamanager.details) 67 .delegate('#dw__mediasearch', 'submit', dw_mediamanager.list); 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 if(!$file.length || !$name.length) { 220 return; 221 } 222 223 text = $file.val(); 224 text = text.substr(text.lastIndexOf('/')+1); 225 text = text.substr(text.lastIndexOf('\\')+1); 226 $name.val(text); 227 }, 228 229 /** 230 * list the content of a namespace using AJAX 231 * 232 * @author Andreas Gohr <andi@splitbrain.org> 233 * @author Pierre Spring <pierre.spring@caillou.ch> 234 */ 235 list: function (event) { 236 var $link, $content, params; 237 $link = jQuery(this); 238 239 event.preventDefault(); 240 241 jQuery('div.success, div.info, div.error, div.notify').remove(); 242 243 if (document.getElementById('media__content')) { 244 //popup 245 $content = jQuery('#media__content'); 246 $content.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 247 248 } else { 249 //fullscreen media manager 250 $content = jQuery('#mediamanager__layout_list'); 251 252 if ($link.hasClass('idx_dir')) { 253 //changing namespace 254 jQuery('#mediamanager__layout_detail').empty(); 255 jQuery('#media__tree .selected').each(function(){ 256 jQuery(this).removeClass('selected'); 257 }); 258 $link.addClass('selected'); 259 } 260 261 jQuery('.scroll-container', $content).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 262 } 263 264 params = ''; 265 266 if ($link[0].search) { 267 params = $link[0].search.substr(1)+'&call=medialist'; 268 } else if ($link[0].action) { 269 params = dw_mediamanager.form_params($link)+'&call=medialist'; 270 } 271 272 // fetch the subtree 273 dw_mediamanager.update_content($content, params); 274 275 }, 276 277 /** 278 * Returns form parameters 279 * 280 * @author Kate Arzamastseva <pshns@ukr.net> 281 */ 282 form_params: function ($form) { 283 var elements = $form.serialize(); 284 var action = ''; 285 var i = $form[0].action.indexOf('?'); 286 if (i >= 0) action = $form[0].action.substr(i+1); 287 return elements+'&'+action; 288 }, 289 290 /** 291 * Changes view of media files list 292 * 293 * @author Kate Arzamastseva <pshns@ukr.net> 294 */ 295 list_view: function (event) { 296 var $link, $content; 297 $link = jQuery(this); 298 299 event.preventDefault(); 300 301 $content = jQuery('#mediamanager__file_list'); 302 if ($link.hasClass('mediamanager-link-thumbnails')) { 303 $content.removeClass('mediamanager-list'); 304 $content.addClass('mediamanager-thumbs'); 305 } else if ($link.hasClass('mediamanager-link-list')) { 306 $content.removeClass('mediamanager-thumbs'); 307 $content.addClass('mediamanager-list'); 308 } 309 }, 310 311 /** 312 * Lists the content of the right column (image details) using AJAX 313 * 314 * @author Kate Arzamastseva <pshns@ukr.net> 315 */ 316 details: function (event) { 317 var $link, $content, params, update_list; 318 $link = jQuery(this); 319 320 event.preventDefault(); 321 322 jQuery('div.success, div.info, div.error, div.notify').remove(); 323 324 if ($link[0].id == 'mediamanager__btn_delete' && !confirm(LANG['del_confirm'])) return false; 325 if ($link[0].id == 'mediamanager__btn_restore' && !confirm(LANG['restore_confirm'])) return false; 326 327 $content = jQuery('#mediamanager__layout_detail'); 328 jQuery('.scroll-container', $content).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 329 330 params = ''; 331 332 if ($link[0].search) { 333 params = $link[0].search.substr(1)+'&call=mediadetails'; 334 } else { 335 params = dw_mediamanager.form_params($link)+'&call=mediadetails'; 336 } 337 338 dw_mediamanager.update_content($content, params); 339 340 update_list = ($link[0].id == 'mediamanager__btn_delete' || $link[0].id == 'mediamanager__btn_restore'); 341 if (update_list) { 342 var $link1, $content1, params1; 343 $link1 = jQuery('a.files'); 344 params1 = $link1[0].search.substr(1)+'&call=medialist'; 345 $content1 = jQuery('#mediamanager__layout_list'); 346 jQuery('.scroll-container', $content1).html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />'); 347 348 dw_mediamanager.update_content($content1, params1); 349 } 350 }, 351 352 update_content: function ($content, params) { 353 jQuery.post( 354 DOKU_BASE + 'lib/exe/ajax.php', 355 params, 356 function (data) { 357 $content.html(data); 358 dw_mediamanager.prepare_content($content); 359 dw_mediamanager.updatehide(); 360 }, 361 'html' 362 ); 363 }, 364 365 prepare_content: function ($content) { 366 // hide syntax example 367 $content.find('div.example:visible').hide(); 368 dw_mediamanager.initFlashUpload(); 369 }, 370 371 /** 372 * shows the popup for a image link 373 */ 374 select: function(event){ 375 var $link, id, dot, ext; 376 377 event.preventDefault(); 378 379 $link = jQuery(this); 380 id = $link.attr('name').substr(2); 381 382 if(!opener){ 383 // if we don't run in popup display example 384 // the id's are a bit wierd and jQuery('#ex_wiki_dokuwiki-128.png') 385 // will not be found by Sizzle (the CSS Selector Engine 386 // used by jQuery), hence the document.getElementById() call 387 jQuery(document.getElementById('ex_'+id.replace(/:/g,'_').replace(/^_/,''))).dw_toggle(); 388 return; 389 } 390 391 dw_mediamanager.ext = false; 392 dot = id.lastIndexOf("."); 393 394 if (-1 === dot) { 395 dw_mediamanager.insert(id); 396 return; 397 } 398 399 ext = id.substr(dot); 400 401 if ({'.jpg':1, '.jpeg':1, '.png':1, '.gif':1, '.swf':1}[ext] !== 1) { 402 dw_mediamanager.insert(id); 403 return; 404 } 405 406 // remove old callback from the insert button and set the new one. 407 jQuery('#media__sendbtn').unbind().click(bind(dw_mediamanager.insert, id)); 408 409 dw_mediamanager.unforbid('ext'); 410 if (ext === '.swf') { 411 dw_mediamanager.ext = 'swf'; 412 dw_mediamanager.forbid('ext', {link: ['1', '2'], 413 size: ['4']}); 414 } else { 415 dw_mediamanager.ext = 'img'; 416 } 417 418 // Set to defaults 419 dw_mediamanager.setOpt('link'); 420 dw_mediamanager.setOpt('align'); 421 dw_mediamanager.setOpt('size'); 422 423 // toggle buttons for detail and linked image, original size 424 jQuery('#media__linkbtn1, #media__linkbtn2, #media__sizebtn4') 425 .toggle(dw_mediamanager.ext === 'img'); 426 427 dw_mediamanager.$popup.dialog('open'); 428 429 jQuery('#media__sendbtn').focus(); 430 }, 431 432 /** 433 * Deletion confirmation dialog to the delete buttons. 434 * 435 * @author Michael Klier <chi@chimeric.de> 436 * @author Pierre Spring <pierre.spring@caillou.ch> 437 */ 438 confirmattach: function(e){ 439 if(!confirm(LANG.del_confirm + "\n" + jQuery(this).attr('title'))) { 440 e.preventDefault(); 441 } 442 }, 443 444 /** 445 * Creates checkboxes for additional options 446 * 447 * @author Andreas Gohr <andi@splitbrain.org> 448 * @author Pierre Spring <pierre.spring@caillou.ch> 449 */ 450 attachoptions: function(){ 451 var $obj, opts; 452 453 $obj = jQuery('#media__opts'); 454 if($obj.length === 0) { 455 return; 456 } 457 458 opts = []; 459 // keep open 460 if(opener){ 461 opts.push(['keepopen', 'keepopen']); 462 } 463 opts.push(['hide', 'hidedetails']); 464 465 jQuery.each(opts, 466 function(_, opt) { 467 var $box, $lbl; 468 $box = jQuery(document.createElement('input')) 469 .attr('type', 'checkbox') 470 .attr('id', 'media__' + opt[0]) 471 .click(bind(dw_mediamanager.toggleOption, 472 opt[0])); 473 474 if(DokuCookie.getValue(opt[0])){ 475 $box.prop('checked', true); 476 dw_mediamanager[opt[0]] = true; 477 } 478 479 $lbl = jQuery(document.createElement('label')) 480 .attr('for', 'media__' + opt[0]) 481 .text(LANG[opt[1]]); 482 483 $obj.append($box, $lbl, document.createElement('br')); 484 }); 485 486 dw_mediamanager.updatehide(); 487 }, 488 489 /** 490 * Generalized toggler 491 * 492 * @author Pierre Spring <pierre.spring@caillou.ch> 493 */ 494 toggleOption: function (variable) { 495 if (jQuery(this).prop('checked')) { 496 DokuCookie.setValue(variable, 1); 497 dw_mediamanager[variable] = true; 498 } else { 499 DokuCookie.setValue(variable, ''); 500 dw_mediamanager[variable] = false; 501 } 502 if (variable === 'hide') { 503 dw_mediamanager.updatehide(); 504 } 505 }, 506 507 initFlashUpload: function () { 508 var $oform, $oflash; 509 if(!hasFlash(8)) { 510 return; 511 } 512 513 $oform = jQuery('#dw__upload'); 514 $oflash = jQuery('#dw__flashupload'); 515 516 if(!$oform.length || !$oflash.length) { 517 return; 518 } 519 520 jQuery(document.createElement('img')) 521 .attr('src', DOKU_BASE+'lib/images/multiupload.png') 522 .attr('title', LANG.mu_btn) 523 .attr('alt', LANG.mu_btn) 524 .css('cursor', 'pointer') 525 .click( 526 function () { 527 $oform.hide(); 528 $oflash.show(); 529 } 530 ) 531 .appendTo($oform); 532 }, 533 534 /** 535 * Sets the visibility of the image details accordingly to the 536 * chosen hide state 537 * 538 * @author Andreas Gohr <andi@splitbrain.org> 539 */ 540 updatehide: function(){ 541 jQuery('#media__content div.detail').dw_toggle(!dw_mediamanager.hide); 542 }, 543 544 /** 545 * set media insertion option 546 * 547 * @author Dominik Eckelmann <eckelmann@cosmocode.de> 548 */ 549 setOpt: function(opt, e){ 550 var val, i; 551 if (typeof e !== 'undefined') { 552 val = this.id.substring(this.id.length - 1); 553 } else { 554 val = dw_mediamanager.getOpt(opt); 555 } 556 557 if (val === false) { 558 DokuCookie.setValue(opt,''); 559 dw_mediamanager[opt] = false; 560 return; 561 } 562 563 if (opt === 'link') { 564 if (val !== '4' && dw_mediamanager.link === '4') { 565 dw_mediamanager.unforbid('linkonly'); 566 dw_mediamanager.setOpt('align'); 567 dw_mediamanager.setOpt('size'); 568 } else if (val === '4') { 569 dw_mediamanager.forbid('linkonly', {align: false, size: false}); 570 } 571 572 jQuery("#media__size, #media__align").dw_toggle(val !== '4'); 573 } 574 575 DokuCookie.setValue(opt, val); 576 dw_mediamanager[opt] = val; 577 578 for (i = 1; i <= 4; i++) { 579 jQuery("#media__" + opt + "btn" + i).removeClass('selected'); 580 } 581 jQuery('#media__' + opt + 'btn' + val).addClass('selected'); 582 }, 583 584 unforbid: function (group) { 585 delete dw_mediamanager.forbidden_opts[group]; 586 }, 587 588 forbid: function (group, forbids) { 589 dw_mediamanager.forbidden_opts[group] = forbids; 590 }, 591 592 allowedOpt: function (opt, val) { 593 var ret = true; 594 jQuery.each(dw_mediamanager.forbidden_opts, 595 function (_, forbids) { 596 ret = forbids[opt] !== false && 597 jQuery.inArray(val, forbids[opt]) === -1; 598 return ret; 599 }); 600 return ret; 601 }, 602 603 getOpt: function (opt) { 604 var allowed = bind(dw_mediamanager.allowedOpt, opt); 605 606 // Current value 607 if (dw_mediamanager[opt] !== false && allowed(dw_mediamanager[opt])) { 608 return dw_mediamanager[opt]; 609 } 610 611 // From cookie 612 if (DokuCookie.getValue(opt) && allowed(DokuCookie.getValue(opt))) { 613 return DokuCookie.getValue(opt); 614 } 615 616 // size default 617 if (opt === 'size' && allowed('2')) { 618 return '2'; 619 } 620 621 // Whatever is allowed, and be it false 622 return jQuery.grep(['1', '2', '3', '4'], allowed)[0] || false; 623 } 624}; 625 626// moved from helpers.js temporarily here 627/** 628 * Very simplistic Flash plugin check, probably works for Flash 8 and higher only 629 * 630 */ 631function hasFlash(version){ 632 var ver = 0, axo; 633 try{ 634 if(navigator.plugins !== null && navigator.plugins.length > 0){ 635 ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0]; 636 }else{ 637 axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); 638 ver = axo.GetVariable("$version").split(' ')[1].split(',')[0]; 639 } 640 }catch(e){ } 641 642 return ver >= version; 643} 644 645jQuery(dw_mediamanager.init); 646