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