PageSourceSearch

https://nube2.aevivienda.gob.bo/apps/files_sharing/js/public.js?v=3fb38e56-57

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

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.