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