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