From e4b1d135a5dea4b51fd913e44a9a2c80698bd51c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 25 Nov 2020 16:36:30 +0100 Subject: [PATCH 1/2] formatting remote sharer should take protocol, path into account Signed-off-by: Arthur Schiwon --- apps/files_sharing/src/share.js | 237 ++++++++++++++++---------------- 1 file changed, 120 insertions(+), 117 deletions(-) diff --git a/apps/files_sharing/src/share.js b/apps/files_sharing/src/share.js index efd1be00ab..0adc629660 100644 --- a/apps/files_sharing/src/share.js +++ b/apps/files_sharing/src/share.js @@ -32,7 +32,7 @@ * "user@example.com/path/to/owncloud" * "user@anotherexample.com@example.com/path/to/owncloud */ - _REMOTE_OWNER_REGEXP: new RegExp('^(([^@]*)@(([^@^/^\\s]*)@)?)([^[\\s/]*)([/](.*))?$'), + _REMOTE_OWNER_REGEXP: new RegExp('^(([^@]*)@(([^@^/\\s]*)@)?)((https://)?[^[\\s/]*)([/](.*))?$'), /** * Initialize the sharing plugin. @@ -341,137 +341,140 @@ } icon.removeClass('icon-shared icon-public').addClass(iconClass) }, - /** - * Format a remote address - * - * @param {String} shareWith userid, full remote share, or whatever - * @param {String} shareWithDisplayName - * @param {String} message - * @returns {String} HTML code to display - */ - _formatRemoteShare: function(shareWith, shareWithDisplayName, message) { - var parts = OCA.Sharing.Util._REMOTE_OWNER_REGEXP.exec(shareWith) - if (!parts || !parts[6]) { - // display avatar of the user - var avatar = '' - var hidden = '' + message + ' ' + escapeHTML(shareWithDisplayName) + ' ' - return avatar + hidden - } + /** + * Format a remote address + * + * @param {String} shareWith userid, full remote share, or whatever + * @param {String} shareWithDisplayName + * @param {String} message + * @returns {String} HTML code to display + */ + _formatRemoteShare: function(shareWith, shareWithDisplayName, message) { + var parts = OCA.Sharing.Util._REMOTE_OWNER_REGEXP.exec(shareWith) + console.error(parts); + if (!parts || !parts[7]) { + // display avatar of the user + var avatar = '' + var hidden = '' + message + ' ' + escapeHTML(shareWithDisplayName) + ' ' + return avatar + hidden + } var userName = parts[2] var userDomain = parts[4] var server = parts[5] + var protocol = parts[6] + var serverPath = parts[8] ? parts[7] : ''; // no trailing slash on root var tooltip = message + ' ' + userName if (userDomain) { tooltip += '@' + userDomain } if (server) { - tooltip += '@' + server + tooltip += '@' + server.replace(protocol, '') + serverPath } - var html = '' - html += '' + escapeHTML(userName) + '' - if (userDomain) { - html += '@' + escapeHTML(userDomain) + '' - } - html += ' ' - return html - }, - /** - * Loop over all recipients in the list and format them using - * all kind of fancy magic. - * - * @param {Object} recipients array of all the recipients - * @returns {String[]} modified list of recipients - */ - _formatShareList: function(recipients) { - var _parent = this - recipients = _.toArray(recipients) - recipients.sort(function(a, b) { - return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName) - }) - return $.map(recipients, function(recipient) { - return _parent._formatRemoteShare(recipient.shareWith, recipient.shareWithDisplayName, t('core', 'Shared with')) - }) + var html = '' + html += '' + escapeHTML(userName) + '' + if (userDomain) { + html += '@' + escapeHTML(userDomain) + '' + } + html += ' ' + return html + }, + /** + * Loop over all recipients in the list and format them using + * all kind of fancy magic. + * + * @param {Object} recipients array of all the recipients + * @returns {String[]} modified list of recipients + */ + _formatShareList: function(recipients) { + var _parent = this + recipients = _.toArray(recipients) + recipients.sort(function(a, b) { + return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName) + }) + return $.map(recipients, function(recipient) { + return _parent._formatRemoteShare(recipient.shareWith, recipient.shareWithDisplayName, t('core', 'Shared with')) + }) }, - - /** - * Marks/unmarks a given file as shared by changing its action icon - * and folder icon. - * - * @param $tr file element to mark as shared - * @param hasShares whether shares are available - * @param hasLink whether link share is available - */ - markFileAsShared: function($tr, hasShares, hasLink) { - var action = $tr.find('.fileactions .action[data-action="Share"]') - var type = $tr.data('type') - var icon = action.find('.icon') - var message, recipients, avatars - var ownerId = $tr.attr('data-share-owner-id') - var owner = $tr.attr('data-share-owner') - var mountType = $tr.attr('data-mounttype') - var shareFolderIcon - var iconClass = 'icon-shared' - action.removeClass('shared-style') - // update folder icon - if (type === 'dir' && (hasShares || hasLink || ownerId)) { - if (typeof mountType !== 'undefined' && mountType !== 'shared-root' && mountType !== 'shared') { - shareFolderIcon = OC.MimeType.getIconUrl('dir-' + mountType) - } else if (hasLink) { - shareFolderIcon = OC.MimeType.getIconUrl('dir-public') - } else { - shareFolderIcon = OC.MimeType.getIconUrl('dir-shared') - } - $tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')') - $tr.attr('data-icon', shareFolderIcon) - } else if (type === 'dir') { - var isEncrypted = $tr.attr('data-e2eencrypted') - // FIXME: duplicate of FileList._createRow logic for external folder, - // need to refactor the icon logic into a single code path eventually - if (isEncrypted === 'true') { - shareFolderIcon = OC.MimeType.getIconUrl('dir-encrypted') - $tr.attr('data-icon', shareFolderIcon) - } else if (mountType && mountType.indexOf('external') === 0) { - shareFolderIcon = OC.MimeType.getIconUrl('dir-external') - $tr.attr('data-icon', shareFolderIcon) - } else { - shareFolderIcon = OC.MimeType.getIconUrl('dir') - // back to default - $tr.removeAttr('data-icon') - } - $tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')') - } - // update share action text / icon - if (hasShares || ownerId) { - recipients = $tr.data('share-recipient-data') - action.addClass('shared-style') - avatars = '' + t('core', 'Shared') + '' - // even if reshared, only show "Shared by" - if (ownerId) { - message = t('core', 'Shared by') - avatars = this._formatRemoteShare(ownerId, owner, message) - } else if (recipients) { - avatars = this._formatShareList(recipients) - } - action.html(avatars).prepend(icon) + /** + * Marks/unmarks a given file as shared by changing its action icon + * and folder icon. + * + * @param $tr file element to mark as shared + * @param hasShares whether shares are available + * @param hasLink whether link share is available + */ + markFileAsShared: function($tr, hasShares, hasLink) { + var action = $tr.find('.fileactions .action[data-action="Share"]') + var type = $tr.data('type') + var icon = action.find('.icon') + var message, recipients, avatars + var ownerId = $tr.attr('data-share-owner-id') + var owner = $tr.attr('data-share-owner') + var mountType = $tr.attr('data-mounttype') + var shareFolderIcon + var iconClass = 'icon-shared' + action.removeClass('shared-style') + // update folder icon + if (type === 'dir' && (hasShares || hasLink || ownerId)) { + if (typeof mountType !== 'undefined' && mountType !== 'shared-root' && mountType !== 'shared') { + shareFolderIcon = OC.MimeType.getIconUrl('dir-' + mountType) + } else if (hasLink) { + shareFolderIcon = OC.MimeType.getIconUrl('dir-public') + } else { + shareFolderIcon = OC.MimeType.getIconUrl('dir-shared') + } + $tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')') + $tr.attr('data-icon', shareFolderIcon) + } else if (type === 'dir') { + var isEncrypted = $tr.attr('data-e2eencrypted') + // FIXME: duplicate of FileList._createRow logic for external folder, + // need to refactor the icon logic into a single code path eventually + if (isEncrypted === 'true') { + shareFolderIcon = OC.MimeType.getIconUrl('dir-encrypted') + $tr.attr('data-icon', shareFolderIcon) + } else if (mountType && mountType.indexOf('external') === 0) { + shareFolderIcon = OC.MimeType.getIconUrl('dir-external') + $tr.attr('data-icon', shareFolderIcon) + } else { + shareFolderIcon = OC.MimeType.getIconUrl('dir') + // back to default + $tr.removeAttr('data-icon') + } + $tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')') + } + // update share action text / icon + if (hasShares || ownerId) { + recipients = $tr.data('share-recipient-data') + action.addClass('shared-style') - if (ownerId || recipients) { - var avatarElement = action.find('.avatar') - avatarElement.each(function() { - $(this).avatar($(this).data('username'), 32) - }) - action.find('span[title]').tooltip({ placement: 'top' }) - } - } else { - action.html('' + t('core', 'Shared') + '').prepend(icon) - } - if (hasLink) { - iconClass = 'icon-public' - } - icon.removeClass('icon-shared icon-public').addClass(iconClass) + avatars = '' + t('core', 'Shared') + '' + // even if reshared, only show "Shared by" + if (ownerId) { + message = t('core', 'Shared by') + avatars = this._formatRemoteShare(ownerId, owner, message) + } else if (recipients) { + avatars = this._formatShareList(recipients) + } + action.html(avatars).prepend(icon) + + if (ownerId || recipients) { + var avatarElement = action.find('.avatar') + avatarElement.each(function() { + $(this).avatar($(this).data('username'), 32) + }) + action.find('span[title]').tooltip({ placement: 'top' }) + } + } else { + action.html('' + t('core', 'Shared') + '').prepend(icon) + } + if (hasLink) { + iconClass = 'icon-public' + } + icon.removeClass('icon-shared icon-public').addClass(iconClass) }, /** From 86cf1199932dd750c1c18a23145787ee6a2e7cf8 Mon Sep 17 00:00:00 2001 From: "npmbuildbot-nextcloud[bot]" Date: Thu, 26 Nov 2020 17:22:57 +0000 Subject: [PATCH 2/2] Compile assets Signed-off-by: npmbuildbot-nextcloud[bot] --- apps/files_sharing/js/dist/additionalScripts.js | 2 +- apps/files_sharing/js/dist/additionalScripts.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/js/dist/additionalScripts.js b/apps/files_sharing/js/dist/additionalScripts.js index bdd535d56e..ba5b1f47f4 100644 --- a/apps/files_sharing/js/dist/additionalScripts.js +++ b/apps/files_sharing/js/dist/additionalScripts.js @@ -1,2 +1,2 @@ -!function(e){var t={};function a(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,a),n.l=!0,n.exports}a.m=e,a.c=t,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)a.d(r,n,function(t){return e[t]}.bind(null,n));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="/js/",a(a.s=319)}({200:function(e,a,r){r.p=OC.linkTo("files_sharing","js/dist/"),r.nc=btoa(OC.requestToken),window.OCP.Collaboration.registerType("file",{action:function(){return new Promise((function(e,a){OC.dialogs.filepicker(t("files_sharing","Link to a file"),(function(t){OC.Files.getClient().getFileInfo(t).then((function(t,a){e(a.id)})).fail((function(){a(new Error("Cannot get fileinfo"))}))}),!1,null,!1,OC.dialogs.FILEPICKER_TYPE_CHOOSE,"",{allowDirectoryChooser:!0})}))},typeString:t("files_sharing","Link to a file"),typeIconClass:"icon-files-dark"})},319:function(e,t,a){"use strict";a.r(t);a(320),a(321),a(322),a(200);a.p=OC.linkTo("files_sharing","js/dist/"),a.nc=btoa(OC.requestToken),window.OCA.Sharing=OCA.Sharing},320:function(e,a){_.extend(OC.Files.Client,{PROPERTY_SHARE_TYPES:"{"+OC.Files.Client.NS_OWNCLOUD+"}share-types",PROPERTY_OWNER_ID:"{"+OC.Files.Client.NS_OWNCLOUD+"}owner-id",PROPERTY_OWNER_DISPLAY_NAME:"{"+OC.Files.Client.NS_OWNCLOUD+"}owner-display-name"}),OCA.Sharing||(OCA.Sharing={}),OCA.Sharing.Util={_REMOTE_OWNER_REGEXP:new RegExp("^(([^@]*)@(([^@^/^\\s]*)@)?)([^[\\s/]*)([/](.*))?$"),attach:function(e){if(OC.Share&&"trashbin"!==e.id&&"files.public"!==e.id){var a=e.fileActions,r=e._createRow;e._createRow=function(e){var t=r.apply(this,arguments),n=OCA.Sharing.Util.getSharePermissions(e);return 0===e.permissions&&(delete a.actions.all.Comment,delete a.actions.all.Details,delete a.actions.all.Goto),t.attr("data-share-permissions",n),e.shareOwner&&(t.attr("data-share-owner",e.shareOwner),t.attr("data-share-owner-id",e.shareOwnerId),"shared-root"===e.mountType&&t.attr("data-permissions",e.permissions|OC.PERMISSION_UPDATE)),e.recipientData&&!_.isEmpty(e.recipientData)&&t.attr("data-share-recipient-data",JSON.stringify(e.recipientData)),e.shareTypes&&t.attr("data-share-types",e.shareTypes.join(",")),t};var n=e.elementToFile;e.elementToFile=function(e){var t=n.apply(this,arguments);if(t.sharePermissions=e.attr("data-share-permissions")||void 0,t.shareOwner=e.attr("data-share-owner")||void 0,t.shareOwnerId=e.attr("data-share-owner-id")||void 0,e.attr("data-share-types")&&(t.shareTypes=e.attr("data-share-types").split(",")),e.attr("data-expiration")){var a=parseInt(e.attr("data-expiration"));t.shares=[],t.shares.push({expiration:a})}return t};var i=e._getWebdavProperties;e._getWebdavProperties=function(){var e=i.apply(this,arguments);return e.push(OC.Files.Client.PROPERTY_OWNER_ID),e.push(OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME),e.push(OC.Files.Client.PROPERTY_SHARE_TYPES),e},e.filesClient.addFileInfoParser((function(e){var t={},a=e.propStat[0].properties,r=a[OC.Files.Client.PROPERTY_PERMISSIONS];r&&r.indexOf("S")>=0&&(t.shareOwner=a[OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME],t.shareOwnerId=a[OC.Files.Client.PROPERTY_OWNER_ID]);var n=a[OC.Files.Client.PROPERTY_SHARE_TYPES];return n&&(t.shareTypes=_.chain(n).filter((function(e){return e.namespaceURI===OC.Files.Client.NS_OWNCLOUD&&"share-type"===e.nodeName.split(":")[1]})).map((function(e){return parseInt(e.textContent||e.text,10)})).value()),t})),e.$el.on("fileActionsReady",(function(e){var t=e.$files;_.each(t,(function(e){var t=$(e),a=t.attr("data-share-types")||"",r=t.attr("data-share-owner");if(a||r){var n=!1,i=!1;_.each(a.split(",")||[],(function(e){(e=parseInt(e,10))===OC.Share.SHARE_TYPE_LINK||e===OC.Share.SHARE_TYPE_EMAIL?n=!0:(e===OC.Share.SHARE_TYPE_USER||e===OC.Share.SHARE_TYPE_GROUP||e===OC.Share.SHARE_TYPE_REMOTE||e===OC.Share.SHARE_TYPE_CIRCLE||e===OC.Share.SHARE_TYPE_ROOM)&&(i=!0)})),OCA.Sharing.Util._updateFileActionIcon(t,i,n)}}))})),e.$el.on("changeDirectory",(function(){OCA.Sharing.sharesLoaded=!1})),a.registerAction({name:"Share",displayName:function(e){if(e&&e.$file){var a=parseInt(e.$file.data("share-types"),10),r=e.$file.data("share-owner-id");if(a>=0||r)return t("core","Shared")}return t("core","Share")},altText:t("core","Share"),mime:"all",order:-150,permissions:OC.PERMISSION_ALL,iconClass:function(e,t){var a=parseInt(t.$file.data("share-types"),10);return a===OC.Share.SHARE_TYPE_EMAIL||a===OC.Share.SHARE_TYPE_LINK?"icon-public":"icon-shared"},icon:function(e,t){var a=t.$file.data("share-owner-id");if(a)return OC.generateUrl("/avatar/".concat(a,"/32"))},type:OCA.Files.FileActions.TYPE_INLINE,actionHandler:function(t,a){var r=parseInt(a.$file.data("share-permissions"),10);(isNaN(r)||r>0)&&e.showDetailsView(t,"sharing")},render:function(e,t,r){return 0!=(parseInt(r.$file.data("permissions"),10)&OC.PERMISSION_SHARE)||r.$file.attr("data-share-owner")?a._defaultRenderAction.call(a,e,t,r):null}});var s=new OCA.Sharing.ShareBreadCrumbView;e.registerBreadCrumbDetailView(s)}},_updateFileListDataAttributes:function(e,t,a){if("files"!==e.id)if(_.pluck(a.get("shares"),"share_with_displayname").length){var r=_.mapObject(a.get("shares"),(function(e){return{shareWith:e.share_with,shareWithDisplayName:e.share_with_displayname}}));t.attr("data-share-recipient-data",JSON.stringify(r))}else t.removeAttr("data-share-recipient-data")},_updateFileActionIcon:function(e,t,a){return!!(t||a||e.attr("data-share-recipient-data")||e.attr("data-share-owner"))&&(OCA.Sharing.Util._markFileAsShared(e,!0,a),!0)},_markFileAsShared:function(e,a,r){var n,i,s,o,l=e.find('.fileactions .action[data-action="Share"]'),d=e.data("type"),c=l.find(".icon"),h=e.attr("data-share-owner-id"),u=e.attr("data-share-owner"),p=e.attr("data-mounttype"),f="icon-shared";l.removeClass("shared-style"),"dir"===d&&(a||r||h)?(o=void 0!==p&&"shared-root"!==p&&"shared"!==p?OC.MimeType.getIconUrl("dir-"+p):r?OC.MimeType.getIconUrl("dir-public"):OC.MimeType.getIconUrl("dir-shared"),e.find(".filename .thumbnail").css("background-image","url("+o+")"),e.attr("data-icon",o)):"dir"===d&&("true"===e.attr("data-e2eencrypted")?(o=OC.MimeType.getIconUrl("dir-encrypted"),e.attr("data-icon",o)):p&&0===p.indexOf("external")?(o=OC.MimeType.getIconUrl("dir-external"),e.attr("data-icon",o)):(o=OC.MimeType.getIconUrl("dir"),e.removeAttr("data-icon")),e.find(".filename .thumbnail").css("background-image","url("+o+")")),a||h?(i=e.data("share-recipient-data"),l.addClass("shared-style"),s=""+t("core","Shared")+"",h?(n=t("core","Shared by"),s=OCA.Sharing.Util._formatRemoteShare(h,u,n)):i&&(s=OCA.Sharing.Util._formatShareList(i)),l.html(s).prepend(c),(h||i)&&(l.find(".avatar").each((function(){$(this).avatar($(this).data("username"),32)})),l.find("span[title]").tooltip({placement:"top"}))):l.html(''+t("core","Shared")+"").prepend(c),r&&(f="icon-public"),c.removeClass("icon-shared icon-public").addClass(f)},_formatRemoteShare:function(e,t,a){var r=OCA.Sharing.Util._REMOTE_OWNER_REGEXP.exec(e);if(!r||!r[6])return''+a+" "+escapeHTML(t)+" ";var n=r[2],i=r[4],s=r[5],o=a+" "+n;i&&(o+="@"+i),s&&(o+="@"+s);var l='';return l+=''+escapeHTML(n)+"",i&&(l+='@'+escapeHTML(i)+""),l+=" "},_formatShareList:function(e){var a=this;return(e=_.toArray(e)).sort((function(e,t){return e.shareWithDisplayName.localeCompare(t.shareWithDisplayName)})),$.map(e,(function(e){return a._formatRemoteShare(e.shareWith,e.shareWithDisplayName,t("core","Shared with"))}))},markFileAsShared:function(e,a,r){var n,i,s,o,l=e.find('.fileactions .action[data-action="Share"]'),d=e.data("type"),c=l.find(".icon"),h=e.attr("data-share-owner-id"),u=e.attr("data-share-owner"),p=e.attr("data-mounttype"),f="icon-shared";l.removeClass("shared-style"),"dir"===d&&(a||r||h)?(o=void 0!==p&&"shared-root"!==p&&"shared"!==p?OC.MimeType.getIconUrl("dir-"+p):r?OC.MimeType.getIconUrl("dir-public"):OC.MimeType.getIconUrl("dir-shared"),e.find(".filename .thumbnail").css("background-image","url("+o+")"),e.attr("data-icon",o)):"dir"===d&&("true"===e.attr("data-e2eencrypted")?(o=OC.MimeType.getIconUrl("dir-encrypted"),e.attr("data-icon",o)):p&&0===p.indexOf("external")?(o=OC.MimeType.getIconUrl("dir-external"),e.attr("data-icon",o)):(o=OC.MimeType.getIconUrl("dir"),e.removeAttr("data-icon")),e.find(".filename .thumbnail").css("background-image","url("+o+")")),a||h?(i=e.data("share-recipient-data"),l.addClass("shared-style"),s=""+t("core","Shared")+"",h?(n=t("core","Shared by"),s=this._formatRemoteShare(h,u,n)):i&&(s=this._formatShareList(i)),l.html(s).prepend(c),(h||i)&&(l.find(".avatar").each((function(){$(this).avatar($(this).data("username"),32)})),l.find("span[title]").tooltip({placement:"top"}))):l.html(''+t("core","Shared")+"").prepend(c),r&&(f="icon-public"),c.removeClass("icon-shared icon-public").addClass(f)},getSharePermissions:function(e){return e.sharePermissions}},OC.Plugins.register("OCA.Files.FileList",OCA.Sharing.Util)},321:function(e,t){!function(){"use strict";var e=OC.Backbone.View.extend({tagName:"span",events:{click:"_onClick"},_dirInfo:void 0,render:function(e){if(this._dirInfo=e.dirInfo||null,null===this._dirInfo||"/"===this._dirInfo.path&&""===this._dirInfo.name)this.$el.removeClass("shared icon-public icon-shared"),this.$el.hide();else{var t=e.dirInfo&&e.dirInfo.shareTypes&&e.dirInfo.shareTypes.length>0;this.$el.removeClass("shared icon-public icon-shared"),t?(this.$el.addClass("shared"),-1!==e.dirInfo.shareTypes.indexOf(OC.Share.SHARE_TYPE_LINK)?this.$el.addClass("icon-public"):this.$el.addClass("icon-shared")):this.$el.addClass("icon-shared"),this.$el.show(),this.delegateEvents()}return this},_onClick:function(e){e.preventDefault();var t=new OCA.Files.FileInfoModel(this._dirInfo),a=this;t.on("change",(function(){a.render({dirInfo:a._dirInfo})}));var r=t.attributes.path+"/"+t.attributes.name;OCA.Files.Sidebar.open(r),OCA.Files.Sidebar.setActiveTab("sharing")}});OCA.Sharing.ShareBreadCrumbView=e}()},322:function(e,t,a){var r=a(323);"string"==typeof r&&(r=[[e.i,r,""]]),r.locals&&(e.exports=r.locals);(0,a(61).default)("57e7eec1",r,!0,{})},323:function(e,t,a){(t=a(49)(!1)).push([e.i,"div.crumb span.icon-shared,div.crumb span.icon-public{display:inline-block;cursor:pointer;opacity:0.2;margin-right:6px}div.crumb span.icon-shared.shared,div.crumb span.icon-public.shared{opacity:0.7}\n",""]),e.exports=t},49:function(e,t,a){"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var a=function(e,t){var a=e[1]||"",r=e[3];if(!r)return a;if(t&&"function"==typeof btoa){var n=(s=r,o=btoa(unescape(encodeURIComponent(JSON.stringify(s)))),l="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(o),"/*# ".concat(l," */")),i=r.sources.map((function(e){return"/*# sourceURL=".concat(r.sourceRoot||"").concat(e," */")}));return[a].concat(i).concat([n]).join("\n")}var s,o,l;return[a].join("\n")}(t,e);return t[2]?"@media ".concat(t[2]," {").concat(a,"}"):a})).join("")},t.i=function(e,a,r){"string"==typeof e&&(e=[[null,e,""]]);var n={};if(r)for(var i=0;ia.parts.length&&(r.parts.length=a.parts.length)}else{var s=[];for(n=0;n=0&&(t.shareOwner=a[OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME],t.shareOwnerId=a[OC.Files.Client.PROPERTY_OWNER_ID]);var n=a[OC.Files.Client.PROPERTY_SHARE_TYPES];return n&&(t.shareTypes=_.chain(n).filter((function(e){return e.namespaceURI===OC.Files.Client.NS_OWNCLOUD&&"share-type"===e.nodeName.split(":")[1]})).map((function(e){return parseInt(e.textContent||e.text,10)})).value()),t})),e.$el.on("fileActionsReady",(function(e){var t=e.$files;_.each(t,(function(e){var t=$(e),a=t.attr("data-share-types")||"",r=t.attr("data-share-owner");if(a||r){var n=!1,i=!1;_.each(a.split(",")||[],(function(e){(e=parseInt(e,10))===OC.Share.SHARE_TYPE_LINK||e===OC.Share.SHARE_TYPE_EMAIL?n=!0:(e===OC.Share.SHARE_TYPE_USER||e===OC.Share.SHARE_TYPE_GROUP||e===OC.Share.SHARE_TYPE_REMOTE||e===OC.Share.SHARE_TYPE_CIRCLE||e===OC.Share.SHARE_TYPE_ROOM)&&(i=!0)})),OCA.Sharing.Util._updateFileActionIcon(t,i,n)}}))})),e.$el.on("changeDirectory",(function(){OCA.Sharing.sharesLoaded=!1})),a.registerAction({name:"Share",displayName:function(e){if(e&&e.$file){var a=parseInt(e.$file.data("share-types"),10),r=e.$file.data("share-owner-id");if(a>=0||r)return t("core","Shared")}return t("core","Share")},altText:t("core","Share"),mime:"all",order:-150,permissions:OC.PERMISSION_ALL,iconClass:function(e,t){var a=parseInt(t.$file.data("share-types"),10);return a===OC.Share.SHARE_TYPE_EMAIL||a===OC.Share.SHARE_TYPE_LINK?"icon-public":"icon-shared"},icon:function(e,t){var a=t.$file.data("share-owner-id");if(a)return OC.generateUrl("/avatar/".concat(a,"/32"))},type:OCA.Files.FileActions.TYPE_INLINE,actionHandler:function(t,a){var r=parseInt(a.$file.data("share-permissions"),10);(isNaN(r)||r>0)&&e.showDetailsView(t,"sharing")},render:function(e,t,r){return 0!=(parseInt(r.$file.data("permissions"),10)&OC.PERMISSION_SHARE)||r.$file.attr("data-share-owner")?a._defaultRenderAction.call(a,e,t,r):null}});var s=new OCA.Sharing.ShareBreadCrumbView;e.registerBreadCrumbDetailView(s)}},_updateFileListDataAttributes:function(e,t,a){if("files"!==e.id)if(_.pluck(a.get("shares"),"share_with_displayname").length){var r=_.mapObject(a.get("shares"),(function(e){return{shareWith:e.share_with,shareWithDisplayName:e.share_with_displayname}}));t.attr("data-share-recipient-data",JSON.stringify(r))}else t.removeAttr("data-share-recipient-data")},_updateFileActionIcon:function(e,t,a){return!!(t||a||e.attr("data-share-recipient-data")||e.attr("data-share-owner"))&&(OCA.Sharing.Util._markFileAsShared(e,!0,a),!0)},_markFileAsShared:function(e,a,r){var n,i,s,o,l=e.find('.fileactions .action[data-action="Share"]'),d=e.data("type"),c=l.find(".icon"),h=e.attr("data-share-owner-id"),u=e.attr("data-share-owner"),p=e.attr("data-mounttype"),f="icon-shared";l.removeClass("shared-style"),"dir"===d&&(a||r||h)?(o=void 0!==p&&"shared-root"!==p&&"shared"!==p?OC.MimeType.getIconUrl("dir-"+p):r?OC.MimeType.getIconUrl("dir-public"):OC.MimeType.getIconUrl("dir-shared"),e.find(".filename .thumbnail").css("background-image","url("+o+")"),e.attr("data-icon",o)):"dir"===d&&("true"===e.attr("data-e2eencrypted")?(o=OC.MimeType.getIconUrl("dir-encrypted"),e.attr("data-icon",o)):p&&0===p.indexOf("external")?(o=OC.MimeType.getIconUrl("dir-external"),e.attr("data-icon",o)):(o=OC.MimeType.getIconUrl("dir"),e.removeAttr("data-icon")),e.find(".filename .thumbnail").css("background-image","url("+o+")")),a||h?(i=e.data("share-recipient-data"),l.addClass("shared-style"),s=""+t("core","Shared")+"",h?(n=t("core","Shared by"),s=OCA.Sharing.Util._formatRemoteShare(h,u,n)):i&&(s=OCA.Sharing.Util._formatShareList(i)),l.html(s).prepend(c),(h||i)&&(l.find(".avatar").each((function(){$(this).avatar($(this).data("username"),32)})),l.find("span[title]").tooltip({placement:"top"}))):l.html(''+t("core","Shared")+"").prepend(c),r&&(f="icon-public"),c.removeClass("icon-shared icon-public").addClass(f)},_formatRemoteShare:function(e,t,a){var r=OCA.Sharing.Util._REMOTE_OWNER_REGEXP.exec(e);if(console.error(r),!r||!r[7])return''+a+" "+escapeHTML(t)+" ";var n=r[2],i=r[4],s=r[5],o=r[6],l=r[8]?r[7]:"",d=a+" "+n;i&&(d+="@"+i),s&&(d+="@"+s.replace(o,"")+l);var c='';return c+=''+escapeHTML(n)+"",i&&(c+='@'+escapeHTML(i)+""),c+=" "},_formatShareList:function(e){var a=this;return(e=_.toArray(e)).sort((function(e,t){return e.shareWithDisplayName.localeCompare(t.shareWithDisplayName)})),$.map(e,(function(e){return a._formatRemoteShare(e.shareWith,e.shareWithDisplayName,t("core","Shared with"))}))},markFileAsShared:function(e,a,r){var n,i,s,o,l=e.find('.fileactions .action[data-action="Share"]'),d=e.data("type"),c=l.find(".icon"),h=e.attr("data-share-owner-id"),u=e.attr("data-share-owner"),p=e.attr("data-mounttype"),f="icon-shared";l.removeClass("shared-style"),"dir"===d&&(a||r||h)?(o=void 0!==p&&"shared-root"!==p&&"shared"!==p?OC.MimeType.getIconUrl("dir-"+p):r?OC.MimeType.getIconUrl("dir-public"):OC.MimeType.getIconUrl("dir-shared"),e.find(".filename .thumbnail").css("background-image","url("+o+")"),e.attr("data-icon",o)):"dir"===d&&("true"===e.attr("data-e2eencrypted")?(o=OC.MimeType.getIconUrl("dir-encrypted"),e.attr("data-icon",o)):p&&0===p.indexOf("external")?(o=OC.MimeType.getIconUrl("dir-external"),e.attr("data-icon",o)):(o=OC.MimeType.getIconUrl("dir"),e.removeAttr("data-icon")),e.find(".filename .thumbnail").css("background-image","url("+o+")")),a||h?(i=e.data("share-recipient-data"),l.addClass("shared-style"),s=""+t("core","Shared")+"",h?(n=t("core","Shared by"),s=this._formatRemoteShare(h,u,n)):i&&(s=this._formatShareList(i)),l.html(s).prepend(c),(h||i)&&(l.find(".avatar").each((function(){$(this).avatar($(this).data("username"),32)})),l.find("span[title]").tooltip({placement:"top"}))):l.html(''+t("core","Shared")+"").prepend(c),r&&(f="icon-public"),c.removeClass("icon-shared icon-public").addClass(f)},getSharePermissions:function(e){return e.sharePermissions}},OC.Plugins.register("OCA.Files.FileList",OCA.Sharing.Util)},321:function(e,t){!function(){"use strict";var e=OC.Backbone.View.extend({tagName:"span",events:{click:"_onClick"},_dirInfo:void 0,render:function(e){if(this._dirInfo=e.dirInfo||null,null===this._dirInfo||"/"===this._dirInfo.path&&""===this._dirInfo.name)this.$el.removeClass("shared icon-public icon-shared"),this.$el.hide();else{var t=e.dirInfo&&e.dirInfo.shareTypes&&e.dirInfo.shareTypes.length>0;this.$el.removeClass("shared icon-public icon-shared"),t?(this.$el.addClass("shared"),-1!==e.dirInfo.shareTypes.indexOf(OC.Share.SHARE_TYPE_LINK)?this.$el.addClass("icon-public"):this.$el.addClass("icon-shared")):this.$el.addClass("icon-shared"),this.$el.show(),this.delegateEvents()}return this},_onClick:function(e){e.preventDefault();var t=new OCA.Files.FileInfoModel(this._dirInfo),a=this;t.on("change",(function(){a.render({dirInfo:a._dirInfo})}));var r=t.attributes.path+"/"+t.attributes.name;OCA.Files.Sidebar.open(r),OCA.Files.Sidebar.setActiveTab("sharing")}});OCA.Sharing.ShareBreadCrumbView=e}()},322:function(e,t,a){var r=a(323);"string"==typeof r&&(r=[[e.i,r,""]]),r.locals&&(e.exports=r.locals);(0,a(61).default)("57e7eec1",r,!0,{})},323:function(e,t,a){(t=a(49)(!1)).push([e.i,"div.crumb span.icon-shared,div.crumb span.icon-public{display:inline-block;cursor:pointer;opacity:0.2;margin-right:6px}div.crumb span.icon-shared.shared,div.crumb span.icon-public.shared{opacity:0.7}\n",""]),e.exports=t},49:function(e,t,a){"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var a=function(e,t){var a=e[1]||"",r=e[3];if(!r)return a;if(t&&"function"==typeof btoa){var n=(s=r,o=btoa(unescape(encodeURIComponent(JSON.stringify(s)))),l="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(o),"/*# ".concat(l," */")),i=r.sources.map((function(e){return"/*# sourceURL=".concat(r.sourceRoot||"").concat(e," */")}));return[a].concat(i).concat([n]).join("\n")}var s,o,l;return[a].join("\n")}(t,e);return t[2]?"@media ".concat(t[2]," {").concat(a,"}"):a})).join("")},t.i=function(e,a,r){"string"==typeof e&&(e=[[null,e,""]]);var n={};if(r)for(var i=0;ia.parts.length&&(r.parts.length=a.parts.length)}else{var s=[];for(n=0;n {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tOC.dialogs.filepicker(t('files_sharing', 'Link to a file'), function(f) {\n\t\t\t\tconst client = OC.Files.getClient()\n\t\t\t\tclient.getFileInfo(f).then((status, fileInfo) => {\n\t\t\t\t\tresolve(fileInfo.id)\n\t\t\t\t}).fail(() => {\n\t\t\t\t\treject(new Error('Cannot get fileinfo'))\n\t\t\t\t})\n\t\t\t}, false, null, false, OC.dialogs.FILEPICKER_TYPE_CHOOSE, '', { allowDirectoryChooser: true })\n\t\t})\n\t},\n\ttypeString: t('files_sharing', 'Link to a file'),\n\ttypeIconClass: 'icon-files-dark',\n})\n","import './share'\nimport './sharebreadcrumbview'\n\nimport './style/sharebreadcrumb.scss'\n\nimport './collaborationresourceshandler.js'\n\n// eslint-disable-next-line camelcase\n__webpack_public_path__ = OC.linkTo('files_sharing', 'js/dist/')\n// eslint-disable-next-line camelcase\n__webpack_nonce__ = btoa(OC.requestToken)\n\nwindow.OCA.Sharing = OCA.Sharing\n","/* eslint-disable */\n/*\n * Copyright (c) 2014\n *\n * This file is licensed under the Affero General Public License version 3\n * or later.\n *\n * See the COPYING-README file.\n *\n */\n\n(function() {\n\n\t_.extend(OC.Files.Client, {\n\t\tPROPERTY_SHARE_TYPES:\t'{' + OC.Files.Client.NS_OWNCLOUD + '}share-types',\n\t\tPROPERTY_OWNER_ID:\t'{' + OC.Files.Client.NS_OWNCLOUD + '}owner-id',\n\t\tPROPERTY_OWNER_DISPLAY_NAME:\t'{' + OC.Files.Client.NS_OWNCLOUD + '}owner-display-name'\n\t})\n\n\tif (!OCA.Sharing) {\n\t\tOCA.Sharing = {}\n\t}\n\n\t/**\n\t * @namespace\n\t */\n\tOCA.Sharing.Util = {\n\n\t\t/**\n\t\t * Regular expression for splitting parts of remote share owners:\n\t\t * \"user@example.com/\"\n\t\t * \"user@example.com/path/to/owncloud\"\n\t\t * \"user@anotherexample.com@example.com/path/to/owncloud\n\t\t */\n\t\t_REMOTE_OWNER_REGEXP: new RegExp('^(([^@]*)@(([^@^/^\\\\s]*)@)?)([^[\\\\s/]*)([/](.*))?$'),\n\n\t\t/**\n\t\t * Initialize the sharing plugin.\n\t\t *\n\t\t * Registers the \"Share\" file action and adds additional\n\t\t * DOM attributes for the sharing file info.\n\t\t *\n\t\t * @param {OCA.Files.FileList} fileList file list to be extended\n\t\t */\n\t\tattach: function(fileList) {\n\t\t\t// core sharing is disabled/not loaded\n\t\t\tif (!OC.Share) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (fileList.id === 'trashbin' || fileList.id === 'files.public') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvar fileActions = fileList.fileActions\n\t\t\tvar oldCreateRow = fileList._createRow\n\t\t\tfileList._createRow = function(fileData) {\n\n\t\t\t\tvar tr = oldCreateRow.apply(this, arguments)\n\t\t\t\tvar sharePermissions = OCA.Sharing.Util.getSharePermissions(fileData)\n\n\t\t\t\tif (fileData.permissions === 0) {\n\t\t\t\t\t// no permission, disabling sidebar\n\t\t\t\t\tdelete fileActions.actions.all.Comment\n\t\t\t\t\tdelete fileActions.actions.all.Details\n\t\t\t\t\tdelete fileActions.actions.all.Goto\n\t\t\t\t}\n\t\t\t\ttr.attr('data-share-permissions', sharePermissions)\n\t\t\t\tif (fileData.shareOwner) {\n\t\t\t\t\ttr.attr('data-share-owner', fileData.shareOwner)\n\t\t\t\t\ttr.attr('data-share-owner-id', fileData.shareOwnerId)\n\t\t\t\t\t// user should always be able to rename a mount point\n\t\t\t\t\tif (fileData.mountType === 'shared-root') {\n\t\t\t\t\t\ttr.attr('data-permissions', fileData.permissions | OC.PERMISSION_UPDATE)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (fileData.recipientData && !_.isEmpty(fileData.recipientData)) {\n\t\t\t\t\ttr.attr('data-share-recipient-data', JSON.stringify(fileData.recipientData))\n\t\t\t\t}\n\t\t\t\tif (fileData.shareTypes) {\n\t\t\t\t\ttr.attr('data-share-types', fileData.shareTypes.join(','))\n\t\t\t\t}\n\t\t\t\treturn tr\n\t\t\t}\n\n\t\t\tvar oldElementToFile = fileList.elementToFile\n\t\t\tfileList.elementToFile = function($el) {\n\t\t\t\tvar fileInfo = oldElementToFile.apply(this, arguments)\n\t\t\t\tfileInfo.sharePermissions = $el.attr('data-share-permissions') || undefined\n\t\t\t\tfileInfo.shareOwner = $el.attr('data-share-owner') || undefined\n\t\t\t\tfileInfo.shareOwnerId = $el.attr('data-share-owner-id') || undefined\n\n\t\t\t\tif ($el.attr('data-share-types')) {\n\t\t\t\t\tfileInfo.shareTypes = $el.attr('data-share-types').split(',')\n\t\t\t\t}\n\n\t\t\t\tif ($el.attr('data-expiration')) {\n\t\t\t\t\tvar expirationTimestamp = parseInt($el.attr('data-expiration'))\n\t\t\t\t\tfileInfo.shares = []\n\t\t\t\t\tfileInfo.shares.push({ expiration: expirationTimestamp })\n\t\t\t\t}\n\n\t\t\t\treturn fileInfo\n\t\t\t}\n\n\t\t\tvar oldGetWebdavProperties = fileList._getWebdavProperties\n\t\t\tfileList._getWebdavProperties = function() {\n\t\t\t\tvar props = oldGetWebdavProperties.apply(this, arguments)\n\t\t\t\tprops.push(OC.Files.Client.PROPERTY_OWNER_ID)\n\t\t\t\tprops.push(OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME)\n\t\t\t\tprops.push(OC.Files.Client.PROPERTY_SHARE_TYPES)\n\t\t\t\treturn props\n\t\t\t}\n\n\t\t\tfileList.filesClient.addFileInfoParser(function(response) {\n\t\t\t\tvar data = {}\n\t\t\t\tvar props = response.propStat[0].properties\n\t\t\t\tvar permissionsProp = props[OC.Files.Client.PROPERTY_PERMISSIONS]\n\n\t\t\t\tif (permissionsProp && permissionsProp.indexOf('S') >= 0) {\n\t\t\t\t\tdata.shareOwner = props[OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME]\n\t\t\t\t\tdata.shareOwnerId = props[OC.Files.Client.PROPERTY_OWNER_ID]\n\t\t\t\t}\n\n\t\t\t\tvar shareTypesProp = props[OC.Files.Client.PROPERTY_SHARE_TYPES]\n\t\t\t\tif (shareTypesProp) {\n\t\t\t\t\tdata.shareTypes = _.chain(shareTypesProp).filter(function(xmlvalue) {\n\t\t\t\t\t\treturn (xmlvalue.namespaceURI === OC.Files.Client.NS_OWNCLOUD && xmlvalue.nodeName.split(':')[1] === 'share-type')\n\t\t\t\t\t}).map(function(xmlvalue) {\n\t\t\t\t\t\treturn parseInt(xmlvalue.textContent || xmlvalue.text, 10)\n\t\t\t\t\t}).value()\n\t\t\t\t}\n\n\t\t\t\treturn data\n\t\t\t})\n\n\t\t\t// use delegate to catch the case with multiple file lists\n\t\t\tfileList.$el.on('fileActionsReady', function(ev) {\n\t\t\t\tvar $files = ev.$files\n\n\t\t\t\t_.each($files, function(file) {\n\t\t\t\t\tvar $tr = $(file)\n\t\t\t\t\tvar shareTypes = $tr.attr('data-share-types') || ''\n\t\t\t\t\tvar shareOwner = $tr.attr('data-share-owner')\n\t\t\t\t\tif (shareTypes || shareOwner) {\n\t\t\t\t\t\tvar hasLink = false\n\t\t\t\t\t\tvar hasShares = false\n\t\t\t\t\t\t_.each(shareTypes.split(',') || [], function(shareType) {\n\t\t\t\t\t\t\tshareType = parseInt(shareType, 10)\n\t\t\t\t\t\t\tif (shareType === OC.Share.SHARE_TYPE_LINK) {\n\t\t\t\t\t\t\t\thasLink = true\n\t\t\t\t\t\t\t} else if (shareType === OC.Share.SHARE_TYPE_EMAIL) {\n\t\t\t\t\t\t\t\thasLink = true\n\t\t\t\t\t\t\t} else if (shareType === OC.Share.SHARE_TYPE_USER) {\n\t\t\t\t\t\t\t\thasShares = true\n\t\t\t\t\t\t\t} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {\n\t\t\t\t\t\t\t\thasShares = true\n\t\t\t\t\t\t\t} else if (shareType === OC.Share.SHARE_TYPE_REMOTE) {\n\t\t\t\t\t\t\t\thasShares = true\n\t\t\t\t\t\t\t} else if (shareType === OC.Share.SHARE_TYPE_CIRCLE) {\n\t\t\t\t\t\t\t\thasShares = true\n\t\t\t\t\t\t\t} else if (shareType === OC.Share.SHARE_TYPE_ROOM) {\n\t\t\t\t\t\t\t\thasShares = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\tOCA.Sharing.Util._updateFileActionIcon($tr, hasShares, hasLink)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tfileList.$el.on('changeDirectory', function() {\n\t\t\t\tOCA.Sharing.sharesLoaded = false\n\t\t\t})\n\n\t\t\tfileActions.registerAction({\n\t\t\t\tname: 'Share',\n\t\t\t\tdisplayName: function(context) {\n\t\t\t\t\tif (context && context.$file) {\n\t\t\t\t\t\tvar shareType = parseInt(context.$file.data('share-types'), 10)\n\t\t\t\t\t\tvar shareOwner = context.$file.data('share-owner-id')\n\t\t\t\t\t\tif (shareType >= 0 || shareOwner) {\n\t\t\t\t\t\t\treturn t('core', 'Shared')\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn t('core', 'Share')\n\t\t\t\t},\n\t\t\t\taltText: t('core', 'Share'),\n\t\t\t\tmime: 'all',\n\t\t\t\torder: -150,\n\t\t\t\tpermissions: OC.PERMISSION_ALL,\n\t\t\t\ticonClass: function(fileName, context) {\n\t\t\t\t\tvar shareType = parseInt(context.$file.data('share-types'), 10)\n\t\t\t\t\tif (shareType === OC.Share.SHARE_TYPE_EMAIL\n\t\t\t\t\t\t|| shareType === OC.Share.SHARE_TYPE_LINK) {\n\t\t\t\t\t\treturn 'icon-public'\n\t\t\t\t\t}\n\t\t\t\t\treturn 'icon-shared'\n\t\t\t\t},\n\t\t\t\ticon: function(fileName, context) {\n\t\t\t\t\tvar shareOwner = context.$file.data('share-owner-id')\n\t\t\t\t\tif (shareOwner) {\n\t\t\t\t\t\treturn OC.generateUrl(`/avatar/${shareOwner}/32`)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\ttype: OCA.Files.FileActions.TYPE_INLINE,\n\t\t\t\tactionHandler: function(fileName, context) {\n\t\t\t\t\t// do not open sidebar if permission is set and equal to 0\n\t\t\t\t\tvar permissions = parseInt(context.$file.data('share-permissions'), 10)\n\t\t\t\t\tif (isNaN(permissions) || permissions > 0) {\n\t\t\t\t\t\tfileList.showDetailsView(fileName, 'sharing')\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\trender: function(actionSpec, isDefault, context) {\n\t\t\t\t\tvar permissions = parseInt(context.$file.data('permissions'), 10)\n\t\t\t\t\t// if no share permissions but share owner exists, still show the link\n\t\t\t\t\tif ((permissions & OC.PERMISSION_SHARE) !== 0 || context.$file.attr('data-share-owner')) {\n\t\t\t\t\t\treturn fileActions._defaultRenderAction.call(fileActions, actionSpec, isDefault, context)\n\t\t\t\t\t}\n\t\t\t\t\t// don't render anything\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// register share breadcrumbs component\n\t\t\tvar breadCrumbSharingDetailView = new OCA.Sharing.ShareBreadCrumbView()\n\t\t\tfileList.registerBreadCrumbDetailView(breadCrumbSharingDetailView)\n\t\t},\n\n\t\t/**\n\t\t * Update file list data attributes\n\t\t */\n\t\t_updateFileListDataAttributes: function(fileList, $tr, shareModel) {\n\t\t\t// files app current cannot show recipients on load, so we don't update the\n\t\t\t// icon when changed for consistency\n\t\t\tif (fileList.id === 'files') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvar recipients = _.pluck(shareModel.get('shares'), 'share_with_displayname')\n\t\t\t// note: we only update the data attribute because updateIcon()\n\t\t\tif (recipients.length) {\n\t\t\t\tvar recipientData = _.mapObject(shareModel.get('shares'), function(share) {\n\t\t\t\t\treturn { shareWith: share.share_with, shareWithDisplayName: share.share_with_displayname }\n\t\t\t\t})\n\t\t\t\t$tr.attr('data-share-recipient-data', JSON.stringify(recipientData))\n\t\t\t} else {\n\t\t\t\t$tr.removeAttr('data-share-recipient-data')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Update the file action share icon for the given file\n\t\t *\n\t\t * @param $tr file element of the file to update\n\t\t * @param {boolean} hasUserShares true if a user share exists\n\t\t * @param {boolean} hasLinkShares true if a link share exists\n\t\t *\n\t\t * @returns {boolean} true if the icon was set, false otherwise\n\t\t */\n\t\t_updateFileActionIcon: function($tr, hasUserShares, hasLinkShares) {\n\t\t\t// if the statuses are loaded already, use them for the icon\n\t\t\t// (needed when scrolling to the next page)\n\t\t\tif (hasUserShares || hasLinkShares || $tr.attr('data-share-recipient-data') || $tr.attr('data-share-owner')) {\n\t\t\t\tOCA.Sharing.Util._markFileAsShared($tr, true, hasLinkShares)\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\n\t\t/**\n\t\t * Marks/unmarks a given file as shared by changing its action icon\n\t\t * and folder icon.\n\t\t *\n\t\t * @param $tr file element to mark as shared\n\t\t * @param hasShares whether shares are available\n\t\t * @param hasLink whether link share is available\n\t\t */\n\t\t_markFileAsShared: function($tr, hasShares, hasLink) {\n\t\t\tvar action = $tr.find('.fileactions .action[data-action=\"Share\"]')\n\t\t\tvar type = $tr.data('type')\n\t\t\tvar icon = action.find('.icon')\n\t\t\tvar message, recipients, avatars\n\t\t\tvar ownerId = $tr.attr('data-share-owner-id')\n\t\t\tvar owner = $tr.attr('data-share-owner')\n\t\t\tvar mountType = $tr.attr('data-mounttype')\n\t\t\tvar shareFolderIcon\n\t\t\tvar iconClass = 'icon-shared'\n\t\t\taction.removeClass('shared-style')\n\t\t\t// update folder icon\n\t\t\tif (type === 'dir' && (hasShares || hasLink || ownerId)) {\n\t\t\t\tif (typeof mountType !== 'undefined' && mountType !== 'shared-root' && mountType !== 'shared') {\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-' + mountType)\n\t\t\t\t} else if (hasLink) {\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-public')\n\t\t\t\t} else {\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-shared')\n\t\t\t\t}\n\t\t\t\t$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')')\n\t\t\t\t$tr.attr('data-icon', shareFolderIcon)\n\t\t\t} else if (type === 'dir') {\n\t\t\t\tvar isEncrypted = $tr.attr('data-e2eencrypted')\n\t\t\t\t// FIXME: duplicate of FileList._createRow logic for external folder,\n\t\t\t\t// need to refactor the icon logic into a single code path eventually\n\t\t\t\tif (isEncrypted === 'true') {\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-encrypted')\n\t\t\t\t\t$tr.attr('data-icon', shareFolderIcon)\n\t\t\t\t} else if (mountType && mountType.indexOf('external') === 0) {\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-external')\n\t\t\t\t\t$tr.attr('data-icon', shareFolderIcon)\n\t\t\t\t} else {\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir')\n\t\t\t\t\t// back to default\n\t\t\t\t\t$tr.removeAttr('data-icon')\n\t\t\t\t}\n\t\t\t\t$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')')\n\t\t\t}\n\t\t\t// update share action text / icon\n\t\t\tif (hasShares || ownerId) {\n\t\t\t\trecipients = $tr.data('share-recipient-data')\n\t\t\t\taction.addClass('shared-style')\n\n\t\t\t\tavatars = '' + t('core', 'Shared') + ''\n\t\t\t\t// even if reshared, only show \"Shared by\"\n\t\t\t\tif (ownerId) {\n\t\t\t\t\tmessage = t('core', 'Shared by')\n\t\t\t\t\tavatars = OCA.Sharing.Util._formatRemoteShare(ownerId, owner, message)\n\t\t\t\t} else if (recipients) {\n\t\t\t\t\tavatars = OCA.Sharing.Util._formatShareList(recipients)\n\t\t\t\t}\n\t\t\t\taction.html(avatars).prepend(icon)\n\n\t\t\t\tif (ownerId || recipients) {\n\t\t\t\t\tvar avatarElement = action.find('.avatar')\n\t\t\t\t\tavatarElement.each(function() {\n\t\t\t\t\t\t$(this).avatar($(this).data('username'), 32)\n\t\t\t\t\t})\n\t\t\t\t\taction.find('span[title]').tooltip({ placement: 'top' })\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\taction.html('' + t('core', 'Shared') + '').prepend(icon)\n\t\t\t}\n\t\t\tif (hasLink) {\n\t\t\t\ticonClass = 'icon-public'\n\t\t\t}\n\t\t\ticon.removeClass('icon-shared icon-public').addClass(iconClass)\n\t\t},\n\t\t/**\t\n\t\t * Format a remote address\t\n\t\t *\t\n\t\t* @param {String} shareWith userid, full remote share, or whatever\t\n\t\t* @param {String} shareWithDisplayName\t\n\t\t* @param {String} message\t\n\t\t* @returns {String} HTML code to display\t\n\t\t*/\t\n\t\t_formatRemoteShare: function(shareWith, shareWithDisplayName, message) {\t\n\t\t\tvar parts = OCA.Sharing.Util._REMOTE_OWNER_REGEXP.exec(shareWith)\t\n\t\t\tif (!parts || !parts[6]) {\n\t\t\t\t// display avatar of the user\t\n\t\t\t\tvar avatar = ''\t\n\t\t\t\tvar hidden = '' + message + ' ' + escapeHTML(shareWithDisplayName) + ' '\t\n\t\t\t\treturn avatar + hidden\t\n\t\t\t}\t\n\n\t\t\tvar userName = parts[2]\n\t\t\tvar userDomain = parts[4]\n\t\t\tvar server = parts[5]\n\n\t\t\tvar tooltip = message + ' ' + userName\n\t\t\tif (userDomain) {\n\t\t\t\ttooltip += '@' + userDomain\n\t\t\t}\n\t\t\tif (server) {\n\t\t\t\ttooltip += '@' + server\n\t\t\t}\n\n\t\t\tvar html = ''\t\n\t\t\thtml += '' + escapeHTML(userName) + ''\t\n\t\t\tif (userDomain) {\t\n\t\t\t\thtml += '@' + escapeHTML(userDomain) + ''\t\n\t\t\t}\t\n\t\t\thtml += ' '\t\n\t\t\treturn html\t\n\t\t},\t\n\t\t/**\t\n\t\t * Loop over all recipients in the list and format them using\t\n\t\t * all kind of fancy magic.\t\n\t\t *\t\n\t\t* @param {Object} recipients array of all the recipients\t\n\t\t* @returns {String[]} modified list of recipients\t\n\t\t*/\t\n\t\t_formatShareList: function(recipients) {\t\n\t\t\tvar _parent = this\t\n\t\t\trecipients = _.toArray(recipients)\t\n\t\t\trecipients.sort(function(a, b) {\t\n\t\t\t\treturn a.shareWithDisplayName.localeCompare(b.shareWithDisplayName)\t\n\t\t\t})\t\n\t\t\treturn $.map(recipients, function(recipient) {\t\n\t\t\t\treturn _parent._formatRemoteShare(recipient.shareWith, recipient.shareWithDisplayName, t('core', 'Shared with'))\t\n\t\t\t})\t\n\t\t},\n\t\t\n\t\t/**\t\n\t\t * Marks/unmarks a given file as shared by changing its action icon\t\n\t\t * and folder icon.\t\n\t\t *\t\n\t\t* @param $tr file element to mark as shared\t\n\t\t* @param hasShares whether shares are available\t\n\t\t* @param hasLink whether link share is available\t\n\t\t*/\t\n\t\tmarkFileAsShared: function($tr, hasShares, hasLink) {\t\n\t\t\tvar action = $tr.find('.fileactions .action[data-action=\"Share\"]')\t\n\t\t\tvar type = $tr.data('type')\t\n\t\t\tvar icon = action.find('.icon')\t\n\t\t\tvar message, recipients, avatars\t\n\t\t\tvar ownerId = $tr.attr('data-share-owner-id')\t\n\t\t\tvar owner = $tr.attr('data-share-owner')\t\n\t\t\tvar mountType = $tr.attr('data-mounttype')\t\n\t\t\tvar shareFolderIcon\t\n\t\t\tvar iconClass = 'icon-shared'\t\n\t\t\taction.removeClass('shared-style')\t\n\t\t\t// update folder icon\t\n\t\t\tif (type === 'dir' && (hasShares || hasLink || ownerId)) {\t\n\t\t\t\tif (typeof mountType !== 'undefined' && mountType !== 'shared-root' && mountType !== 'shared') {\t\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-' + mountType)\t\n\t\t\t\t} else if (hasLink) {\t\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-public')\t\n\t\t\t\t} else {\t\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-shared')\t\n\t\t\t\t}\t\n\t\t\t\t$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')')\t\n\t\t\t\t$tr.attr('data-icon', shareFolderIcon)\t\n\t\t\t} else if (type === 'dir') {\t\n\t\t\t\tvar isEncrypted = $tr.attr('data-e2eencrypted')\t\n\t\t\t\t// FIXME: duplicate of FileList._createRow logic for external folder,\t\n\t\t\t\t// need to refactor the icon logic into a single code path eventually\t\n\t\t\t\tif (isEncrypted === 'true') {\t\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-encrypted')\t\n\t\t\t\t\t$tr.attr('data-icon', shareFolderIcon)\t\n\t\t\t\t} else if (mountType && mountType.indexOf('external') === 0) {\t\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir-external')\t\n\t\t\t\t\t$tr.attr('data-icon', shareFolderIcon)\t\n\t\t\t\t} else {\t\n\t\t\t\t\tshareFolderIcon = OC.MimeType.getIconUrl('dir')\t\n\t\t\t\t\t// back to default\t\n\t\t\t\t\t$tr.removeAttr('data-icon')\t\n\t\t\t\t}\t\n\t\t\t\t$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')')\t\n\t\t\t}\t\n\t\t\t// update share action text / icon\t\n\t\t\tif (hasShares || ownerId) {\t\n\t\t\t\trecipients = $tr.data('share-recipient-data')\t\n\t\t\t\taction.addClass('shared-style')\t\n\n\t\t\t\tavatars = '' + t('core', 'Shared') + ''\t\n\t\t\t\t// even if reshared, only show \"Shared by\"\t\n\t\t\t\tif (ownerId) {\t\n\t\t\t\t\tmessage = t('core', 'Shared by')\t\n\t\t\t\t\tavatars = this._formatRemoteShare(ownerId, owner, message)\t\n\t\t\t\t} else if (recipients) {\t\n\t\t\t\t\tavatars = this._formatShareList(recipients)\t\n\t\t\t\t}\t\n\t\t\t\taction.html(avatars).prepend(icon)\t\n\n\t\t\t\tif (ownerId || recipients) {\t\n\t\t\t\t\tvar avatarElement = action.find('.avatar')\t\n\t\t\t\t\tavatarElement.each(function() {\t\n\t\t\t\t\t\t$(this).avatar($(this).data('username'), 32)\t\n\t\t\t\t\t})\t\n\t\t\t\t\taction.find('span[title]').tooltip({ placement: 'top' })\t\n\t\t\t\t}\t\n\t\t\t} else {\t\n\t\t\t\taction.html('' + t('core', 'Shared') + '').prepend(icon)\t\n\t\t\t}\t\n\t\t\tif (hasLink) {\t\n\t\t\t\ticonClass = 'icon-public'\t\n\t\t\t}\t\n\t\t\ticon.removeClass('icon-shared icon-public').addClass(iconClass)\t\n\t\t},\n\n\t\t/**\n\t\t * @param {Array} fileData\n\t\t * @returns {String}\n\t\t */\n\t\tgetSharePermissions: function(fileData) {\n\t\t\treturn fileData.sharePermissions\n\t\t}\n\t}\n})()\n\nOC.Plugins.register('OCA.Files.FileList', OCA.Sharing.Util)\n","/**\n * @copyright 2016 Christoph Wurst \n *\n * @author 2016 Christoph Wurst \n *\n * @license GNU AGPL version 3 or any later version\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see .\n *\n */\n\n(function() {\n\t'use strict'\n\n\tconst BreadCrumbView = OC.Backbone.View.extend({\n\t\ttagName: 'span',\n\t\tevents: {\n\t\t\tclick: '_onClick',\n\t\t},\n\t\t_dirInfo: undefined,\n\n\t\trender: function(data) {\n\t\t\tthis._dirInfo = data.dirInfo || null\n\n\t\t\tif (this._dirInfo !== null && (this._dirInfo.path !== '/' || this._dirInfo.name !== '')) {\n\t\t\t\tconst isShared = data.dirInfo && data.dirInfo.shareTypes && data.dirInfo.shareTypes.length > 0\n\t\t\t\tthis.$el.removeClass('shared icon-public icon-shared')\n\t\t\t\tif (isShared) {\n\t\t\t\t\tthis.$el.addClass('shared')\n\t\t\t\t\tif (data.dirInfo.shareTypes.indexOf(OC.Share.SHARE_TYPE_LINK) !== -1) {\n\t\t\t\t\t\tthis.$el.addClass('icon-public')\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.$el.addClass('icon-shared')\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.$el.addClass('icon-shared')\n\t\t\t\t}\n\t\t\t\tthis.$el.show()\n\t\t\t\tthis.delegateEvents()\n\t\t\t} else {\n\t\t\t\tthis.$el.removeClass('shared icon-public icon-shared')\n\t\t\t\tthis.$el.hide()\n\t\t\t}\n\n\t\t\treturn this\n\t\t},\n\t\t_onClick: function(e) {\n\t\t\te.preventDefault()\n\n\t\t\tconst fileInfoModel = new OCA.Files.FileInfoModel(this._dirInfo)\n\t\t\tconst self = this\n\t\t\tfileInfoModel.on('change', function() {\n\t\t\t\tself.render({\n\t\t\t\t\tdirInfo: self._dirInfo,\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tconst path = fileInfoModel.attributes.path + '/' + fileInfoModel.attributes.name\n\t\t\tOCA.Files.Sidebar.open(path)\n\t\t\tOCA.Files.Sidebar.setActiveTab('sharing')\n\t\t},\n\t})\n\n\tOCA.Sharing.ShareBreadCrumbView = BreadCrumbView\n})()\n","// style-loader: Adds some css to the DOM by adding a