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