1/* DOKUWIKI:include jquery.filedownload.js */
2
3/** global: DOKU_BASE */
4/** global: LANG */
5/** global: NS */
6/** global: JSINFO */
7/** global: opener */
8// Siteexport Admin Plugin Script
9(function($){
10    $(function(){
11
12        if ( !$('form#siteexport, form#siteexport_site_aggregator, form#siteexport_siteexporter').length ) {
13            return;
14        }
15
16        if (!window.location.origin) {
17            window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
18        }
19
20        var SiteexportAdmin = function() {
21        };
22
23        (function(_){
24
25            _.url = DOKU_BASE + 'lib/exe/ajax.php';
26            _.aggregateForm = $('form#siteexport_site_aggregator, form#siteexport_siteexporter');
27            _.suspendGenerate = _.aggregateForm.length > 0;
28            _.allElements = 'form#siteexport :input:not([readonly]):not([disabled]):not([type=submit]):not(button):not(.dummy), form#siteexport_site_aggregator :input:not([type=submit]):not(button), form#siteexport_siteexporter :input:not([type=submit]):not(button)';
29            _.isManager = $('div#siteexport__manager').length > 0;
30            _.forbidden_options = [ 'call', 'sectok' ];
31
32            _.generate = function() {
33
34                if ( _.suspendGenerate || _.isManager ) { return; }
35
36                this.resetDataForNewRequest();
37
38                _.throbber(true);
39                $.post( _.url, _.settings('__siteexport_generateurl'), function(data) {
40                    data = data.split("\n");
41                    $('#copyurl').val(data[0]);
42                    $('#wgeturl').val(data[1]);
43                    $('#curlurl').val(data[2]);
44                }).fail(function(jqXHR){
45                    _.errorLog(jqXHR.responseText);
46                }).always(function(){
47                    _.throbber(false);
48                });
49            };
50
51            _.run = function() {
52
53                this.resetDataForNewRequest();
54
55                if ( _.isManager && !(typeof opener === "undefined") ) {
56
57                    var settings = $.param(_.cleanSettings()).split('&').join(' ');
58                    if ( settings.length > 0 ) { settings = ' ' + settings; }
59
60                    var edid = String.prototype.match.call(document.location, new RegExp("&edid=([^&]+)"));
61                    opener.insertTags(edid ? edid[1] : 'wiki__text', '{{siteexportAGGREGATOR' + settings + '}}','','');
62
63                    window.close();
64                    opener.focus();
65                    return;
66                }
67
68                _.throbber(true);
69                $.post( _.url, _.settings('__siteexport_getsitelist'), function(data) {
70                    data = data.split("\n");
71
72                    _.pattern = data.shift();
73                    _.zipURL = data.shift();
74
75                    _.pageCount = data.length - 1; // starting at 0
76                    _.currentCount = 0;
77
78                    _.allPages = data;
79                    _.status(_.pages());
80                    _.nextPage();
81                }).fail(function(jqXHR){
82                    _.errorLog(jqXHR.responseText);
83                }).always(function(){
84                    _.throbber(false);
85                });
86            };
87
88
89            _.aggregatorStatus = null;
90            _.runAggregator = function() {
91
92                this.resetDataForNewRequest();
93
94                if ( _.aggregatorStatus == null ) {
95                    _.aggregatorStatus = $('<span id="siteexport__out"/>').appendTo("form#siteexport_site_aggregator, form#siteexport_siteexporter");
96                }
97
98                _.status(LANG.plugins.siteexport.loadingpage);
99                _.aggregatorStatus.removeClass('error').show();
100                _.aggregateForm.addClass('loading');
101                var settings = _.settings('__siteexport_aggregate');
102                var throbber = $('form#siteexport_site_aggregator :input[name=baseID], form#siteexport_site_aggregator :input[type=submit], form#siteexport_siteexporter :input[type=submit]').prop('disabled', true);
103                $.post( _.url, settings, function(data) {
104
105                    if ( data.match( new RegExp( 'mpdf error', 'i' ) ) ) {
106                        _.aggregatorStatus.addClass('error');
107                        _.status(data);
108                    } else {
109                        _.downloadFile({
110                                id : 'siteexport_site_aggregator_downloader',
111                                src: window.location.origin + data,
112                                root: 'div.siteexporter',
113                                timeout: function(){
114                                    _.aggregatorStatus.hide();
115                                }
116                        });
117                    }
118
119                }).fail(function(jqXHR){
120                    _.aggregatorStatus.addClass('error');
121                    _.status(jqXHR.responseText.replace("\n", "<br/>"));
122                }).always(function(){
123                    throbber.prop('disabled', false);
124                    _.aggregateForm.removeClass('loading');
125                });
126            };
127
128            _.downloadFile = function(iframeProps) {
129
130                    _.status(LANG.plugins.siteexport.startdownload);
131                    _.aggregateForm.addClass('download');
132                    if ( $.fileDownload ) {
133
134                        $.fileDownload(iframeProps.src).done(function(){
135                            _.status(LANG.plugins.siteexport.downloadfinished);
136
137                            if ( typeof iframeProps.timeout == 'function' ) {
138                                window.setTimeout(iframeProps.timeout, 2000);
139                            }
140
141                        }).fail(function(){
142                            _.error(LANG.plugins.siteexport.finishedbutdownloadfailed);
143                        }).always(function(){
144                            _.aggregateForm.removeClass('download');
145                        });
146
147                        return;
148                    }
149
150                    var frameQuery = "iframe#" + iframeProps.id;
151                    var frame = $(frameQuery);
152                    if ( frame.length == 0 ) {
153                        frame = $('<iframe/>')
154                        .hide()
155                        .appendTo(iframeProps.root)
156                        .prop({
157                            type : 'application/octet-stream',
158                            id : iframeProps.id
159                        });
160                    }
161
162                    // Downloads do not generate a load event
163                    frame.load(function(){
164                        _.status(LANG.plugins.siteexport.downloadfinished);
165
166                        // This must only happen when not downloading, meaning we have a PDF file.
167                        // ENSURE THIS IS THE ONLY CASE!
168                        // frame.remove();
169
170                        if ( $.popupviewer ) {
171
172                            var clone = frame.clone().css({
173                                border: 'none'
174                            }).show();
175
176                            frame.remove();
177                            _.aggregateForm.removeClass('download');
178
179                            var viewer = new $.popupviewer();
180                            viewer.showViewer();
181
182                            $("div#popupviewer div.content").html(clone);
183                            viewer.resizePopup($(window).width(), $(window).height(), null, clone, false, false);
184                        } else {
185                            // No Popup? Open right here
186                            document.location.href = iframeProps.src;
187                        }
188                    });
189
190                    frame.attr('src', iframeProps.src);
191                    if ( typeof iframeProps.timeout == 'function' ) {
192                        window.setTimeout(iframeProps.timeout, 2000);
193                    }
194
195                       $(window).unload(function(){
196                           // last resort or the frame might reload
197                           frame.remove();
198                       });
199            };
200
201            _.addSite = function(site) {
202
203                var settings = _.settings('__siteexport_addsite');
204                settings.push({
205                    name: 'site',
206                    value: site
207                },{
208                    name: 'pattern',
209                    value: this.pattern
210                },{
211                    name: 'base',
212                    value: DOKU_BASE
213                });
214
215                _.throbber(true);
216                $.post( _.url, settings, function(data) {
217                    _.zipURL = data.split("\n").pop();
218                    _.nextPage();
219                }).fail(function(jqXHR){
220                    _.errorLog(jqXHR.responseText);
221                    _.errorCount++;
222                }).always(function(){
223                    _.throbber(false);
224                });
225            };
226
227            _.nextPage = function() {
228                if (!this.allPages) {
229                    return;
230                }
231
232                var page = this.allPages.shift();
233
234                if (!page) {
235                    if (_.zipURL != "" && _.zipURL != 'undefined' && typeof _.zipURL != 'undefined' ) {
236
237                        _.downloadFile({
238                                id : 'siteexport_downloader',
239                                src: window.location.origin + _.zipURL,
240                                root: '#siteexport'
241                        });
242
243                    } else {
244                        _.status(LANG.plugins.siteexport.finishedbutdownloadfailed);
245                        _.errorLog(_.zipURL);
246                    }
247                    return;
248                }
249
250                if (!page) {
251                    this.nextPage();
252                }
253
254                _.status('Adding "' + page + '" ' + this.pages(this.currentCount++));
255                _.addSite(page);
256            };
257
258            _.pages = function() {
259                return '( '
260                        + _.currentCount
261                        + ' / '
262                        + _.pageCount
263                        + (_.errorCount && _.errorCount != 0 ? ' / <span style="color: #a00">' + _.errorCount + '</span>'
264                                : '') + ' )';
265            };
266
267            _.status = function(text) {
268                $('#siteexport__out').html(text).removeClass('error');
269            };
270
271            _.error = function(text) {
272                $('#siteexport__out').html(text).addClass('error');
273            };
274
275            _.settings = function(call) {
276                var settings = $(_.allElements).serializeArray();
277
278                /* Because serializeArray() ignores unset checkboxes and radio buttons: */
279                settings = settings.concat(
280                    $('form#siteexport label.sendIfNotSet input[type=checkbox]:not(:checked)').map(function() {
281                        return { "name": this.name, "value": '0' /* false */ }
282                    }).get()
283                );
284
285                if (call) { settings.push({ name: 'call', value: call}); }
286                if ( $('input#pdfExport:checked').length > 0 ) { settings.push({ name: 'renderer', value: 'siteexport_pdf'}); } // is disabled and would not get pushed
287                return settings;
288            };
289
290            _.cleanSettings = function(call) {
291
292                return _.settings(call).filter(function(element){
293
294                    if ( element.value == NS || element.value == JSINFO.id || element.value == JSINFO.namespace ) { element.name = null; }
295                    if ( !isNaN(element.value) ) { element.value = parseInt(element.value); }
296                    return element.name && _.forbidden_options.indexOf(element.name) < 0 && (element.value.length > 0 || (!isNaN(element.value) && element.value > 0));
297                });
298            };
299
300            /**
301             * Display the loading gif
302             */
303            _.throbberCount = 0;
304            _.throbber = function(on) {
305
306                _.throbberCount += (on?1:-1);
307                $('#siteexport__throbber').css('visibility', _.throbberCount>0 ? 'visible' : 'hidden');
308            };
309
310            _.resetDataForNewRequest = function() {
311
312                this.pageCount = 0;
313                this.currentCount = 0;
314                this.errorCount = 0;
315                this.allPages = [];
316                this.zipURL = '';
317                this.pattern = '';
318
319                this.status('');
320                this.resetErrorLog();
321            };
322
323            /**
324             * Log errors into container
325             */
326            _.errorLog = function(text) {
327
328                if (!text) {
329                    return;
330                }
331
332                if (!$('#siteexport__errorlog').length) {
333                    $('#siteexport__out').parent().append($('<div id="siteexport__errorlog"></div>'));
334                }
335
336                var msg = text.split("\n");
337                for ( var int = 0; int < msg.length; int++) {
338
339                    var txtMsg = msg[int];
340                    txtMsg = txtMsg.replace(new RegExp("^runtime error:", "i"), "");
341
342                    if (txtMsg.length == 0) {
343                        continue;
344                    }
345
346                    $('#siteexport__errorlog').append($('<p></p>').text(txtMsg.replace(new RegExp(
347                            "</?.*?>", "ig"), "")));
348                }
349            };
350
351            _.resetErrorLog = function() {
352                $('#siteexport__errorlog').remove();
353            };
354
355            _.toggleDisableAllPlugins = function(input) {
356                $('#siteexport :input[name=disableplugin\\[\\]]:not([disabled=disabled])').prop('checked', input.checked);
357            };
358
359
360            _.addCustomOption = function(nameVal, valueVal) {
361
362                if ( typeof nameVal == 'undefined' )
363                {
364                    nameVal = 'name';
365                }
366
367                if ( typeof valueVal == 'undefined' )
368                {
369                    valueVal = 'value';
370                }
371
372
373                var regenerate = function(event) {
374                    event.stopPropagation();
375                    _.generate();
376                };
377
378                var customOption = $('<input type="hidden"/>').attr({ name: nameVal, value: valueVal});
379                var name = $('<input/>').addClass('edit dummy').attr({ value: nameVal}).change(function(event)
380                {
381                    customOption.attr({ name: this.value }); regenerate(event);
382                }).click(function(){this.select();});
383                var value = $('<input/>').addClass('edit dummy').attr({ value: valueVal}).change(function(event)
384                {
385                    customOption.attr({ value: this.value }); regenerate(event);
386                }).click(function(){this.select();});
387
388
389                $('<li/>').append(name).append(value).append(customOption).appendTo('#siteexport__customActions');
390            };
391
392            _.updateValue = function( elem, value ) {
393                if ( !elem.length ) {
394                    return;
395                }
396                switch(elem[0].type) {
397                    case 'checkbox': elem.prop('checked', elem.val() == value); break;
398                    case 'select-one':
399                    case 'select': {
400
401                        var selected = false;
402                        elem.find('option').each(function(){
403                            if ( $(this).val() == value ) {
404                                $(this).prop('selected', true);
405                                selected = true;
406                                return false;
407                            }
408                            return true;
409                        });
410
411                        if ( !selected && !isNaN(value) ) {
412                            elem.find('option:eq('+value+')').prop('selected', true);
413                        }
414
415                         break;
416                    }
417                    default: elem.val(value);
418                }
419            };
420
421            _.setValues = function(values) {
422
423                $(_.allElements + ':not(:checkbox)').val(null);
424                $(_.allElements + ':checkbox').prop('checked', false);
425                $('#siteexport__customActions').html("");
426
427                _.suspendGenerate = true;
428                for ( var node in values ) {
429
430                    if ( !values.hasOwnProperty(node)) {
431                        continue; // Skip keys from the prototype.
432                    }
433
434                    var value = values[node];
435                    if ( typeof value == 'object' ) {
436                        for ( var val in value ) {
437                            if ( !value.hasOwnProperty(val)) {
438                                continue; // Skip keys from the prototype.
439                            }
440                            _.updateValue($('#siteexport #'+node+'_'+value[val]+':input[name='+node+'\\[\\]]'), value[val]);
441                        }
442                    } else {
443                        _.updateValue($('#siteexport :input[name='+node+']'), value);
444                    }
445                }
446
447                // Custom Options
448                for ( var index in values['customoptionname'] ) {
449
450                    if ( !values['customoptionname'].hasOwnProperty(index)) {
451                        continue; // Skip keys from the prototype.
452                    }
453
454                    try {
455                        _.addCustomOption(values['customoptionname'][index], values['customoptionvalue'][index]);
456                    } catch (e) {
457                        _.errorLog(e);
458                    }
459                }
460
461                _.suspendGenerate = false;
462            };
463
464        }(SiteexportAdmin.prototype));
465
466        var __siteexport = null;
467        $.siteexport = function() {
468            if ( __siteexport == null ) {
469                __siteexport = new SiteexportAdmin();
470            }
471
472            return __siteexport;
473        };
474
475        $.siteexport().generate();
476        $('#siteexport :input').each(function(){
477            $(this).change(function(event){
478                event.stopPropagation();
479                $.siteexport().generate();
480            });
481        });
482
483        $('form#siteexport :input[type=submit][name~=do\\[siteexport\\]]').click(function(event){
484            event.stopPropagation();
485            $.siteexport().run();
486            return false;
487        });
488
489        $('form#siteexport_site_aggregator :input[type=submit][name~=do\\[siteexport\\]], form#siteexport_siteexporter :input[type=submit][name~=do\\[siteexport\\]]').click(function(event){
490            event.stopPropagation();
491            $.siteexport().runAggregator();
492            return false;
493        });
494
495        $('form#siteexport #depthType:input').change(function(event){
496            event.stopPropagation();
497            if ( parseInt($(this).val()) == 2 ) {
498                $('div#depthContainer').show();
499            } else {
500                $('div#depthContainer').hide();
501            }
502        });
503
504
505        $('form#siteexport #pdfExport:input').change(function(event){
506            event.stopPropagation();
507            $('form#siteexport #renderer').find('option[value=siteexport_pdf]').prop('selected', this.checked);
508            $('form#siteexport #renderer').prop('disabled', this.checked);
509        });
510
511        $('form#siteexport select#renderer').change(function(event){
512            event.stopPropagation();
513            $('form#siteexport #pdfExport:input, form#siteexport select#template').prop('disabled', $(this).prop('value') == 'dw2pdf');
514        });
515
516
517        $('form#siteexport #disableall:input').change(function(event){
518            event.stopPropagation();
519            $.siteexport().toggleDisableAllPlugins(this);
520        });
521
522        $('form#siteexport :input[name=disableplugin\\[\\]]').change(function(event){
523            event.stopPropagation();
524
525            if ( !this.checked && $('form#siteexport #disableall:input').prop('checked') ) {
526                $('form#siteexport #disableall:input').prop('checked', false);
527            }
528        });
529
530        $('form#siteexport :input[type=submit][name=do\\[addoption\\]]').click(function(event){
531            event.stopPropagation();
532            $.siteexport().addCustomOption();
533            return false;
534        });
535    });
536})(jQuery);
537
538var copyMapIDToClipBoard = function() {
539    var $this = jQuery(this);
540    var $mapID = $this.find('span.mapID');
541    var range, selection, ok;
542
543    if (window.getSelection && document.createRange) {
544        selection = window.getSelection();
545        range = document.createRange();
546        range.selectNodeContents($mapID.get(0));
547        selection.removeAllRanges();
548        selection.addRange(range);
549    } else if (document.selection && document.body.createTextRange) {
550        range = document.body.createTextRange();
551        range.moveToElementText($mapID.get(0));
552        range.select();
553    }
554    // Use try & catch for unsupported browser
555    try {
556        // The important part (copy selected text)
557        ok = document.execCommand('copy');
558    } catch (err) {
559        // Ignore if it does not work.
560    }
561
562    if (ok) {
563        $mapID.addClass('done');
564        setTimeout(function(){
565            $mapID.removeClass('done');
566        }, 1000);
567    }
568};