Completed
Push — stable9 ( 485cb1...e094cf )
by Lukas
26:41 queued 26:23
created

apps/files_sharing/js/public.js (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
/*
2
 * Copyright (c) 2014
3
 *
4
 * This file is licensed under the Affero General Public License version 3
5
 * or later.
6
 *
7
 * See the COPYING-README file.
8
 *
9
 */
10
11
/* global FileActions, Files, FileList */
12
/* global dragOptions, folderDropOptions */
13
if (!OCA.Sharing) {
14
	OCA.Sharing = {};
15
}
16
if (!OCA.Files) {
17
	OCA.Files = {};
18
}
19
/**
20
 * @namespace
21
 */
22
OCA.Sharing.PublicApp = {
23
	_initialized: false,
24
25
	/**
26
	 * Initializes the public share app.
27
	 *
28
	 * @param $el container
29
	 */
30
	initialize: function ($el) {
31
		var self = this;
32
		var fileActions;
33
		if (this._initialized) {
34
			return;
35
		}
36
		fileActions = new OCA.Files.FileActions();
37
		// default actions
38
		fileActions.registerDefaultActions();
39
		// legacy actions
40
		fileActions.merge(window.FileActions);
41
		// regular actions
42
		fileActions.merge(OCA.Files.fileActions);
43
44
		// in case apps would decide to register file actions later,
45
		// replace the global object with this one
46
		OCA.Files.fileActions = fileActions;
47
48
		this._initialized = true;
49
		this.initialDir = $('#dir').val();
50
51
		var token = $('#sharingToken').val();
52
53
		// file list mode ?
54
		if ($el.find('#filestable').length) {
55
			var filesClient = new OC.Files.Client({
56
				host: OC.getHost(),
57
				port: OC.getPort(),
58
				userName: token,
59
				// note: password not be required, the endpoint
60
				// will recognize previous validation from the session
61
				root: OC.getRootPath() + '/public.php/webdav',
62
				useHTTPS: OC.getProtocol() === 'https'
63
			});
64
65
			this.fileList = new OCA.Files.FileList(
66
				$el,
67
				{
68
					id: 'files.public',
69
					scrollContainer: $('#content-wrapper'),
70
					dragOptions: dragOptions,
71
					folderDropOptions: folderDropOptions,
72
					fileActions: fileActions,
73
					detailsViewEnabled: false,
74
					filesClient: filesClient
75
				}
76
			);
77
			this.files = OCA.Files.Files;
78
			this.files.initialize();
79
			// TODO: move to PublicFileList.initialize() once
80
			// the code was split into a separate class
81
			OC.Plugins.attach('OCA.Sharing.PublicFileList', this.fileList);
82
		}
83
84
		var mimetype = $('#mimetype').val();
85
		var mimetypeIcon = $('#mimetypeIcon').val();
86
		mimetypeIcon = mimetypeIcon.substring(0, mimetypeIcon.length - 3);
87
		mimetypeIcon = mimetypeIcon + 'svg';
88
89
		var previewSupported = $('#previewSupported').val();
90
91
		if (typeof FileActions !== 'undefined') {
92
			// Show file preview if previewer is available, images are already handled by the template
93
			if (mimetype.substr(0, mimetype.indexOf('/')) !== 'image' && $('.publicpreview').length === 0) {
94
				// Trigger default action if not download TODO
95
				var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ);
96
				if (typeof action !== 'undefined') {
97
					action($('#filename').val());
98
				}
99
			}
100
		}
101
102
103
		// dynamically load image previews
104
		var bottomMargin = 350;
105
		var previewWidth = $(window).width();
106
		var previewHeight = $(window).height() - bottomMargin;
107
		previewHeight = Math.max(200, previewHeight);
108
		var params = {
109
			x: Math.ceil(previewWidth * window.devicePixelRatio),
110
			y: Math.ceil(previewHeight * window.devicePixelRatio),
111
			a: 'true',
112
			file: encodeURIComponent(this.initialDir + $('#filename').val()),
113
			t: token,
114
			scalingup: 0
115
		};
116
117
		var img = $('<img class="publicpreview" alt="">');
118
		img.css({
119
			'max-width': previewWidth,
120
			'max-height': previewHeight
121
		});
122
123
		var fileSize = parseInt($('#filesize').val(), 10);
124
		var maxGifSize = parseInt($('#maxSizeAnimateGif').val(), 10);
125
126
		if (mimetype === 'image/gif' &&
127
			(maxGifSize === -1 || fileSize <= (maxGifSize * 1024 * 1024))) {
128
			img.attr('src', $('#downloadURL').val());
129
			img.appendTo('#imgframe');
130
		} else if (mimetype.substr(0, mimetype.indexOf('/')) === 'text' && window.btoa) {
131
			// Undocumented Url to public WebDAV endpoint
132
			var url = parent.location.protocol + '//' + location.host + OC.linkTo('', 'public.php/webdav');
133
			$.ajax({
134
				url: url,
135
				headers: {
136
					Authorization: 'Basic ' + btoa(token + ':'),
137
					Range: 'bytes=0-1000'
138
				}
139
			}).then(function (data) {
140
				self._showTextPreview(data, previewHeight);
141
			});
142
		} else if (previewSupported === 'true' ||
143
			mimetype.substr(0, mimetype.indexOf('/')) === 'image' &&
144
			mimetype !== 'image/svg+xml') {
145
			img.attr('src', OC.filePath('files_sharing', 'ajax', 'publicpreview.php') + '?' + OC.buildQueryString(params));
146
			img.appendTo('#imgframe');
147
		} else if (mimetype.substr(0, mimetype.indexOf('/')) !== 'video') {
148
			img.attr('src', OC.Util.replaceSVGIcon(mimetypeIcon));
149
			img.attr('width', 128);
150
			img.appendTo('#imgframe');
151
		}
152
153
		if (this.fileList) {
154
			// TODO: move this to a separate PublicFileList class that extends OCA.Files.FileList (+ unit tests)
155
			this.fileList.getDownloadUrl = function (filename, dir, isDir) {
0 ignored issues
show
isDir does not seem to be used.
Loading history...
156
				var path = dir || this.getCurrentDirectory();
157
				if (_.isArray(filename)) {
158
					filename = JSON.stringify(filename);
159
				}
160
				var params = {
161
					path: path
162
				};
163
				if (filename) {
164
					params.files = filename;
165
				}
166
				return OC.generateUrl('/s/' + token + '/download') + '?' + OC.buildQueryString(params);
167
			};
168
169
			this.fileList.getAjaxUrl = function (action, params) {
170
				params = params || {};
171
				params.t = token;
172
				return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params);
173
			};
174
175
			this.fileList.linkTo = function (dir) {
176
				return OC.generateUrl('/s/' + token + '', {dir: dir});
177
			};
178
179
			this.fileList.generatePreviewUrl = function (urlSpec) {
180
				urlSpec = urlSpec || {};
181
				if (!urlSpec.x) {
182
					urlSpec.x = 32;
183
				}
184
				if (!urlSpec.y) {
185
					urlSpec.y = 32;
186
				}
187
				urlSpec.x *= window.devicePixelRatio;
188
				urlSpec.y *= window.devicePixelRatio;
189
				urlSpec.x = Math.ceil(urlSpec.x);
190
				urlSpec.y = Math.ceil(urlSpec.y);
191
				urlSpec.t = $('#dirToken').val();
192
				return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec);
193
			};
194
195
			this.fileList.updateEmptyContent = function() {
196
				this.$el.find('#emptycontent .uploadmessage').text(
197
					t('files_sharing', 'You can upload into this folder')
198
				);
199
				OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments);
200
			};
201
202
			var file_upload_start = $('#file_upload_start');
0 ignored issues
show
Identifier 'file_upload_start' is not in camel case.
Loading history...
203
			file_upload_start.on('fileuploadadd', function (e, data) {
204
				var fileDirectory = '';
205
				if (typeof data.files[0].relativePath !== 'undefined') {
206
					fileDirectory = data.files[0].relativePath;
207
				}
208
209
				// Add custom data to the upload handler
210
				data.formData = {
211
					requesttoken: $('#publicUploadRequestToken').val(),
212
					dirToken: $('#dirToken').val(),
213
					subdir: data.targetDir || self.fileList.getCurrentDirectory(),
214
					file_directory: fileDirectory
215
				};
216
			});
217
218
			// do not allow sharing from the public page
219
			delete this.fileList.fileActions.actions.all.Share;
220
221
			this.fileList.changeDirectory(this.initialDir || '/', false, true);
222
223
			// URL history handling
224
			this.fileList.$el.on('changeDirectory', _.bind(this._onDirectoryChanged, this));
225
			OC.Util.History.addOnPopStateHandler(_.bind(this._onUrlChanged, this));
226
227
			$('#download').click(function (e) {
228
				e.preventDefault();
229
				OC.redirect(FileList.getDownloadUrl());
230
			});
231
		}
232
233
		$(document).on('click', '#directLink', function () {
234
			$(this).focus();
235
			$(this).select();
236
		});
237
238
		$('.save-form').submit(function (event) {
239
			event.preventDefault();
240
241
			var remote = $(this).find('input[type="text"]').val();
242
			var token = $('#sharingToken').val();
243
			var owner = $('#save').data('owner');
244
			var ownerDisplayName = $('#save').data('owner-display-name');
245
			var name = $('#save').data('name');
246
			var isProtected = $('#save').data('protected') ? 1 : 0;
247
			OCA.Sharing.PublicApp._saveToOwnCloud(remote, token, owner, ownerDisplayName, name, isProtected);
248
		});
249
250
		$('#remote_address').on("keyup paste", function() {
251
			if ($(this).val() === '') {
252
				$('#save-button-confirm').prop('disabled', true);
253
			} else {
254
				$('#save-button-confirm').prop('disabled', false);
255
			}
256
		});
257
258
		$('#save #save-button').click(function () {
259
			$(this).hide();
260
			$('.save-form').css('display', 'inline');
261
			$('#remote_address').focus();
262
		});
263
264
		// legacy
265
		window.FileList = this.fileList;
266
	},
267
268
	_showTextPreview: function (data, previewHeight) {
269
		var textDiv = $('<div/>').addClass('text-preview');
270
		textDiv.text(data);
271
		textDiv.appendTo('#imgframe');
272
		var divHeight = textDiv.height();
273
		if (data.length > 999) {
274
			var ellipsis = $('<div/>').addClass('ellipsis');
275
			ellipsis.html('(&#133;)');
276
			ellipsis.appendTo('#imgframe');
277
		}
278
		if (divHeight > previewHeight) {
279
			textDiv.height(previewHeight);
280
		}
281
	},
282
283
	_onDirectoryChanged: function (e) {
284
		OC.Util.History.pushState({
285
			// arghhhh, why is this not called "dir" !?
286
			path: e.dir
287
		});
288
	},
289
290
	_onUrlChanged: function (params) {
291
		this.fileList.changeDirectory(params.path || params.dir, false, true);
292
	},
293
294
	_saveToOwnCloud: function (remote, token, owner, ownerDisplayName, name, isProtected) {
0 ignored issues
show
This function has too many parameters. (6)
Loading history...
295
		var location = window.location.protocol + '//' + window.location.host + OC.webroot;
296
		
297
		if(remote.substr(-1) !== '/') {
298
			remote += '/'
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
299
		};
300
301
		var url = remote + 'index.php/apps/files#' + 'remote=' + encodeURIComponent(location) // our location is the remote for the other server
0 ignored issues
show
Line is too long.
Loading history...
302
			+ "&token=" + encodeURIComponent(token) + "&owner=" + encodeURIComponent(owner) +"&ownerDisplayName=" + encodeURIComponent(ownerDisplayName) + "&name=" + encodeURIComponent(name) + "&protected=" + isProtected;
0 ignored issues
show
Line is too long.
Loading history...
303
304
305
		if (remote.indexOf('://') > 0) {
306
			OC.redirect(url);
307
		} else {
308
			// if no protocol is specified, we automatically detect it by testing https and http
309
			// this check needs to happen on the server due to the Content Security Policy directive
310
			$.get(OC.generateUrl('apps/files_sharing/testremote'), {remote: remote}).then(function (protocol) {
311
				if (protocol !== 'http' && protocol !== 'https') {
312
					OC.dialogs.alert(t('files_sharing', 'No ownCloud installation (7 or higher) found at {remote}', {remote: remote}),
313
						t('files_sharing', 'Invalid ownCloud url'));
314
				} else {
315
					OC.redirect(protocol + '://' + url);
316
				}
317
			});
318
		}
319
	}
320
};
321
322
$(document).ready(function () {
323
	// FIXME: replace with OC.Plugins.register()
324
	if (window.TESTING) {
325
		return;
326
	}
327
328
	var App = OCA.Sharing.PublicApp;
329
	// defer app init, to give a chance to plugins to register file actions
330
	_.defer(function () {
331
		App.initialize($('#preview'));
332
	});
333
334
	if (window.Files) {
335
		// HACK: for oc-dialogs previews that depends on Files:
336
		Files.generatePreviewUrl = function (urlSpec) {
337
			return App.fileList.generatePreviewUrl(urlSpec);
338
		};
339
	}
340
});
341
342