xref: /dokuwiki/lib/scripts/media.js (revision a9cfe01a284c48b245a40ff3d02ebd2183fcba66)
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 functionalitiy 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 cls = document.createElement('input');
556        cls.type  = 'button';
557        cls.setAttribute('class','button');
558        cls.value = LANG['mediaclose'];
559        btnp.appendChild(cls);
560        addEvent(cls,'click',function(event){ return media_manager.closePopup(event,this); });
561
562        var btn  = document.createElement('input');
563        btn.type = 'button';
564        btn.id   = 'media__sendbtn';
565        btn.setAttribute('class','button');
566        btn.value = LANG['mediainsert'];
567        btnp.appendChild(btn);
568        addEvent(btn,'click',function(event){ return media_manager.insert(event); });
569    },
570
571    /**
572     * Insert the clicked image into the opener's textarea
573     *
574     * @author Andreas Gohr <andi@splitbrain.org>
575     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
576     */
577    insert: function(event){
578        var id = media_manager.id;
579        // set syntax options
580        $('media__popup').style.display = 'none';
581
582        var opts       = '';
583        var optsstart  = '';
584        var alignleft  = '';
585        var alignright = '';
586
587        if (media_manager.ext == 'img' || media_manager.ext == 'swf') {
588
589            if (media_manager.link == '4') {
590                    opts = '?linkonly';
591            } else {
592
593                if (media_manager.link == "3" && media_manager.ext == 'img') {
594                    opts = '?nolink';
595                    optsstart = true;
596                } else if (media_manager.link == "2" && media_manager.ext == 'img') {
597                    opts = '?direct';
598                    optsstart = true;
599                }
600
601                var s = parseInt(media_manager.size);
602
603                if (s && s >= 1) {
604                    opts += (optsstart)?'&':'?';
605                    if (s=="1") {
606                        opts += '100';
607                        if (media_manager.ext == 'swf') {
608                            opts += 'x62';
609                        }
610                    } else if (s=="2") {
611                        opts += '200';
612                        if (media_manager.ext == 'swf') {
613                            opts += 'x123';
614                        }
615                    } else if (s=="3"){
616                        opts += '300';
617                        if (media_manager.ext == 'swf') {
618                            opts += 'x185';
619                        }
620                    }
621                }
622                if (media_manager.align == '1') {
623                    alignleft = '';
624                    alignright = ' ';
625                }
626                if (media_manager.align == '2') {
627                    alignleft = ' ';
628                    alignright = ' ';
629                }
630                if (media_manager.align == '3') {
631                    alignleft = ' ';
632                    alignright = '';
633                }
634            }
635        }
636        opener.insertTags('wiki__text','{{'+alignleft+id+opts+alignright+'|','}}','');
637
638        if(!media_manager.keepopen) window.close();
639        opener.focus();
640        return false;
641    },
642
643    initFlashUpload: function(){
644        if(!hasFlash(8)) return;
645        var oform  = $('dw__upload');
646        var oflash = $('dw__flashupload');
647        if(!oform || !oflash) return;
648
649        var clicky = document.createElement('img');
650        clicky.src     = DOKU_BASE+'lib/images/multiupload.png';
651        clicky.title   = LANG['mu_btn'];
652        clicky.alt     = LANG['mu_btn'];
653        clicky.style.cursor = 'pointer';
654        clicky.onclick = function(){
655                            oform.style.display  = 'none';
656                            oflash.style.display = '';
657                         };
658        oform.appendChild(clicky);
659    },
660
661    /**
662     * closes the link type popup
663     */
664    closePopup: function(event) {
665        $('media__popup').style.display = 'none';
666    },
667
668    /**
669     * set the align
670     *
671     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
672     */
673    setalign: function(event,cb){
674        if(cb.value){
675            DokuCookie.setValue('align',cb.value);
676            media_manager.align = cb.value;
677            media_manager.outSet("media__alignbtn0");
678            media_manager.outSet("media__alignbtn1");
679            media_manager.outSet("media__alignbtn2");
680            media_manager.outSet("media__alignbtn3");
681            media_manager.inSet("media__alignbtn"+cb.value);
682        }else{
683            DokuCookie.setValue('align','');
684            media_manager.align = false;
685        }
686    },
687    /**
688     * set the link type
689     *
690     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
691     */
692    setlink: function(event,cb){
693        if(cb.value){
694            DokuCookie.setValue('link',cb.value);
695            media_manager.link = cb.value;
696            media_manager.outSet("media__linkbtn1");
697            media_manager.outSet("media__linkbtn2");
698            media_manager.outSet("media__linkbtn3");
699            media_manager.outSet("media__linkbtn4");
700            media_manager.inSet("media__linkbtn"+cb.value);
701            var size = document.getElementById("media__size");
702            var align = document.getElementById("media__align");
703            if (cb.value != '4') {
704                size.style.display  = "block";
705                align.style.display = "block";
706            } else {
707                size.style.display  = "none";
708                align.style.display = "none";
709            }
710        }else{
711            DokuCookie.setValue('link','');
712            media_manager.link = false;
713        }
714    },
715
716    /**
717     * set the display type
718     *
719     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
720     */
721    setdisplay: function(event,cb){
722        if(cb.value){
723            DokuCookie.setValue('display',cb.value);
724            media_manager.display = cb.value;
725            media_manager.outSet("media__displaybtn1");
726            media_manager.outSet("media__displaybtn2");
727            media_manager.inSet("media__displaybtn"+cb.value);
728
729        }else{
730            DokuCookie.setValue('display','');
731            media_manager.align = false;
732        }
733    },
734
735    /**
736     * sets the border to outset
737     */
738    outSet: function(id) {
739        var ele = document.getElementById(id);
740        if (ele == null) return;
741        ele.style.borderStyle = "outset";
742    },
743    /**
744     * sets the border to inset
745     */
746    inSet: function(id) {
747        var ele = document.getElementById(id);
748        if (ele == null) return;
749        ele.style.borderStyle = "inset";
750    },
751
752    /**
753     * set the image size
754     *
755     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
756     */
757    setsize: function(event,cb){
758        if (cb.value) {
759            DokuCookie.setValue('size',cb.value);
760            media_manager.size = cb.value;
761            for (var i = 1 ; i <= 4 ; ++i) {
762                media_manager.outSet("media__sizebtn" + i);
763            }
764            media_manager.inSet("media__sizebtn"+cb.value);
765        } else {
766            DokuCookie.setValue('size','');
767            media_manager.width = false;
768        }
769    }
770};
771
772addInitEvent(function(){
773    //media_manager.treeattach($('media__tree'));
774    media_manager.confirmattach($('media__content'));
775    media_manager.attachoptions($('media__opts'));
776    media_manager.initpopup();
777    media_manager.initFlashUpload();
778});
779