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