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