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