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