xref: /dokuwiki/lib/scripts/media.js (revision 9d0bfd9dd1051f34da2dc9fe03d4df4dcded123e)
1/**
2 * JavaScript functionality for the media management popup
3 *
4 * @author Andreas Gohr <andi@splitbrain.org>
5 * @author Pierre Spring <pierre.spring@caillou.ch>
6 */
7
8var dw_mediamanager = {
9    keepopen: false,
10    hide: false,
11    popup: false,
12    display: false,
13    ext: false,
14    $popup: null,
15
16    // Image insertion opts
17    align: false,
18    link: false,
19    size: false,
20    forbidden_opts: {},
21
22    // File list options
23    view_opts: {list: false, sort: false},
24
25    layout_width: 0,
26
27    // The minimum height of the full-screen mediamanager in px
28    minHeights: {thumbs: 200, rows: 100},
29
30    init: function () {
31        var $content, $tree;
32        $content = jQuery('#media__content');
33        $tree = jQuery('#media__tree');
34        if (!$tree.length) return;
35
36        dw_mediamanager.prepare_content($content);
37
38        dw_mediamanager.attachoptions();
39        dw_mediamanager.initpopup();
40
41        // add the action to autofill the "upload as" field
42        $content
43            .delegate('#upload__file', 'change', dw_mediamanager.suggest)
44            // Attach the image selector action to all links
45            .delegate('a.select', 'click', dw_mediamanager.select)
46            // Attach deletion confirmation dialog to the delete buttons
47            .delegate('#media__content a.btn_media_delete', 'click',
48            dw_mediamanager.confirmattach)
49            .delegate('#mediamanager__done_form', 'submit', dw_mediamanager.list);
50
51        $tree.dw_tree({
52            toggle_selector: 'img',
53            load_data: function (show_sublist, $clicky) {
54                // get the enclosed link (is always the first one)
55                var $link = $clicky.parent().find('div.li a.idx_dir');
56
57                jQuery.post(
58                    DOKU_BASE + 'lib/exe/ajax.php',
59                    $link[0].search.substr(1) + '&call=medians',
60                    show_sublist,
61                    'html'
62                );
63            },
64
65            toggle_display: function ($clicky, opening) {
66                $clicky.attr('src', DOKU_BASE + 'lib/images/' + (opening ? 'minus' : 'plus') + '.gif');
67            }
68        });
69        $tree.delegate('a', 'click', dw_mediamanager.list);
70
71        // Init view property
72        dw_mediamanager.set_fileview_list();
73
74        dw_mediamanager.init_options();
75
76        dw_mediamanager.image_diff();
77        dw_mediamanager.init_ajax_uploader();
78
79        // changing opened tab in the file list panel
80        var $page = jQuery('#mediamanager__page');
81        $page.find('div.filelist')
82            .delegate('ul.tabs a', 'click', dw_mediamanager.list)
83            // loading file details
84            .delegate('div.panelContent a', 'click', dw_mediamanager.details)
85            // search form
86            .delegate('#dw__mediasearch', 'submit', dw_mediamanager.list)
87            // "upload as" field autofill
88            .delegate('#upload__file', 'change', dw_mediamanager.suggest)
89            // uploaded images
90            .delegate('.qq-upload-file a', 'click', dw_mediamanager.details);
91
92        // changing opened tab in the file details panel
93        $page.find('div.file')
94            .delegate('ul.tabs a', 'click', dw_mediamanager.details)
95            // "update new version" button
96            .delegate('#mediamanager__btn_update', 'submit', dw_mediamanager.list)
97            // revisions form
98            .delegate('#page__revisions', 'submit', dw_mediamanager.details)
99            .delegate('#page__revisions a', 'click', dw_mediamanager.details)
100            // meta edit form
101            .delegate('#mediamanager__save_meta', 'submit', dw_mediamanager.details)
102            // delete button
103            .delegate('#mediamanager__btn_delete', 'submit', dw_mediamanager.details)
104            // "restore this version" button
105            .delegate('#mediamanager__btn_restore', 'submit', dw_mediamanager.details)
106            // less/more recent buttons in media revisions form
107            .delegate('.btn_newer, .btn_older', 'submit', dw_mediamanager.details);
108
109        dw_mediamanager.update_resizable();
110        dw_mediamanager.layout_width = $page.width();
111        jQuery(window).resize(dw_mediamanager.window_resize);
112    },
113
114    init_options: function () {
115        var $options = jQuery('div.filelist div.panelHeader form.options'),
116            $listType, $sortBy, $both;
117        if ($options.length === 0) {
118            return;
119        }
120
121        $listType = $options.find('li.listType');
122        $sortBy = $options.find('li.sortBy');
123        $both = $listType.add($sortBy);
124
125        // Remove the submit button
126        $options.find('button[type=submit]').parent().hide();
127
128        // Prepare HTML for jQuery UI buttonset
129        $both.find('label').each(function () {
130            var $this = jQuery(this);
131            $this.children('input').appendTo($this.parent());
132        });
133
134        // Init buttonset
135        $both.buttonset();
136
137        // Change handlers
138        $listType.children('input').change(function () {
139            dw_mediamanager.set_fileview_list();
140        });
141        $sortBy.children('input').change(function (event) {
142            dw_mediamanager.set_fileview_sort();
143            dw_mediamanager.list.call(jQuery('#dw__mediasearch')[0] || this, event);
144        });
145    },
146
147    /**
148     * build the popup window
149     *
150     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
151     */
152    initpopup: function () {
153        var opts, $insp, $insbtn;
154
155        dw_mediamanager.$popup = jQuery(document.createElement('div'))
156            .attr('id', 'media__popup_content')
157            .dialog({
158                autoOpen: false, width: 280, modal: true,
159                draggable: true, title: LANG.mediatitle,
160                resizable: false
161            });
162
163        opts = [
164            {
165                id: 'link', label: LANG.mediatarget,
166                btns: ['lnk', 'direct', 'nolnk', 'displaylnk']
167            },
168            {
169                id: 'align', label: LANG.mediaalign,
170                btns: ['noalign', 'left', 'center', 'right']
171            },
172            {
173                id: 'size', label: LANG.mediasize,
174                btns: ['small', 'medium', 'large', 'original']
175            }
176        ];
177
178        jQuery.each(opts, function (_, opt) {
179            var $p, $l;
180            $p = jQuery(document.createElement('p'))
181                .attr('id', 'media__' + opt.id);
182
183            if (dw_mediamanager.display === "2") {
184                $p.hide();
185            }
186
187            $l = jQuery(document.createElement('label'))
188                .text(opt.label);
189            $p.append($l);
190
191            jQuery.each(opt.btns, function (i, text) {
192                var $btn, $img;
193                $btn = jQuery(document.createElement('button'))
194                    .addClass('button')
195                    .attr('id', "media__" + opt.id + "btn" + (i + 1))
196                    .attr('title', LANG['media' + text])
197                    .click(bind(dw_mediamanager.setOpt, opt.id));
198
199                $img = jQuery(document.createElement('img'))
200                    .attr('src', DOKU_BASE + 'lib/images/media_' + opt.id + '_' + text + '.png');
201
202                $btn.append($img);
203                $p.append($btn);
204            });
205
206            dw_mediamanager.$popup.append($p);
207        });
208
209        // insert button
210        $insp = jQuery(document.createElement('p'));
211        dw_mediamanager.$popup.append($insp);
212
213        $insbtn = jQuery(document.createElement('input'))
214            .attr('id', 'media__sendbtn')
215            .attr('type', 'button')
216            .addClass('button')
217            .val(LANG.mediainsert);
218        $insp.append($insbtn);
219    },
220
221    /**
222     * Insert the clicked image into the opener's textarea
223     *
224     * @author Andreas Gohr <andi@splitbrain.org>
225     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
226     * @author Pierre Spring <pierre.spring@caillou.ch>
227     */
228    insert: function (id) {
229        var opts, cb, edid, s;
230
231        // set syntax options
232        dw_mediamanager.$popup.dialog('close');
233
234        opts = '';
235
236        if ({img: 1, swf: 1}[dw_mediamanager.ext] === 1) {
237
238            if (dw_mediamanager.link === '4') {
239                opts = '?linkonly';
240            } else {
241
242                if (dw_mediamanager.link === "3" && dw_mediamanager.ext === 'img') {
243                    opts = '?nolink';
244                } else if (dw_mediamanager.link === "2" && dw_mediamanager.ext === 'img') {
245                    opts = '?direct';
246                }
247
248                s = parseInt(dw_mediamanager.size, 10);
249                var size = s * 200;
250
251                if (s && s >= 1 && s < 4) {
252                    opts += (opts.length) ? '&' : '?';
253                    opts += size;
254                    if (dw_mediamanager.ext === 'swf') {
255                        switch (s) {
256                            case 1:
257                                opts += 'x62';
258                                break;
259                            case 2:
260                                opts += 'x123';
261                                break;
262                            case 3:
263                                opts += 'x185';
264                                break;
265                        }
266                    }
267                }
268            }
269        }
270        edid = String.prototype.match.call(document.location, /&edid=([^&]+)/);
271        edid = edid ? edid[1] : 'wiki__text';
272        cb = String.prototype.match.call(document.location, /&onselect=([^&]+)/);
273        cb = cb ? cb[1].replace(/[^\w]+/, '') : 'dw_mediamanager_item_select';
274
275        opener[cb](edid, id, opts, dw_mediamanager.align);
276        if (!dw_mediamanager.keepopen) {
277            window.close();
278        }
279        opener.focus();
280        return false;
281    },
282
283
284    /**
285     * Prefills the wikiname.
286     *
287     * @author Andreas Gohr <andi@splitbrain.org>
288     */
289    suggest: function () {
290        var $file, $name, text;
291
292        $file = jQuery(this);
293        $name = jQuery('#upload__name');
294
295        if ($name.val() != '') return;
296
297        if (!$file.length || !$name.length) {
298            return;
299        }
300
301        text = $file.val();
302        text = text.substr(text.lastIndexOf('/') + 1);
303        text = text.substr(text.lastIndexOf('\\') + 1);
304        $name.val(text);
305    },
306
307    /**
308     * list the content of a namespace using AJAX
309     *
310     * @author Andreas Gohr <andi@splitbrain.org>
311     * @author Pierre Spring <pierre.spring@caillou.ch>
312     */
313    list: function (event) {
314        var $link, $content, params;
315
316        if (event) {
317            event.preventDefault();
318        }
319
320        jQuery('div.success, div.info, div.error, div.notify').remove();
321
322        $link = jQuery(this);
323
324        //popup
325        $content = jQuery('#media__content');
326
327        if ($content.length === 0) {
328            //fullscreen media manager
329            $content = jQuery('div.filelist');
330
331            if ($link.hasClass('idx_dir')) {
332                //changing namespace
333                jQuery('div.file').empty();
334                jQuery('div.namespaces .selected').removeClass('selected');
335                $link.addClass('selected');
336            }
337        }
338
339        params = 'call=medialist&';
340
341        if ($link[0].search) {
342            params += $link[0].search.substr(1);
343        } else if ($link.is('form')) {
344            params += dw_mediamanager.form_params($link);
345        } else if ($link.closest('form').length > 0) {
346            params += dw_mediamanager.form_params($link.closest('form'));
347        }
348
349        // fetch the subtree
350        dw_mediamanager.update_content($content, params);
351    },
352
353    /**
354     * Returns form parameters
355     *
356     * @author Kate Arzamastseva <pshns@ukr.net>
357     */
358    form_params: function ($form) {
359        if (!$form.length) return;
360
361        var action = '';
362        var i = $form[0].action.indexOf('?');
363        if (i >= 0) {
364            action = $form[0].action.substr(i + 1);
365        }
366        return action + '&' + $form.serialize();
367    },
368
369    set_fileview_list: function (new_type) {
370        dw_mediamanager.set_fileview_opt(['list', 'listType', function (new_type) {
371            jQuery('div.filelist div.panelContent ul')
372                .toggleClass('rows', new_type === 'rows')
373                .toggleClass('thumbs', new_type === 'thumbs');
374        }], new_type);
375
376        // FIXME: Move to onchange handler (opt[2])?
377        dw_mediamanager.resize();
378    },
379
380    set_fileview_sort: function (new_sort) {
381        dw_mediamanager.set_fileview_opt(['sort', 'sortBy', function (new_sort) {
382            // FIXME
383        }], new_sort);
384    },
385
386    set_fileview_opt: function (opt, new_val) {
387        if (typeof new_val === 'undefined') {
388            new_val = jQuery('form.options li.' + opt[1] + ' input')
389                .filter(':checked').val();
390            // if new_val is still undefined (because form.options is not in active tab), set to most spacious option
391            if (typeof new_val === 'undefined') {
392                new_val = 'thumbs';
393            }
394        }
395
396        if (new_val !== dw_mediamanager.view_opts[opt[0]]) {
397            opt[2](new_val);
398
399            DokuCookie.setValue(opt[0], new_val);
400
401            dw_mediamanager.view_opts[opt[0]] = new_val;
402        }
403    },
404
405    /**
406     * Lists the content of the right column (image details) using AJAX
407     *
408     * @author Kate Arzamastseva <pshns@ukr.net>
409     */
410    details: function (event) {
411        var $link, $content, params, update_list;
412        $link = jQuery(this);
413        event.preventDefault();
414
415        jQuery('div.success, div.info, div.error, div.notify').remove();
416
417        if ($link[0].id == 'mediamanager__btn_delete' && !confirm(LANG.del_confirm)) {
418            return false;
419        }
420        if ($link[0].id == 'mediamanager__btn_restore' && !confirm(LANG.restore_confirm)) {
421            return false;
422        }
423
424        $content = jQuery('div.file');
425        params = 'call=mediadetails&';
426
427        if ($link[0].search) {
428            params += $link[0].search.substr(1);
429        } else if ($link.is('form')) {
430            params += dw_mediamanager.form_params($link);
431        } else if ($link.closest('form').length > 0) {
432            params += dw_mediamanager.form_params($link.closest('form'));
433        }
434
435        update_list = ($link[0].id == 'mediamanager__btn_delete' ||
436        $link[0].id == 'mediamanager__btn_restore');
437
438        dw_mediamanager.update_content($content, params, update_list);
439    },
440
441    update_content: function ($content, params, update_list) {
442        var $container;
443
444        jQuery.post(
445            DOKU_BASE + 'lib/exe/ajax.php',
446            params,
447            function (data) {
448                dw_mediamanager.$resizables().resizable('destroy');
449
450                if (update_list) {
451                    dw_mediamanager.list.call(jQuery('#mediamanager__page').find('form.options button[type="submit"]')[0]);
452                }
453
454                $content.html(data);
455
456                dw_mediamanager.prepare_content($content);
457                dw_mediamanager.updatehide();
458
459                dw_mediamanager.update_resizable();
460                dw_behaviour.revisionBoxHandler();
461
462                // Make sure that the list view style stays the same
463                dw_mediamanager.set_fileview_list(dw_mediamanager.view_opts.list);
464
465                dw_mediamanager.image_diff();
466                dw_mediamanager.init_ajax_uploader();
467                dw_mediamanager.init_options();
468
469            },
470            'html'
471        );
472        $container = $content.find('div.panelContent');
473        if ($container.length === 0) {
474            $container = $content;
475        }
476        $container.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />');
477    },
478
479    window_resize: function () {
480        dw_mediamanager.resize();
481
482        dw_mediamanager.opacity_slider();
483        dw_mediamanager.portions_slider();
484    },
485
486    $resizables: function () {
487        return jQuery('#mediamanager__page').find('div.namespaces, div.filelist');
488    },
489
490    /**
491     * Updates mediamanager layout
492     *
493     * @author Kate Arzamastseva <pshns@ukr.net>
494     */
495    update_resizable: function () {
496        var $resizables = dw_mediamanager.$resizables();
497
498        $resizables.resizable({
499            handles: (jQuery('html[dir=rtl]').length ? 'w' : 'e'),
500            resize: function (event, ui) {
501                var $page = jQuery('#mediamanager__page');
502                var widthFull = $page.width();
503                var widthResizables = 0;
504                $resizables.each(function () {
505                    widthResizables += jQuery(this).width();
506                });
507                var $filePanel = $page.find('div.panel.file');
508
509                // set max width of resizable column
510                var widthOtherResizable = widthResizables - jQuery(this).width();
511                var minWidthNonResizable = parseFloat($filePanel.css("min-width"));
512                var maxWidth = widthFull - (widthOtherResizable + minWidthNonResizable) - 1;
513                $resizables.resizable("option", "maxWidth", maxWidth);
514
515                // width of file panel in % = 100% - width of resizables in %
516                // this calculates with 99.9 and not 100 to overcome rounding errors
517                var relWidthNonResizable = 99.9 - (100 * widthResizables / widthFull);
518                // set width of file panel
519                $filePanel.width(relWidthNonResizable + '%');
520
521                // FIXME: please fix without browser sniffing
522                if (!jQuery.browser.webkit) {
523                    $resizables.each(function () {
524                        var w = jQuery(this).width();
525                        w = (99.99 * w / widthFull);
526                        w += "%";
527                        jQuery(this).width(w);
528                    });
529                }
530
531                dw_mediamanager.resize();
532
533                dw_mediamanager.opacity_slider();
534                dw_mediamanager.portions_slider();
535            }
536        });
537
538        dw_mediamanager.resize();
539    },
540
541    resize: function () {
542        var $contents = jQuery('#mediamanager__page').find('div.panelContent'),
543            height = jQuery(window).height() - jQuery(document.body).height() +
544                Math.max.apply(null, jQuery.map($contents, function (v) {
545                    return jQuery(v).height();
546                }));
547
548        // If the screen is too small, don’t try to resize
549        if (height < dw_mediamanager.minHeights[dw_mediamanager.view_opts.list]) {
550            $contents.add(dw_mediamanager.$resizables()).height('auto');
551        } else {
552            $contents.height(height);
553            dw_mediamanager.$resizables().each(function () {
554                var $this = jQuery(this);
555                $this.height(height + $this.find('div.panelContent').offset().top - $this.offset().top);
556            });
557        }
558    },
559
560    /**
561     * Prints 'select' for image difference representation type
562     *
563     * @author Kate Arzamastseva <pshns@ukr.net>
564     */
565    image_diff: function () {
566        if (jQuery('#mediamanager__difftype').length) return;
567
568        var $form = jQuery('#mediamanager__form_diffview');
569        if (!$form.length) return;
570
571        var $label = jQuery(document.createElement('label'));
572        $label.append('<span>' + LANG.media_diff + '</span> ');
573        var $select = jQuery(document.createElement('select'))
574            .attr('id', 'mediamanager__difftype')
575            .attr('name', 'difftype')
576            .change(dw_mediamanager.change_diff_type);
577        $select.append(new Option(LANG.media_diff_both, "both"));
578        $select.append(new Option(LANG.media_diff_opacity, "opacity"));
579        $select.append(new Option(LANG.media_diff_portions, "portions"));
580        $label.append($select);
581        $form.append($label);
582
583        // for IE
584        var select = document.getElementById('mediamanager__difftype');
585        select.options[0].text = LANG.media_diff_both;
586        select.options[1].text = LANG.media_diff_opacity;
587        select.options[2].text = LANG.media_diff_portions;
588    },
589
590    /**
591     * Handles selection of image difference representation type
592     *
593     * @author Kate Arzamastseva <pshns@ukr.net>
594     */
595    change_diff_type: function () {
596        var $select = jQuery('#mediamanager__difftype');
597        var $content = jQuery('#mediamanager__diff');
598
599        var params = dw_mediamanager.form_params($select.closest('form')) + '&call=mediadiff';
600        jQuery.post(
601            DOKU_BASE + 'lib/exe/ajax.php',
602            params,
603            function (data) {
604                $content.html(data);
605                dw_mediamanager.portions_slider();
606                dw_mediamanager.opacity_slider();
607            },
608            'html'
609        );
610    },
611
612    /**
613     * Sets options for opacity diff slider
614     *
615     * @author Kate Arzamastseva <pshns@ukr.net>
616     */
617    opacity_slider: function () {
618        var $diff = jQuery("#mediamanager__diff");
619        var $slider = $diff.find("div.slider");
620        if (!$slider.length) return;
621
622        var $image = $diff.find('div.imageDiff.opacity div.image1 img');
623        if (!$image.length) return;
624        $slider.width($image.width() - 20);
625
626        $slider.slider();
627        $slider.slider("option", "min", 0);
628        $slider.slider("option", "max", 0.999);
629        $slider.slider("option", "step", 0.001);
630        $slider.slider("option", "value", 0.5);
631        $slider.bind("slide", function (event, ui) {
632            jQuery('#mediamanager__diff').find('div.imageDiff.opacity div.image2 img').css({opacity: $slider.slider("option", "value")});
633        });
634    },
635
636    /**
637     * Sets options for red line diff slider
638     *
639     * @author Kate Arzamastseva <pshns@ukr.net>
640     */
641    portions_slider: function () {
642        var $diff = jQuery("#mediamanager__diff");
643        if (!$diff.length) return;
644
645        var $image1 = $diff.find('div.imageDiff.portions div.image1 img');
646        var $image2 = $diff.find('div.imageDiff.portions div.image2 img');
647        if (!$image1.length || !$image2.length) return;
648
649        $diff.width('100%');
650        $image2.parent().width('97%');
651        $image1.width('100%');
652        $image2.width('100%');
653
654        if ($image1.width() < $diff.width()) {
655            $diff.width($image1.width());
656        }
657
658        $image2.parent().width('50%');
659        $image2.width($image1.width());
660        $image1.width($image1.width());
661
662        var $slider = $diff.find("div.slider");
663        if (!$slider.length) return;
664        $slider.width($image1.width() - 20);
665
666        $slider.slider();
667        $slider.slider("option", "min", 0);
668        $slider.slider("option", "max", 97);
669        $slider.slider("option", "step", 1);
670        $slider.slider("option", "value", 50);
671        $slider.bind("slide", function (event, ui) {
672            jQuery('#mediamanager__diff').find('div.imageDiff.portions div.image2').css({width: $slider.slider("option", "value") + '%'});
673        });
674    },
675
676    /**
677     * Parse a URI query string to an associative array
678     *
679     * @author Kate Arzamastseva <pshns@ukr.net>
680     */
681    params_toarray: function (str) {
682        var vars = [], hash;
683        var hashes = str.split('&');
684        for (var i = 0; i < hashes.length; i++) {
685            hash = hashes[i].split('=');
686            vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
687        }
688        return vars;
689    },
690
691    init_ajax_uploader: function () {
692        if (!jQuery('#mediamanager__uploader').length) return;
693        if (jQuery('.qq-upload-list').length) return;
694
695        var params = dw_mediamanager.form_params(jQuery('#dw__upload')) + '&call=mediaupload';
696        params = dw_mediamanager.params_toarray(params);
697
698        var uploader = new qq.FileUploaderExtended({
699            element: document.getElementById('mediamanager__uploader'),
700            action: DOKU_BASE + 'lib/exe/ajax.php',
701            params: params
702        });
703    },
704
705    prepare_content: function ($content) {
706        // hide syntax example
707        $content.find('div.example:visible').hide();
708    },
709
710    /**
711     * shows the popup for a image link
712     */
713    select: function (event) {
714        var $link, id, dot, ext;
715
716        event.preventDefault();
717
718        $link = jQuery(this);
719        id = $link.attr('id').substr(2);
720
721        if (!opener) {
722            // if we don't run in popup display example
723            // the id's are a bit wierd and jQuery('#ex_wiki_dokuwiki-128.png')
724            // will not be found by Sizzle (the CSS Selector Engine
725            // used by jQuery), hence the document.getElementById() call
726            jQuery(document.getElementById('ex_' + id.replace(/:/g, '_').replace(/^_/, ''))).dw_toggle();
727            return;
728        }
729
730        dw_mediamanager.ext = false;
731        dot = id.lastIndexOf(".");
732
733        if (-1 === dot) {
734            dw_mediamanager.insert(id);
735            return;
736        }
737
738        ext = id.substr(dot);
739
740        if ({'.jpg': 1, '.jpeg': 1, '.png': 1, '.gif': 1, '.swf': 1}[ext] !== 1) {
741            dw_mediamanager.insert(id);
742            return;
743        }
744
745        // remove old callback from the insert button and set the new one.
746        var $sendbtn = jQuery('#media__sendbtn');
747        $sendbtn.unbind().click(bind(dw_mediamanager.insert, id));
748
749        dw_mediamanager.unforbid('ext');
750        if (ext === '.swf') {
751            dw_mediamanager.ext = 'swf';
752            dw_mediamanager.forbid('ext', {
753                link: ['1', '2'],
754                size: ['4']
755            });
756        } else {
757            dw_mediamanager.ext = 'img';
758        }
759
760        // Set to defaults
761        dw_mediamanager.setOpt('link');
762        dw_mediamanager.setOpt('align');
763        dw_mediamanager.setOpt('size');
764
765        // toggle buttons for detail and linked image, original size
766        jQuery('#media__linkbtn1, #media__linkbtn2, #media__sizebtn4')
767            .toggle(dw_mediamanager.ext === 'img');
768
769        dw_mediamanager.$popup.dialog('open');
770
771        $sendbtn.focus();
772    },
773
774    /**
775     * Deletion confirmation dialog to the delete buttons.
776     *
777     * @author Michael Klier <chi@chimeric.de>
778     * @author Pierre Spring <pierre.spring@caillou.ch>
779     */
780    confirmattach: function (e) {
781        if (!confirm(LANG.del_confirm + "\n" + jQuery(this).attr('title'))) {
782            e.preventDefault();
783        }
784    },
785
786    /**
787     * Creates checkboxes for additional options
788     *
789     * @author Andreas Gohr <andi@splitbrain.org>
790     * @author Pierre Spring <pierre.spring@caillou.ch>
791     */
792    attachoptions: function () {
793        var $obj, opts;
794
795        $obj = jQuery('#media__opts');
796        if ($obj.length === 0) {
797            return;
798        }
799
800        opts = [];
801        // keep open
802        if (opener) {
803            opts.push(['keepopen', 'keepopen']);
804        }
805        opts.push(['hide', 'hidedetails']);
806
807        jQuery.each(opts,
808            function (_, opt) {
809                var $box, $lbl;
810                $box = jQuery(document.createElement('input'))
811                    .attr('type', 'checkbox')
812                    .attr('id', 'media__' + opt[0])
813                    .click(bind(dw_mediamanager.toggleOption, opt[0]));
814
815                if (DokuCookie.getValue(opt[0])) {
816                    $box.prop('checked', true);
817                    dw_mediamanager[opt[0]] = true;
818                }
819
820                $lbl = jQuery(document.createElement('label'))
821                    .attr('for', 'media__' + opt[0])
822                    .text(LANG[opt[1]]);
823
824                $obj.append($box, $lbl, document.createElement('br'));
825            });
826
827        dw_mediamanager.updatehide();
828    },
829
830    /**
831     * Generalized toggler
832     *
833     * @author Pierre Spring <pierre.spring@caillou.ch>
834     */
835    toggleOption: function (variable) {
836        if (jQuery(this).prop('checked')) {
837            DokuCookie.setValue(variable, 1);
838            dw_mediamanager[variable] = true;
839        } else {
840            DokuCookie.setValue(variable, '');
841            dw_mediamanager[variable] = false;
842        }
843        if (variable === 'hide') {
844            dw_mediamanager.updatehide();
845        }
846    },
847
848    /**
849     * Sets the visibility of the image details accordingly to the
850     * chosen hide state
851     *
852     * @author Andreas Gohr <andi@splitbrain.org>
853     */
854    updatehide: function () {
855        jQuery('#media__content').find('div.detail').dw_toggle(!dw_mediamanager.hide);
856    },
857
858    /**
859     * set media insertion option
860     *
861     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
862     */
863    setOpt: function (opt, e) {
864        var val, i;
865        if (typeof e !== 'undefined') {
866            val = this.id.substring(this.id.length - 1);
867        } else {
868            val = dw_mediamanager.getOpt(opt);
869        }
870
871        if (val === false) {
872            DokuCookie.setValue(opt, '');
873            dw_mediamanager[opt] = false;
874            return;
875        }
876
877        if (opt === 'link') {
878            if (val !== '4' && dw_mediamanager.link === '4') {
879                dw_mediamanager.unforbid('linkonly');
880                dw_mediamanager.setOpt('align');
881                dw_mediamanager.setOpt('size');
882            } else if (val === '4') {
883                dw_mediamanager.forbid('linkonly', {align: false, size: false});
884            }
885
886            jQuery("#media__size, #media__align").dw_toggle(val !== '4');
887        }
888
889        DokuCookie.setValue(opt, val);
890        dw_mediamanager[opt] = val;
891
892        for (i = 1; i <= 4; i++) {
893            jQuery("#media__" + opt + "btn" + i).removeClass('selected');
894        }
895        jQuery('#media__' + opt + 'btn' + val).addClass('selected');
896    },
897
898    unforbid: function (group) {
899        delete dw_mediamanager.forbidden_opts[group];
900    },
901
902    forbid: function (group, forbids) {
903        dw_mediamanager.forbidden_opts[group] = forbids;
904    },
905
906    allowedOpt: function (opt, val) {
907        var ret = true;
908        jQuery.each(dw_mediamanager.forbidden_opts,
909            function (_, forbids) {
910                ret = forbids[opt] !== false &&
911                    jQuery.inArray(val, forbids[opt]) === -1;
912                return ret;
913            });
914        return ret;
915    },
916
917    getOpt: function (opt) {
918        var allowed = bind(dw_mediamanager.allowedOpt, opt);
919
920        // Current value
921        if (dw_mediamanager[opt] !== false && allowed(dw_mediamanager[opt])) {
922            return dw_mediamanager[opt];
923        }
924
925        // From cookie
926        if (DokuCookie.getValue(opt) && allowed(DokuCookie.getValue(opt))) {
927            return DokuCookie.getValue(opt);
928        }
929
930        // size default
931        if (opt === 'size' && allowed('2')) {
932            return '2';
933        }
934
935        // Whatever is allowed, and be it false
936        return jQuery.grep(['1', '2', '3', '4'], allowed)[0] || false;
937    }
938};
939
940/**
941 * Default implementation for the media manager's select action
942 *
943 * Can be overriden with the onselect URL parameter. Is called on the opener context
944 *
945 * @param {string} edid
946 * @param {string} mediaid
947 * @param {string} opts
948 * @param {string} align [none, left, center, right]
949 */
950function dw_mediamanager_item_select(edid, mediaid, opts, align) {
951    var alignleft = '';
952    var alignright = '';
953    if (align !== '1') {
954        alignleft = align === '2' ? '' : ' ';
955        alignright = align === '4' ? '' : ' ';
956    }
957
958    insertTags(edid, '{{' + alignleft + mediaid + opts + alignright + '|', '}}', '');
959}
960
961jQuery(dw_mediamanager.init);
962