PageSourceSearch

https://cloud.pa-nunukan.go.id/apps/files_sharing/js/public.js?v=1d0b5643-136

js pa-nunukan.go.id collected 2026-10-02 00:10:01 UTC 15,298 bytes, 495 lines download raw bytes

1/*
2 * Copyright (c) 2014
3 * @copyright Copyright (c) 2016, Björn Schießle <[email protected]>
4 *
5 * This file is licensed under the Affero General Public License version 3
6 * or later.
7 *
8 * See the COPYING-README file.
9 *
10 */
11
12/* global FileActions, Files, FileList */
13/* global dragOptions, folderDropOptions */
14if (!OCA.Sharing) {
15	OCA.Sharing = {};
16}
17if (!OCA.Files) {
18	OCA.Files = {};
19}
20/**
21 * @namespace
22 */
23OCA.Sharing.PublicApp = {
24	_initialized: false,
25
26	/**
27	 * Initializes the public share app.
28	 *
29	 * @param $el container
30	 */
31	initialize: function ($el) {
32		var self = this;
33		var fileActions;
34		if (this._initialized) {
35			return;
36		}
37		fileActions = new OCA.Files.FileActions();
38		// default actions
39		fileActions.registerDefaultActions();
40		// legacy actions
41		fileActions.merge(window.FileActions);
42		// regular actions
43		fileActions.merge(OCA.Files.fileActions);
44
45		// in case apps would decide to register file actions later,
46		// replace the global object with this one
47		OCA.Files.fileActions = fileActions;
48
49		this._initialized = true;
50		this.initialDir = $('#dir').val();
51
52		var token = $('#sharingToken').val();
53		var hideDownload = $('#hideDownload').val();
54
55
56		// file list mode ?
57		if ($el.find('#filestable').length) {
58			var filesClient = new OC.Files.Client({
59				host: OC.getHost(),
60				port: OC.getPort(),
61				userName: token,
62				// note: password not be required, the endpoint
63				// will recognize previous validation from the session
64				root: OC.getRootPath() + '/public.php/webdav',
65				useHTTPS: OC.getProtocol() === 'https'
66			});
67
68			this.fileList = new OCA.Files.FileList(
69				$el,
70				{
71					id: 'files.public',
72					dragOptions: dragOptions,
73					folderDropOptions: folderDropOptions,
74					fileActions: fileActions,
75					detailsViewEnabled: false,
76					filesClient: filesClient,
77					enableUpload: true,
78					multiSelectMenu: [
79						{
80								name: 'copyMove',
81								displayName:  t('files', 'Move or copy'),
82								iconClass: 'icon-external',
83						},
84						{
85								name: 'download',
86								displayName:  t('files', 'Download'),
87								iconClass: 'icon-download',
88						},
89						{
90								name: 'delete',
91								displayName: t('files', 'Delete'),
92								iconClass: 'icon-delete',
93						}
94					]
95				}
96			);
97			if (hideDownload === 'true') {
98				this.fileList._allowSelection = false;
99			}
100			this.files = OCA.Files.Files;
101			this.files.initialize();
102			// TODO: move to PublicFileList.initialize() once
103			// the code was split into a separate class
104			OC.Plugins.attach('OCA.Sharing.PublicFileList', this.fileList);
105		}
106
107		var mimetype = $('#mimetype').val();
108		var mimetypeIcon = $('#mimetypeIcon').val();
109		mimetypeIcon = mimetypeIcon.substring(0, mimetypeIcon.length - 3);
110		mimetypeIcon = mimetypeIcon + 'svg';
111
112		var previewSupported = $('#previewSupported').val();
113
114		if (typeof FileActions !== 'undefined') {
115			// Show file preview if previewer is available, images are already handled by the template
116			if (mimetype.substr(0, mimetype.indexOf('/')) !== 'image' && $('.publicpreview').length === 0) {
117				// Trigger default action if not download TODO
118				var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ);
119				if (typeof action !== 'undefined') {
120					action($('#filename').val());
121				}
122			}
123		}
124
125
126		// dynamically load image previews
127		var bottomMargin = 350;
128		var previewWidth = $(window).width();
129		var previewHeight = $(window).height() - bottomMargin;
130		previewHeight = Math.max(200, previewHeight);
131		var params = {
132			x: Math.ceil(previewWidth * window.devicePixelRatio),
133			y: Math.ceil(previewHeight * window.devicePixelRatio),
134			a: 'true',
135			file: encodeURIComponent(this.initialDir + $('#filename').val()),
136			scalingup: 0
137		};
138
139		var imgcontainer = $('<img class="publicpreview" alt="">');
140		if (hideDownload === 'false') {
141			imgcontainer = $('<a href="' + $('#previewURL').val() + '" target="_blank"></a>').append(imgcontainer);
142		}
143		var img = imgcontainer.hasClass('publicpreview')? imgcontainer: imgcontainer.find('.publicpreview');
144		img.css({
145			'max-width': previewWidth,
146			'max-height': previewHeight
147		});
148
149		var fileSize = parseInt($('#filesize').val(), 10);
150		var maxGifSize = parseInt($('#maxSizeAnimateGif').val(), 10);
151
152		if (mimetype === 'image/gif' &&
153			(maxGifSize === -1 || fileSize <= (maxGifSize * 1024 * 1024))) {
154			img.attr('src', $('#downloadURL').val());
155			imgcontainer.appendTo('#imgframe');
156		} else if (mimetype.substr(0, mimetype.indexOf('/')) === 'text' && window.btoa) {
157			if (OC.appswebroots['files_texteditor'] !== undefined) {
158				// the text editor handles the previewing
159				return;
160			}
161			// Undocumented Url to public WebDAV endpoint
162			var url = parent.location.protocol + '//' + location.host + OC.linkTo('', 'public.php/webdav');
163			$.ajax({
164				url: url,
165				headers: {
166					Authorization: 'Basic ' + btoa(token + ':'),
167					Range: 'bytes=0-1000'
168				}
169			}).then(function (data) {
170				self._showTextPreview(data, previewHeight);
171			});
172		} else if ((previewSupported === 'true' && mimetype.substr(0, mimetype.indexOf('/')) !== 'video') ||
173			mimetype.substr(0, mimetype.indexOf('/')) === 'image' &&
174			mimetype !== 'image/svg+xml') {
175			img.attr('src', OC.generateUrl('/apps/files_sharing/publicpreview/' + token + '?' + OC.buildQueryString(params)));
176			imgcontainer.appendTo('#imgframe');
177		} else if (mimetype.substr(0, mimetype.indexOf('/')) !== 'video') {
178			img.attr('src', mimetypeIcon);
179			img.attr('width', 128);
180			// "#imgframe" is either empty or it contains an audio preview that
181			// the icon should appear before, so the container should be
182			// prepended to the frame.
183			imgcontainer.prependTo('#imgframe');
184		}
185		else if (previewSupported === 'true') {
186			$('#imgframe > video').attr('poster', OC.generateUrl('/apps/files_sharing/publicpreview/' + token + '?' + OC.buildQueryString(params)));
187		}
188
189		if (this.fileList) {
190			// TODO: move this to a separate PublicFileList class that extends OCA.Files.FileList (+ unit tests)
191			this.fileList.getDownloadUrl = function (filename, dir, isDir) {
192				var path = dir || this.getCurrentDirectory();
193				if (_.isArray(filename)) {
194					filename = JSON.stringify(filename);
195				}
196				var params = {
197					path: path
198				};
199				if (filename) {
200					params.files = filename;
201				}
202				return OC.generateUrl('/s/' + token + '/download') + '?' + OC.buildQueryString(params);
203			};
204
205			this.fileList._createRow = function(fileData) {
206				var $tr = OCA.Files.FileList.prototype._createRow.apply(this, arguments);
207				if (hideDownload === 'true') {
208					this.fileActions.currentFile = $tr.find('td');
209					var mime = this.fileActions.getCurrentMimeType();
210					var type = this.fileActions.getCurrentType();
211					var permissions = this.fileActions.getCurrentPermissions();
212					var action = this.fileActions.getDefault(mime, type, permissions);
213
214					// Remove the link. This means that files without a default action fail hard
215					$tr.find('a.name').attr('href', '#');
216
217					this.fileActions.actions.all = {};
218				}
219				return $tr;
220			};
221
222			this.fileList.isSelectedDownloadable = function () {
223				return hideDownload !== 'true';
224			};
225
226			this.fileList.getUploadUrl = function(fileName, dir) {
227				if (_.isUndefined(dir)) {
228					dir = this.getCurrentDirectory();
229				}
230
231				var pathSections = dir.split('/');
232				if (!_.isUndefined(fileName)) {
233					pathSections.push(fileName);
234				}
235				var encodedPath = '';
236				_.each(pathSections, function(section) {
237					if (section !== '') {
238						encodedPath += '/' + encodeURIComponent(section);
239					}
240				});
241				var base = '';
242
243				if (!this._uploader.isXHRUpload()) {
244					// also add auth in URL due to POST workaround
245					base = OC.getProtocol() + '://' + token + '@' + OC.getHost() + (OC.getPort() ? ':' + OC.getPort() : '');
246				}
247				return base + OC.getRootPath() + '/public.php/webdav' + encodedPath;
248			};
249
250			this.fileList.getAjaxUrl = function (action, params) {
251				params = params || {};
252				params.t = token;
253				return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params);
254			};
255
256			this.fileList.linkTo = function (dir) {
257				return OC.generateUrl('/s/' + token + '', {dir: dir});
258			};
259
260			this.fileList.generatePreviewUrl = function (urlSpec) {
261				urlSpec = urlSpec || {};
262				if (!urlSpec.x) {
263					urlSpec.x = this.$table.data('preview-x') || 250;
264				}
265				if (!urlSpec.y) {
266					urlSpec.y = this.$table.data('preview-y') || 250;
267				}
268				urlSpec.x *= window.devicePixelRatio;
269				urlSpec.y *= window.devicePixelRatio;
270				urlSpec.x = Math.ceil(urlSpec.x);
271				urlSpec.y = Math.ceil(urlSpec.y);
272				var token = $('#dirToken').val();
273				return OC.generateUrl('/apps/files_sharing/publicpreview/' + token + '?' + OC.buildQueryString(urlSpec));
274			};
275
276			this.fileList.updateEmptyContent = function() {
277				this.$el.find('#emptycontent .uploadmessage').text(
278					t('files_sharing', 'You can upload into this folder')
279				);
280				OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments);
281			};
282
283			this.fileList._uploader.on('fileuploadadd', function(e, data) {
284				if (!data.headers) {
285					data.headers = {};
286				}
287
288				data.headers.Authorization = 'Basic ' + btoa(token + ':');
289			});
290
291			// do not allow sharing from the public page
292			delete this.fileList.fileActions.actions.all.Share;
293
294			this.fileList.changeDirectory(this.initialDir || '/', false, true);
295
296			// URL history handling
297			this.fileList.$el.on('changeDirectory', _.bind(this._onDirectoryChanged, this));
298			OC.Util.History.addOnPopStateHandler(_.bind(this._onUrlChanged, this));
299
300			$('#download').click(function (e) {
301				e.preventDefault();
302				OC.redirect(FileList.getDownloadUrl());
303			});
304
305			if (hideDownload === 'true') {
306				this.fileList.$el.find('#headerSelection').remove();
307				this.fileList.$el.find('.summary').find('td:first-child').remove();
308			}
309		}
310
311		$(document).on('click', '#directLink', function () {
312			$(this).focus();
313			$(this).select();
314		});
315
316		$('.save-form').submit(function (event) {
317			event.preventDefault();
318
319			var remote = $(this).find('#remote_address').val();
320			var token = $('#sharingToken').val();
321			var owner = $('#save-external-share').data('owner');
322			var ownerDisplayName = $('#save-external-share').data('owner-display-name');
323			var name = $('#save-external-share').data('name');
324			var isProtected = $('#save-external-share').data('protected') ? 1 : 0;
325			OCA.Sharing.PublicApp._createFederatedShare(remote, token, owner, ownerDisplayName, name, isProtected);
326		});
327
328		$('#remote_address').on("keyup paste", function() {
329			if ($(this).val() === '' || $('#save-external-share > .icon.icon-loading-small').length > 0) {
330				$('#save-button-confirm').prop('disabled', true);
331			} else {
332				$('#save-button-confirm').prop('disabled', false);
333			}
334		});
335
336		self._bindShowTermsAction();
337
338		// legacy
339		window.FileList = this.fileList;
340	},
341
342	/**
343	 * Binds the click action for the "terms of service" action.
344	 * Shows an OC info dialog on click.
345	 *
346	 * @private
347	 */
348	_bindShowTermsAction: function() {
349		$('#show-terms-dialog').on('click', function() {
350			OC.dialogs.info($('#disclaimerText').val(), t('files_sharing', 'Terms of service'));
351		});
352	},
353
354	_showTextPreview: function (data, previewHeight) {
355		var textDiv = $('<div/>').addClass('text-preview');
356		textDiv.text(data);
357		textDiv.appendTo('#imgframe');
358		var divHeight = textDiv.height();
359		if (data.length > 999) {
360			var ellipsis = $('<div/>').addClass('ellipsis');
361			ellipsis.html('(&#133;)');
362			ellipsis.appendTo('#imgframe');
363		}
364		if (divHeight > previewHeight) {
365			textDiv.height(previewHeight);
366		}
367	},
368
369	_onDirectoryChanged: function (e) {
370		OC.Util.History.pushState({
371			// arghhhh, why is this not called "dir" !?
372			path: e.dir
373		});
374	},
375
376	_onUrlChanged: function (params) {
377		this.fileList.changeDirectory(params.path || params.dir, false, true);
378	},
379
380
381	/**
382	 * fall back to old behaviour where we redirect the user to his server to mount
383	 * the public link instead of creating a dedicated federated share
384	 *
385	 * @param remote
386	 * @param token
387	 * @param owner
388	 * @param ownerDisplayName
389	 * @param name
390	 * @param isProtected
391	 * @private
392	 */
393	_legacyCreateFederatedShare: function (remote, token, owner, ownerDisplayName, name, isProtected) {
394
395		var self = this;
396		var location = window.location.protocol + '//' + window.location.host + OC.getRootPath();
397
398		if(remote.substr(-1) !== '/') {
399			remote += '/'
400		}
401
402		var url = remote + 'index.php/apps/files#' + 'remote=' + encodeURIComponent(location) // our location is the remote for the other server
403			+ "&token=" + encodeURIComponent(token) + "&owner=" + encodeURIComponent(owner) +"&ownerDisplayName=" + encodeURIComponent(ownerDisplayName) + "&name=" + encodeURIComponent(name) + "&protected=" + isProtected;
404
405
406		if (remote.indexOf('://') > 0) {
407			OC.redirect(url);
408		} else {
409			// if no protocol is specified, we automatically detect it by testing https and http
410			// this check needs to happen on the server due to the Content Security Policy directive
411			$.get(OC.generateUrl('apps/files_sharing/testremote'), {remote: remote}).then(function (protocol) {
412				if (protocol !== 'http' && protocol !== 'https') {
413					self._toggleLoading();
414					OC.dialogs.alert(t('files_sharing', 'No compatible server found at {remote}', {remote: remote}),
415						t('files_sharing', 'Invalid server URL'));
416				} else {
417					OC.redirect(protocol + '://' + url);
418				}
419			});
420		}
421	},
422
423	_toggleLoading: function() {
424		var loading = $('#save-external-share > .icon.icon-loading-small').length === 0;
425		if (loading) {
426			$('#save-external-share > .icon-external')
427				.removeClass("icon-external")
428				.addClass("icon-loading-small");
429			$('#save-external-share #save-button-confirm').prop("disabled", true);
430
431		} else {
432			$('#save-external-share > .icon-loading-small')
433				.addClass("icon-external")
434				.removeClass("icon-loading-small");
435			$('#save-external-share #save-button-confirm').prop("disabled", false);
436
437		}
438	},
439
440	_createFederatedShare: function (remote, token, owner, ownerDisplayName, name, isProtected) {
441		var self = this;
442
443		this._toggleLoading();
444
445		if (remote.indexOf('@') === -1) {
446			this._legacyCreateFederatedShare(remote, token, owner, ownerDisplayName, name, isProtected);
447			return;
448		}
449
450		$.post(
451			OC.generateUrl('/apps/federatedfilesharing/createFederatedShare'),
452			{
453				'shareWith': remote,
454				'token': token
455			}
456		).done(
457			function (data) {
458				var url = data.remoteUrl;
459
460				if (url.indexOf('://') > 0) {
461					OC.redirect(url);
462				} else {
463					OC.redirect('http://' + url);
464				}
465			}
466		).fail(
467			function (jqXHR) {
468				OC.dialogs.alert(JSON.parse(jqXHR.responseText).message,
469					t('files_sharing', 'Failed to add the public link to your Nextcloud'));
470				self._toggleLoading();
471			}
472		);
473	}
474};
475
476$(document).ready(function () {
477	// FIXME: replace with OC.Plugins.register()
478	if (window.TESTING) {
479		return;
480	}
481
482	var App = OCA.Sharing.PublicApp;
483	// defer app init, to give a chance to plugins to register file actions
484	_.defer(function () {
485		App.initialize($('#preview'));
486	});
487
488	if (window.Files) {
489		// HACK: for oc-dialogs previews that depends on Files:
490		Files.generatePreviewUrl = function (urlSpec) {
491			return App.fileList.generatePreviewUrl(urlSpec);
492		};
493	}
494
495});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.